|
1 |
/*
|
|
2 |
AMiRo-Apps is a collection of applications for the Autonomous Mini Robot (AMiRo) platform.
|
|
3 |
Copyright (C) 2018..2018 Thomas Schöpping et al.
|
|
4 |
|
|
5 |
This program is free software: you can redistribute it and/or modify
|
|
6 |
it under the terms of the GNU General Public License as published by
|
|
7 |
the Free Software Foundation, either version 3 of the License, or
|
|
8 |
(at your option) any later version.
|
|
9 |
|
|
10 |
This program is distributed in the hope that it will be useful,
|
|
11 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 |
GNU General Public License for more details.
|
|
14 |
|
|
15 |
You should have received a copy of the GNU General Public License
|
|
16 |
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17 |
*/
|
|
18 |
|
|
19 |
#ifndef _URT_OSAL_H_
|
|
20 |
#define _URT_OSAL_H_
|
|
21 |
|
|
22 |
/*============================================================================*/
|
|
23 |
/* VERSION */
|
|
24 |
/*============================================================================*/
|
|
25 |
|
|
26 |
/**
|
|
27 |
* @brief The µRtWare operating system abstraction layer interface major version.
|
|
28 |
* @note Changes of the major version imply incompatibilities.
|
|
29 |
*/
|
|
30 |
#define URT_OSAL_VERSION_MAJOR 0
|
|
31 |
|
|
32 |
/**
|
|
33 |
* @brief The µRtWare operating system abstraction layer interface minor version.
|
|
34 |
* @note A higher minor version implies new functionalty, but all old interfaces are still available.
|
|
35 |
*/
|
|
36 |
#define URT_OSAL_VERSION_MINOR 1
|
|
37 |
|
|
38 |
/*============================================================================*/
|
|
39 |
/* DEPENDENCIES */
|
|
40 |
/*============================================================================*/
|
|
41 |
|
|
42 |
#include <urt_types.h>
|
|
43 |
#include <amiroos.h>
|
|
44 |
|
|
45 |
/*============================================================================*/
|
|
46 |
/* TIME */
|
|
47 |
/*============================================================================*/
|
|
48 |
|
|
49 |
/**
|
|
50 |
* @brief The urt_osTime_t represents time at an arbitrary precision.
|
|
51 |
*/
|
|
52 |
typedef aos_timestamp_t urt_osTime_t;
|
|
53 |
|
|
54 |
/**
|
|
55 |
* @brief Convert an urt_osTime_t to microseconds.
|
|
56 |
*
|
|
57 |
* @param[in] time The urt_osTime_t object to convert.
|
|
58 |
*
|
|
59 |
* @return The time at microsecond precision.
|
|
60 |
*/
|
|
61 |
static inline uint64_t urtTime2Us(urt_osTime_t* time)
|
|
62 |
{
|
|
63 |
aosDbgCheck(time != NULL);
|
|
64 |
|
|
65 |
return *time;
|
|
66 |
}
|
|
67 |
|
|
68 |
/**
|
|
69 |
* @brief Retrieve the current system time.
|
|
70 |
*
|
|
71 |
* @return The current system time.
|
|
72 |
*/
|
|
73 |
static inline urt_osTime_t urtTimeNow(void)
|
|
74 |
{
|
|
75 |
urt_osTime_t time;
|
|
76 |
aosSysGetUptime(&time);
|
|
77 |
return time;
|
|
78 |
}
|
|
79 |
|
|
80 |
/*============================================================================*/
|
|
81 |
/* TIMER */
|
|
82 |
/*============================================================================*/
|
|
83 |
|
|
84 |
/**
|
|
85 |
* @brief A timer type.
|
|
86 |
*/
|
|
87 |
typedef aos_timer_t urt_osTimer_t;
|
|
88 |
|
|
89 |
/**
|
|
90 |
* @brief Initialize a timer object.
|
|
91 |
*
|
|
92 |
* @param[in] timer The timer object to initialize.
|
|
93 |
*/
|
|
94 |
static inline void urtTimerInit(urt_osTimer_t* timer)
|
|
95 |
{
|
|
96 |
aosDbgCheck(timer != NULL);
|
|
97 |
|
|
98 |
aosTimerInit(timer);
|
|
99 |
}
|
|
100 |
|
|
101 |
/**
|
|
102 |
* @brief Set a timer to fire after a specified delay and execute the callback function.
|
|
103 |
*
|
|
104 |
* @param[in] timer The timer object.
|
|
105 |
* @param[in] delay A delay after which the timer shall fire.
|
|
106 |
* @param[in] callback The callback to be executed by the timer.
|
|
107 |
* @param[in] parameter Optional parameters to the callback function.
|
|
108 |
*
|
|
109 |
* @return Satus indicating whether execution was successful.
|
|
110 |
*/
|
|
111 |
static inline urt_status_t urtTimerSet(urt_osTimer_t* timer, urt_delay_t delay, urt_osTimerCallback callback, void* parameter)
|
|
112 |
{
|
|
113 |
aosDbgCheck(timer != NULL);
|
|
114 |
aosDbgCheck(callback != NULL);
|
|
115 |
|
|
116 |
if (sizeof(urt_delay_t) > sizeof(aos_interval_t)) {
|
|
117 |
aos_longinterval_t interval = delay;
|
|
118 |
aosTimerSetLongInterval(timer, &interval, callback, parameter);
|
|
119 |
} else {
|
|
120 |
aosTimerSetInterval(timer, delay, callback, parameter);
|
|
121 |
}
|
|
122 |
return URT_STATUS_OK;
|
|
123 |
}
|
|
124 |
|
|
125 |
/**
|
|
126 |
* @brief Reset a timer.
|
|
127 |
*
|
|
128 |
* @param[in] timer The timer to reset.
|
|
129 |
*
|
|
130 |
* @return Status indicating whether execution was successful.
|
|
131 |
*/
|
|
132 |
static inline urt_status_t urtTimerReset(urt_osTimer_t* timer)
|
|
133 |
{
|
|
134 |
aosDbgCheck(timer != NULL);
|
|
135 |
|
|
136 |
aosTimerReset(timer);
|
|
137 |
return URT_STATUS_OK;
|
|
138 |
}
|
|
139 |
|
|
140 |
/**
|
|
141 |
* @brief Retrieve whether a timer is currently armed.
|
|
142 |
*
|
|
143 |
* @param[in] timer The timer to check.
|
|
144 |
*
|
|
145 |
* @return Indicator whether the timer is armed.
|
|
146 |
*/
|
|
147 |
static inline bool urtTimerIsArmed(urt_osTimer_t* timer)
|
|
148 |
{
|
|
149 |
aosDbgCheck(timer != NULL);
|
|
150 |
|
|
151 |
return aosTimerIsArmed(timer);
|
|
152 |
}
|
|
153 |
|
|
154 |
/*============================================================================*/
|
|
155 |
/* STREAMS */
|
|
156 |
/*============================================================================*/
|
|
157 |
|
|
158 |
/**
|
|
159 |
* @brief Prints a formatted string to standard output.
|
|
160 |
* @note Behaves like standard C printf().
|
|
161 |
*
|
|
162 |
* @param[in] fmt Formatted string to print.
|
|
163 |
*/
|
|
164 |
#define urtPrintf(fmt, ...) aosprintf(fmt, ##__VA_ARGS__)
|
|
165 |
|
|
166 |
/**
|
|
167 |
* @brief Prints a formatted string to error output.
|
|
168 |
* @note Behaves like to standard C printf().
|
|
169 |
*
|
|
170 |
* @param[in] fmt Formatted string to print.
|
|
171 |
*/
|
|
172 |
#define urtErrPrintf(fmt, ...) aosprintf(fmt, ##__VA_ARGS__)
|
|
173 |
|
|
174 |
/*============================================================================*/
|
|
175 |
/* EVENTS */
|
|
176 |
/*============================================================================*/
|
|
177 |
|
|
178 |
/**
|
|
179 |
* @brief Type representing event masks.
|
|
180 |
* @details Event masks can be used to distinguish and filter events.
|
|
181 |
*/
|
|
182 |
typedef eventmask_t urt_osEventMask_t;
|
|
183 |
|
|
184 |
/**
|
|
185 |
* @brief The event mask that is served by the kernel with highest priority.
|
|
186 |
* @details It is assumed to be one of three values:
|
|
187 |
* * 1 Lower bits have higher priority.
|
|
188 |
* * -1 Higher bits have higher priority.
|
|
189 |
* * 0 Thekernel does not implement any priorities.
|
|
190 |
*/
|
|
191 |
#define URT_EVENTMASK_MAXPRIO (urt_osEventMask_t)1
|
|
192 |
|
|
193 |
/**
|
|
194 |
* @brief Type representing event flags.
|
|
195 |
* @details Event flags can be used to represent rudiemntary metadata or filter events.
|
|
196 |
*/
|
|
197 |
typedef eventflags_t urt_osEventFlags_t;
|
|
198 |
|
|
199 |
/**
|
|
200 |
* @brief Event source type.
|
|
201 |
*/
|
|
202 |
typedef event_source_t urt_osEventSource_t;
|
|
203 |
|
|
204 |
/**
|
|
205 |
* @brief Initialize an event source object.
|
|
206 |
*
|
|
207 |
* @param[in] source The event source object to initialize.
|
|
208 |
*/
|
|
209 |
static inline void urtEventSourceInit(urt_osEventSource_t* source)
|
|
210 |
{
|
|
211 |
aosDbgCheck(source != NULL);
|
|
212 |
|
|
213 |
chEvtObjectInit(source);
|
|
214 |
}
|
|
215 |
|
|
216 |
/**
|
|
217 |
* @brief Broadcast an event via the source.
|
|
218 |
*
|
|
219 |
* @param[in] source The event source to use for broadcasting.
|
|
220 |
* @param[in] flags Flags to be broadcasted along with the event.
|
|
221 |
*/
|
|
222 |
static inline void urtEventSourceBroadcast(urt_osEventSource_t* source, urt_osEventFlags_t flags)
|
|
223 |
{
|
|
224 |
aosDbgCheck(source != NULL);
|
|
225 |
|
|
226 |
chEvtBroadcastFlags(source, flags);
|
|
227 |
}
|
|
228 |
|
|
229 |
/**
|
|
230 |
* @brief Event listener type.
|
|
231 |
*/
|
|
232 |
typedef event_listener_t urt_osEventListener_t;
|
|
233 |
|
|
234 |
/**
|
|
235 |
* @brief Initialize an event listener object.
|
|
236 |
*
|
|
237 |
* @param[in] listener The vent listener object to initialize.
|
|
238 |
*/
|
|
239 |
static inline void urtEventListenerInit(urt_osEventListener_t* listener)
|
|
240 |
{
|
|
241 |
aosDbgCheck(listener != NULL);
|
|
242 |
|
|
243 |
(void)listener;
|
|
244 |
return;
|
|
245 |
}
|
|
246 |
|
|
247 |
/**
|
|
248 |
* @brief Retrieve the flags of a listener.
|
|
249 |
*
|
|
250 |
* @param[in] listener Event listener to retrieve the flags from.
|
|
251 |
*
|
|
252 |
* @return The flag mask of the event listener.
|
|
253 |
*/
|
|
254 |
static inline urt_osEventFlags_t urtEventListenerGetFlags(urt_osEventListener_t* listener)
|
|
255 |
{
|
|
256 |
aosDbgCheck(listener != NULL);
|
|
257 |
|
|
258 |
return listener->flags;
|
|
259 |
}
|
|
260 |
|
|
261 |
/**
|
|
262 |
* @brief Retrieve and clear the flags of listener.
|
|
263 |
*
|
|
264 |
* @param[in] listener Event listener to retrieve and clear the flags from.
|
|
265 |
*
|
|
266 |
* @return The flag mask of the event listener before it was cleared.
|
|
267 |
*/
|
|
268 |
static inline urt_osEventFlags_t urtEventListenerGetAndClearFlags(urt_osEventListener_t* listener)
|
|
269 |
{
|
|
270 |
aosDbgCheck(listener != NULL);
|
|
271 |
|
|
272 |
return chEvtGetAndClearFlags(listener);
|
|
273 |
}
|
|
274 |
|
|
275 |
/**
|
|
276 |
* @brief Register an event source and listener with an individual event nask.
|
|
277 |
*
|
|
278 |
* @param[in] source The event source to register.
|
|
279 |
* @param[in] listener The event listener to register.
|
|
280 |
* @param[in] mask Individual event mask to idetify these evente.
|
|
281 |
*
|
|
282 |
* @return Status indicating whether registration was successful.
|
|
283 |
*/
|
|
284 |
static inline urt_status_t urtEventRegister(urt_osEventSource_t* source, urt_osEventListener_t* listener, urt_osEventMask_t mask)
|
|
285 |
{
|
|
286 |
aosDbgCheck(source!= NULL);
|
|
287 |
aosDbgCheck(listener != NULL);
|
|
288 |
|
|
289 |
chEvtRegisterMask(source, listener, mask);
|
|
290 |
return URT_STATUS_OK;
|
|
291 |
}
|
|
292 |
|
|
293 |
/**
|
|
294 |
* @brief Unregister an event source and listener.
|
|
295 |
*
|
|
296 |
* @param[in] source The event source to unregister.
|
|
297 |
* @param[in] listener The event listener to unregister.
|
|
298 |
*
|
|
299 |
* @return Status indicating whether unregistration was successful.
|
|
300 |
*/
|
|
301 |
static inline urt_status_t urtEventUnregister(urt_osEventSource_t* source, urt_osEventListener_t* listener)
|
|
302 |
{
|
|
303 |
aosDbgCheck(source != NULL);
|
|
304 |
aosDbgCheck(listener != NULL);
|
|
305 |
|
|
306 |
chEvtUnregister(source, listener);
|
|
307 |
return URT_STATUS_OK;
|
|
308 |
}
|
|
309 |
|
|
310 |
/**
|
|
311 |
* @brief Wait for one, any or all specified events to occur.
|
|
312 |
*
|
|
313 |
* @param[in] mask An event mask for filtering events.
|
|
314 |
* @param[in] type Specifier to define how to wait for one or multiple events.
|
|
315 |
* @param[in] timeout Timeout after which the function will return.
|
|
316 |
*
|
|
317 |
* @return The ORed event mask of all received events.
|
|
318 |
* In case of a timeout it will be zero.
|
|
319 |
*/
|
|
320 |
static inline urt_osEventMask_t urtEventWait(urt_osEventMask_t mask, urt_osEventWaitType_t type, urt_delay_t timeout)
|
|
321 |
{
|
|
322 |
switch (type) {
|
|
323 |
case URT_EVENT_WAIT_ONE:
|
|
324 |
return chEvtWaitOneTimeout(mask, timeout);
|
|
325 |
case URT_EVENT_WAIT_ANY:
|
|
326 |
return chEvtWaitAnyTimeout(mask, timeout);
|
|
327 |
case URT_EVENT_WAIT_ALL:
|
|
328 |
return chEvtWaitAllTimeout(mask, timeout);
|
|
329 |
}
|
|
330 |
}
|
|
331 |
|
|
332 |
/*============================================================================*/
|
|
333 |
/* MUTEX LOCK */
|
|
334 |
/*============================================================================*/
|
|
335 |
|
|
336 |
/**
|
|
337 |
* @brief Mutex lock type.
|
|
338 |
*/
|
|
339 |
typedef mutex_t urt_osMutex_t;
|
|
340 |
|
|
341 |
/**
|
|
342 |
* @brief Initialization of a mutex lock object.
|
|
343 |
*
|
|
344 |
* @param[in] mutex The mutex lock object to initialize.
|
|
345 |
*/
|
|
346 |
static inline void urtMutexInit(urt_osMutex_t* mutex)
|
|
347 |
{
|
|
348 |
aosDbgCheck(mutex != NULL);
|
|
349 |
|
|
350 |
chMtxObjectInit(mutex);
|
|
351 |
}
|
|
352 |
|
|
353 |
/**
|
|
354 |
* @brief Lock a mutex lock (blocking).
|
|
355 |
* @details If the specified mutex is curently locked, the function will block until it could be acquired.
|
|
356 |
*
|
|
357 |
* @param[in] mutex The mutex lock to lock.
|
|
358 |
*/
|
|
359 |
static inline void urtMutexLock(urt_osMutex_t* mutex)
|
|
360 |
{
|
|
361 |
aosDbgCheck(mutex != NULL);
|
|
362 |
|
|
363 |
chMtxLock(mutex);
|
|
364 |
}
|
|
365 |
|
|
366 |
/**
|
|
367 |
* @brief Try to lock a mutex lock (unblocking)
|
|
368 |
* @details If the mutex lock is currently locked, the function will return immediately.
|
|
369 |
*
|
|
370 |
* @param[in] mutex The mutex lock to lock.
|
|
371 |
*
|
|
372 |
* @return Status indicating whether the mutex lock could be acquired.
|
|
373 |
*/
|
|
374 |
static inline bool urtMutexTryLock(urt_osMutex_t* mutex)
|
|
375 |
{
|
|
376 |
aosDbgCheck(mutex != NULL);
|
|
377 |
|
|
378 |
return chMtxTryLock(mutex);
|
|
379 |
}
|
|
380 |
|
|
381 |
/**
|
|
382 |
* @brief Unlock an owned mutex lock.
|
|
383 |
*
|
|
384 |
* @param[in] mutex The mutex lock to unlock.
|
|
385 |
*/
|
|
386 |
static inline void urtMutexUnlock(urt_osMutex_t* mutex)
|
|
387 |
{
|
|
388 |
aosDbgCheck(mutex != NULL);
|
|
389 |
|
|
390 |
chMtxUnlock(mutex);
|
|
391 |
}
|
|
392 |
|
|
393 |
/*============================================================================*/
|
|
394 |
/* CONDITION VARIABLE */
|
|
395 |
/*============================================================================*/
|
|
396 |
|
|
397 |
/**
|
|
398 |
* @brief Condition variable type.
|
|
399 |
*/
|
|
400 |
typedef condition_variable_t urt_osCondvar_t;
|
|
401 |
|
|
402 |
/**
|
|
403 |
* @brief Initialize a condition variable object.
|
|
404 |
*
|
|
405 |
* @param[in] condvar The condition variable object to initualize.
|
|
406 |
*/
|
|
407 |
static inline void urtCondvarInit(urt_osCondvar_t* condvar)
|
|
408 |
{
|
|
409 |
aosDbgCheck(condvar != NULL);
|
|
410 |
|
|
411 |
chCondObjectInit(condvar);
|
|
412 |
}
|
|
413 |
|
|
414 |
/**
|
|
415 |
* @brief Signal a condition variable.
|
|
416 |
*
|
|
417 |
* @param[in] condvar The condition variable to be signaled.
|
|
418 |
*/
|
|
419 |
static inline void urtCondvarSignal(urt_osCondvar_t* condvar)
|
|
420 |
{
|
|
421 |
aosDbgCheck(condvar != NULL);
|
|
422 |
|
|
423 |
chCondSignal(condvar);
|
|
424 |
}
|
|
425 |
|
|
426 |
/**
|
|
427 |
* @brief Broadcast a condition variable.
|
|
428 |
*
|
|
429 |
* @param[in] condvar The condition variable to be broadcasted.
|
|
430 |
*/
|
|
431 |
static inline void urtCondvarBroadcast(urt_osCondvar_t* condvar)
|
|
432 |
{
|
|
433 |
aosDbgCheck(condvar != NULL);
|
|
434 |
|
|
435 |
chCondBroadcast(condvar);
|
|
436 |
}
|
|
437 |
|
|
438 |
/**
|
|
439 |
* @brief Wait for a condition variable.
|
|
440 |
*
|
|
441 |
* @param[in] condvar The condition variable to wait for.
|
|
442 |
* @param[in] mutex A priviously acquired mutex lock.
|
|
443 |
* @param[in] timeout A timeout when the function will return.
|
|
444 |
*
|
|
445 |
* @return Status indicating how the condition variable was signaled or whether a timeout occurred.
|
|
446 |
*/
|
|
447 |
static inline urt_condvarStatus_t urtCondvarWait(urt_osCondvar_t* condvar, urt_osMutex_t* mutex, urt_delay_t timeout)
|
|
448 |
{
|
|
449 |
aosDbgCheck(condvar != NULL);
|
|
450 |
aosDbgCheck(mutex != NULL);
|
|
451 |
|
|
452 |
(void)mutex;
|
|
453 |
|
|
454 |
switch (chCondWaitTimeout(condvar, timeout)) {
|
|
455 |
case MSG_OK:
|
|
456 |
return URT_CONDVAR_STATUS_SIGNAL;
|
|
457 |
case MSG_RESET:
|
|
458 |
return URT_CONDVAR_STATUS_BROADCAST;
|
|
459 |
case MSG_TIMEOUT:
|
|
460 |
return URT_CONDVAR_STATUS_TIMEOUT;
|
|
461 |
default:
|
|
462 |
chSysHalt(__func__);
|
|
463 |
return URT_CONDVAR_STATUS_TIMEOUT;
|
|
464 |
}
|
|
465 |
}
|
|
466 |
|
|
467 |
/*============================================================================*/
|
|
468 |
/* THREAD */
|
|
469 |
/*============================================================================*/
|
|
470 |
|
|
471 |
/**
|
|
472 |
* @brief Thread priority data type.
|
|
473 |
*/
|
|
474 |
typedef tprio_t urt_osThreadPrio_t;
|
|
475 |
|
|
476 |
/**
|
|
477 |
* @brief Minimum thread priority.
|
|
478 |
*/
|
|
479 |
#define URT_THREAD_PRIO_LOW_MIN AOS_THD_LOWPRIO_MIN
|
|
480 |
|
|
481 |
/**
|
|
482 |
* @brief Maximum thread priority for low priority class threads.
|
|
483 |
*/
|
|
484 |
#define URT_THREAD_PRIO_LOW_MAX AOS_THD_LOWPRIO_MAX
|
|
485 |
|
|
486 |
/**
|
|
487 |
* @brief Minimum thread priority for normal priority class threads.
|
|
488 |
*/
|
|
489 |
#define URT_THREAD_PRIO_NORMAL_MIN AOS_THD_NORMALPRIO_MIN
|
|
490 |
|
|
491 |
/**
|
|
492 |
* @brief Maximum thread priority for normal priority class threads.
|
|
493 |
*/
|
|
494 |
#define URT_THREAD_PRIO_NORMAL_MAX AOS_THD_NORMALPRIO_MAX
|
|
495 |
|
|
496 |
/**
|
|
497 |
* @brief Minimum thread priority for high priority class threads.
|
|
498 |
*/
|
|
499 |
#define URT_THREAD_PRIO_HIGH_MIN AOS_THD_HIGHPRIO_MIN
|
|
500 |
|
|
501 |
/**
|
|
502 |
* @brief Maximum thread priority for high priority class threads.
|
|
503 |
*/
|
|
504 |
#define URT_THREAD_PRIO_HIGH_MAX AOS_THD_HIGHPRIO_MAX
|
|
505 |
|
|
506 |
/**
|
|
507 |
* @brief Minimum thread priority for real-time class threads.
|
|
508 |
*/
|
|
509 |
#define URT_THREAD_PRIO_RT_MIN AOS_THD_RTPRIO_MIN
|
|
510 |
|
|
511 |
/**
|
|
512 |
* @brief maximum thread priority for real-time class threads.
|
|
513 |
*/
|
|
514 |
#define URT_THREAD_PRIO_RT_MAX AOS_THD_RTPRIO_MAX
|
|
515 |
|
|
516 |
/**
|
|
517 |
* @brief Thread data type.
|
|
518 |
*/
|
|
519 |
typedef thread_t urt_osThread_t;
|
|
520 |
|
|
521 |
/**
|
|
522 |
* @brief Maximum number of seconds a thread can sleep.
|
|
523 |
*/
|
|
524 |
#define URT_THREAD_SLEEP_MAX (float)AOS_THD_MAX_SLEEP_S
|
|
525 |
|
|
526 |
/**
|
|
527 |
* @brief Maximum number of seconds a thread can sleep.
|
|
528 |
*/
|
|
529 |
#define URT_THREAD_SSLEEP_MAX (unsigned int)AOS_THD_MAX_SLEEP_S
|
|
530 |
|
|
531 |
/**
|
|
532 |
* @brief Maximum number of milliseconds a thread can sleep.
|
|
533 |
*/
|
|
534 |
#define URT_THREAD_MSLEEP_MAX (unsigned int)AOS_THD_MAX_SLEEP_MS
|
|
535 |
|
|
536 |
/**
|
|
537 |
* @brief Maximum number of microseconds a thread can sleep.
|
|
538 |
*/
|
|
539 |
#define URT_THREAD_USLEEP_MAX (urt_delay_t)AOS_THD_MAX_SLEEP_US
|
|
540 |
|
|
541 |
/**
|
|
542 |
* @brief Macro function to layout a thread memory.
|
|
543 |
* @details The overall memory required for a thread usually is a combination of the stack and some further data (i.e. the thread object itself).
|
|
544 |
* The layout in memory as well as the metadata may differ between kernels and event hardware ports.
|
|
545 |
*
|
|
546 |
* @param[in] varname The name of the resulting buffer variable.
|
|
547 |
* @param[in] stacksize The size of the thread's stack.
|
|
548 |
*/
|
|
549 |
#define URT_THREAD_MEMORY(varname, stacksize) THD_WORKING_AREA(varname, stacksize)
|
|
550 |
|
|
551 |
/**
|
|
552 |
* @brief Initialize a thread object.
|
|
553 |
* @details The thread is created but not started yet.
|
|
554 |
*
|
|
555 |
* @param[in] memory The thread memory to use (see @p URT_THREAD_MEMORY)
|
|
556 |
* @param[in] size Size of the thread memory in bytes.
|
|
557 |
* @param[in] func The thread main function to execute.
|
|
558 |
*
|
|
559 |
* @return Pointer to the created thread object.
|
|
560 |
*/
|
|
561 |
static inline urt_osThread_t* urtThreadInit(void* memory, size_t size, urt_osThreadFunction_t func)
|
|
562 |
{
|
|
563 |
aosDbgCheck(memory != NULL);
|
|
564 |
aosDbgCheck(size != 0);
|
|
565 |
aosDbgCheck(func != NULL);
|
|
566 |
|
|
567 |
const thread_descriptor_t descriptor = {
|
|
568 |
/* name */ "",
|
|
569 |
/* pointer to working area base */ (stkalign_t*)memory,
|
|
570 |
/* end of the working area */ &((stkalign_t*)memory)[size / sizeof(stkalign_t)],
|
|
571 |
/* thread priority */ URT_THREAD_PRIO_LOW_MIN,
|
|
572 |
/* thread function pointer */ func,
|
|
573 |
/* thread argument */ NULL,
|
|
574 |
/* pointer to the parent thread */ chThdGetSelfX(),
|
|
575 |
};
|
|
576 |
|
|
577 |
urt_osThread_t* thread = chThdCreateSuspended(&descriptor);
|
|
578 |
|
|
579 |
// store the function pointer in the stack (required for urtThreadStart())
|
|
580 |
*((urt_osThreadFunction_t*)thread->wabase) = func;
|
|
581 |
|
|
582 |
return thread;
|
|
583 |
}
|
|
584 |
|
|
585 |
/**
|
|
586 |
* @brief Start a previously initialized thread.
|
|
587 |
*
|
|
588 |
* @param[in] thread Pointer to the thread to start.
|
|
589 |
* @param[in] prio Priority to set for the thread.
|
|
590 |
* @param[in] arg Optional arguments for the thread function.
|
|
591 |
*/
|
|
592 |
static inline void urtThreadStart(urt_osThread_t* thread, urt_osThreadPrio_t prio, void* arg)
|
|
593 |
{
|
|
594 |
aosDbgCheck(thread != NULL);
|
|
595 |
aosDbgCheck(prio >= URT_THREAD_PRIO_LOW_MIN && prio <= URT_THREAD_PRIO_RT_MAX);
|
|
596 |
|
|
597 |
PORT_SETUP_CONTEXT(thread, thread->wabase, thread, *(urt_osThreadFunction_t*)thread->wabase, arg);
|
|
598 |
chThdSetPriority(prio);
|
|
599 |
chThdStart(thread);
|
|
600 |
}
|
|
601 |
|
|
602 |
/**
|
|
603 |
* @brief The calling thread yields execution until it is scheduled again.
|
|
604 |
*/
|
|
605 |
static inline void urtThreadYield(void)
|
|
606 |
{
|
|
607 |
chThdYield();
|
|
608 |
}
|
|
609 |
|
|
610 |
/**
|
|
611 |
* @brief Retrieve the currently set priority of the calling thread.
|
|
612 |
* @return
|
|
613 |
*/
|
|
614 |
static inline urt_osThreadPrio_t urtThreadGetPriority(void)
|
|
615 |
{
|
|
616 |
return chThdGetPriorityX();
|
|
617 |
}
|
|
618 |
|
|
619 |
/**
|
|
620 |
* @brief Set a new priority for the calling thread.
|
|
621 |
*
|
|
622 |
* @param[in] prio The new priority to set.
|
|
623 |
*/
|
|
624 |
static inline void urtThreadSetPriority(urt_osThreadPrio_t prio)
|
|
625 |
{
|
|
626 |
aosDbgCheck(prio >= URT_THREAD_PRIO_LOW_MIN && prio <= URT_THREAD_PRIO_RT_MAX);
|
|
627 |
|
|
628 |
chThdSetPriority(prio);
|
|
629 |
}
|
|
630 |
|
|
631 |
/**
|
|
632 |
* @brief suspend execution of the calling thread.
|
|
633 |
*/
|
|
634 |
static inline void urtThreadSuspend()
|
|
635 |
{
|
|
636 |
thread_reference_t ref = chThdGetSelfX();
|
|
637 |
|
|
638 |
chSysLock();
|
|
639 |
chThdSuspendS(&ref);
|
|
640 |
chSysUnlock();
|
|
641 |
}
|
|
642 |
|
|
643 |
/**
|
|
644 |
* @brief Resume a suspended thread.
|
|
645 |
*
|
|
646 |
* @param[in] thread The suspended thread to be resumed.
|
|
647 |
*
|
|
648 |
* @return Status indicating whether resuming the thread was successful.
|
|
649 |
*/
|
|
650 |
static inline urt_status_t urtThreadResume(urt_osThread_t* thread)
|
|
651 |
{
|
|
652 |
aosDbgCheck(thread != NULL);
|
|
653 |
|
|
654 |
thread_reference_t ref = thread;
|
|
655 |
|
|
656 |
chSysLock();
|
|
657 |
chThdResumeS(&ref, thread->u.rdymsg);
|
|
658 |
chSysUnlock();
|
|
659 |
|
|
660 |
return URT_STATUS_OK;
|
|
661 |
}
|
|
662 |
|
|
663 |
/**
|
|
664 |
* @brief The calling thread sleeps for the specified amount of time (seconds).
|
|
665 |
*
|
|
666 |
* @param[in] seconds The duration to sleep in seconds.
|
|
667 |
*/
|
|
668 |
static inline void urtThreadSleep(float seconds)
|
|
669 |
{
|
|
670 |
aosDbgCheck(seconds <= URT_THREAD_SLEEP_MAX);
|
|
671 |
|
|
672 |
aosThdSleep(seconds);
|
|
673 |
}
|
|
674 |
|
|
675 |
/**
|
|
676 |
* @brief The calling thread sleeps for the specified amount of time (seconds).
|
|
677 |
*
|
|
678 |
* @param[in] seconds The duration to sleep in seconds.
|
|
679 |
*/
|
|
680 |
static inline void urtThreadSSleep(unsigned int seconds)
|
|
681 |
{
|
|
682 |
aosDbgCheck(seconds <= URT_THREAD_SSLEEP_MAX);
|
|
683 |
|
|
684 |
aosThdSSleep(seconds);
|
|
685 |
}
|
|
686 |
|
|
687 |
/**
|
|
688 |
* @brief The calling thread sleeps for the specified amount of time (milliseconds).
|
|
689 |
*
|
|
690 |
* @param[in] milliseconds The duration to sleep in milliseconds.
|
|
691 |
*/
|
|
692 |
static inline void urtThreadMSleep(unsigned int milliseconds)
|
|
693 |
{
|
|
694 |
aosDbgCheck(milliseconds <= URT_THREAD_MSLEEP_MAX);
|
|
695 |
|
|
696 |
aosThdMSleep(milliseconds);
|
|
697 |
}
|
|
698 |
|
|
699 |
/**
|
|
700 |
* @brief The calling thread sleeps for the specified amount of time (microseconds).
|
|
701 |
*
|
|
702 |
* @param[in] microseconds The duration to sleep in microseconds.
|
|
703 |
*/
|
|
704 |
static inline void urtThreadUSleep(unsigned int microseconds)
|
|
705 |
{
|
|
706 |
aosDbgCheck(microseconds <= URT_THREAD_USLEEP_MAX);
|
|
707 |
|
|
708 |
aosThdUSleep(microseconds);
|
|
709 |
}
|
|
710 |
|
|
711 |
/**
|
|
712 |
* @brief The calling thread sleeps until the specified system time.
|
|
713 |
*
|
|
714 |
* @param[in] time The system time to wake up again.
|
|
715 |
*/
|
|
716 |
static inline void urtThreadSleepUntil(urt_osTime_t time)
|
|
717 |
{
|
|
718 |
aosThdSleepUntil(&time);
|
|
719 |
}
|
|
720 |
|
|
721 |
/**
|
|
722 |
* @brief The calling thread terminates and ends execution.
|
|
723 |
*/
|
|
724 |
static inline void urtThreadExit(void)
|
|
725 |
{
|
|
726 |
chThdExit(MSG_OK);
|
|
727 |
}
|
|
728 |
|
|
729 |
/**
|
|
730 |
* @brief Make a thread terminate.
|
|
731 |
*
|
|
732 |
* @param[in] thread The thread to be terminated.
|
|
733 |
* @param[in] sig The signal value how to terminate the thread.
|
|
734 |
*/
|
|
735 |
static inline void urtThreadTerminate(urt_osThread_t* thread, urt_osThreadTerminateSignal_t sig)
|
|
736 |
{
|
|
737 |
aosDbgCheck(thread != NULL);
|
|
738 |
|
|
739 |
/*
|
|
740 |
* TODO: implement kill functionality.
|
|
741 |
*/
|
|
742 |
(void)sig;
|
|
743 |
chThdTerminate(thread);
|
|
744 |
}
|
|
745 |
|
|
746 |
/**
|
|
747 |
* @brief Wait for a thread to terminate.
|
|
748 |
*
|
|
749 |
* @param[in] thread The thread to wait for.
|
|
750 |
*
|
|
751 |
* @return Status value of the terminated thread (0 = success).
|
|
752 |
*/
|
|
753 |
static inline int urtThreadJoin(urt_osThread_t* thread)
|
|
754 |
{
|
|
755 |
aosDbgCheck(thread != NULL);
|
|
756 |
|
|
757 |
return chThdWait(thread);
|
|
758 |
}
|
|
759 |
|
|
760 |
/**
|
|
761 |
* @brief Retrieve the current execution state of a thread.
|
|
762 |
*
|
|
763 |
* @param[in] thread Thread to retrieve the execution state from.
|
|
764 |
*
|
|
765 |
* @return Execution state of the specified thread.
|
|
766 |
*/
|
|
767 |
static inline urt_osThreadState_t urtThreadGetState(urt_osThread_t* thread)
|
|
768 |
{
|
|
769 |
aosDbgCheck(thread != NULL);
|
|
770 |
|
|
771 |
switch (thread->state) {
|
|
772 |
case CH_STATE_CURRENT:
|
|
773 |
return URT_THREAD_STATE_RUNNING;
|
|
774 |
case CH_STATE_READY:
|
|
775 |
return URT_THREAD_STATE_READY;
|
|
776 |
case CH_STATE_SLEEPING:
|
|
777 |
return URT_THREAD_STATE_SLEEPING;
|
|
778 |
case CH_STATE_WTSTART:
|
|
779 |
case CH_STATE_SUSPENDED:
|
|
780 |
return URT_THREAD_STATE_SUSPENDED;
|
|
781 |
case CH_STATE_FINAL:
|
|
782 |
return URT_THREAD_STATE_TERMINATED;
|
|
783 |
case CH_STATE_QUEUED:
|
|
784 |
case CH_STATE_WTSEM:
|
|
785 |
case CH_STATE_WTMTX:
|
|
786 |
case CH_STATE_WTCOND:
|
|
787 |
case CH_STATE_WTEXIT:
|
|
788 |
case CH_STATE_WTOREVT:
|
|
789 |
case CH_STATE_WTANDEVT:
|
|
790 |
case CH_STATE_SNDMSGQ:
|
|
791 |
case CH_STATE_SNDMSG:
|
|
792 |
case CH_STATE_WTMSG:
|
|
793 |
default:
|
|
794 |
return URT_THREAD_STATE_WAITING;
|
|
795 |
}
|
|
796 |
}
|
|
797 |
|
|
798 |
/**
|
|
799 |
* @brief The calling thread retrieves a pointer to itself.
|
|
800 |
*
|
|
801 |
* @return Pointer to the calling thread object.
|
|
802 |
*/
|
|
803 |
static inline urt_osThread_t* urtThreadGetSelf(void)
|
|
804 |
{
|
|
805 |
return chThdGetSelfX();
|
|
806 |
}
|
|
807 |
|
|
808 |
/**
|
|
809 |
* @brief Retrieve the first child of a thread.
|
|
810 |
*
|
|
811 |
* @param[in] thread Thread to retrieve the children from.
|
|
812 |
*
|
|
813 |
* @return Pointer to the first child or @p NULL if the thread has no children.
|
|
814 |
*/
|
|
815 |
static inline urt_osThread_t* urtThreadGetChildren(urt_osThread_t* thread)
|
|
816 |
{
|
|
817 |
aosDbgCheck(thread != NULL);
|
|
818 |
|
|
819 |
return thread->children;
|
|
820 |
}
|
|
821 |
|
|
822 |
/**
|
|
823 |
* @brief Retrieve a sibling of a thread.
|
|
824 |
*
|
|
825 |
* @param[in] thread Thread to retrieve the siblsing from.
|
|
826 |
*
|
|
827 |
* @return Pointer to the sibling thread or @p NULL if there are no further siblings.
|
|
828 |
*/
|
|
829 |
static inline urt_osThread_t* urtThreadGetSibling(urt_osThread_t* thread)
|
|
830 |
{
|
|
831 |
aosDbgCheck(thread != NULL);
|
|
832 |
|
|
833 |
return thread->sibling;
|
|
834 |
}
|
|
835 |
|
|
836 |
/**
|
|
837 |
* @brief Retrieve the parent of a thread.
|
|
838 |
*
|
|
839 |
* @param[in] thread Thread to retrieve the parent from.
|
|
840 |
*
|
|
841 |
* @return Pointer to the parent thread or @p NULL if there is nor parent.
|
|
842 |
*/
|
|
843 |
static inline urt_osThread_t* urtThreadGetParent(urt_osThread_t* thread)
|
|
844 |
{
|
|
845 |
aosDbgCheck(thread != NULL);
|
|
846 |
|
|
847 |
return thread->parent;
|
|
848 |
}
|
|
849 |
|
|
850 |
#endif /* _URT_OSAL_H_ */
|