amiro-apps / middleware / urt_osal.h @ 87c1953b
History | View | Annotate | Download (23.219 KB)
| 1 | 9316d292 | Thomas Schöpping | /*
|
|---|---|---|---|
| 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_ */ |