| #pragma once | |
| #include "FreeRTOS.h" | |
| #include "thread.h" | |
| #include <locks.h> | |
| #define INC_TASK_H | |
| /** | |
| * Initialise a timeout with the current number of elapsed ticks. This is used | |
| * in a blocking function in conjunction with `xTaskCheckForTimeOut()`. The | |
| * value returned here should be passed as the first argument of | |
| * `xTaskCheckForTimeOut()`. | |
| */ | |
| static inline void vTaskSetTimeOutState(TimeOut_t *timeout) | |
| { | |
| SystickReturn ret = thread_systemtick_get(); | |
| *timeout = ((uint64_t)ret.hi << 32) | ret.lo; | |
| } | |
| /** | |
| * Return whether a timeout has expired. The first argument should be a | |
| * pointer to the value returned by `vTaskSetTimeOutState()` before any | |
| * blocking operations. The second argument is the number of ticks to wait. | |
| * This function returns `pdTRUE` if the timeout has expired, or `pdFALSE` if | |
| * the timeout has not expired, and updates the arguments to reflect the | |
| * remaining time to wait. | |
| */ | |
| static inline BaseType_t xTaskCheckForTimeOut(TimeOut_t *pxTimeOut, | |
| TickType_t *pxTicksToWait) | |
| { | |
| BaseType_t xReturn; | |
| uint64_t timeBlock; | |
| TickType_t xElapsedTime; | |
| vTaskSetTimeOutState(&timeBlock); | |
| xElapsedTime = timeBlock - *pxTimeOut; | |
| if (xElapsedTime < *pxTicksToWait) | |
| { | |
| *pxTicksToWait -= xElapsedTime; | |
| *pxTimeOut = timeBlock; | |
| xReturn = pdFALSE; | |
| } | |
| else | |
| { | |
| *pxTicksToWait = (TickType_t)0; | |
| xReturn = pdTRUE; | |
| } | |
| return xReturn; | |
| } | |
| /** | |
| * Block the current thread for a given number of ticks. | |
| */ | |
| static inline void vTaskDelay(const TickType_t xTicksToDelay) | |
| { | |
| struct Timeout timeout = {0, xTicksToDelay}; | |
| thread_sleep(&timeout, ThreadSleepNoEarlyWake); | |
| } | |
| /** | |
| * Return the number of ticks elapsed since the system booted. This is | |
| * truncated to a 32-bit value. | |
| */ | |
| static inline TickType_t xTaskGetTickCount(void) | |
| { | |
| return thread_systemtick_get().lo; | |
| } | |
| /** | |
| * Returns the current thread ID. | |
| */ | |
| static inline TaskHandle_t xTaskGetCurrentTaskHandle(void) | |
| { | |
| return thread_id_get(); | |
| } | |
| __BEGIN_DECLS | |
| /** | |
| * Lock used to simulate disabling interrupts in `taskENTER_CRITICAL` and | |
| * `taskEXIT_CRITICAL`. Code using these APIs must provide a definition to | |
| * accompany this declaration. | |
| */ | |
| extern struct RecursiveMutexState __CriticalSectionFlagLock; | |
| /** | |
| * Lock used to simulate disabling interrupts in `vTaskSuspendAll` and | |
| * `xTaskResumeAll`. Code using these APIs must provide a definition to | |
| * accompany this declaration. | |
| */ | |
| extern struct RecursiveMutexState __SuspendFlagLock; | |
| __END_DECLS | |
| /** | |
| * Critical section. This acquires a recursive mutex. In FreeRTOS, this | |
| * disables interrupts. The CHERIoT RTOS security model does not permit | |
| * interrupts to be arbitrarily disabled, only for designated scopes. Callers | |
| * of this should be carefully audited to ensure that they are safe. | |
| */ | |
| static inline void taskENTER_CRITICAL(void) | |
| { | |
| Timeout t = {0, UnlimitedTimeout}; | |
| recursivemutex_trylock(&t, &__CriticalSectionFlagLock); | |
| } | |
| /** | |
| * Exit a critical section entered with `taskENTER_CRITICAL`. | |
| */ | |
| static inline void taskEXIT_CRITICAL(void) | |
| { | |
| recursivemutex_unlock(&__CriticalSectionFlagLock); | |
| } | |
| /** | |
| * Critical section. This acquires a recursive mutex. In FreeRTOS, this | |
| * disables interrupts. The CHERIoT RTOS security model does not permit | |
| * interrupts to be arbitrarily disabled, only for designated scopes. Callers | |
| * of this should be carefully audited to ensure that they are safe. | |
| */ | |
| static inline void vTaskSuspendAll(void) | |
| { | |
| Timeout t = {0, UnlimitedTimeout}; | |
| recursivemutex_trylock(&t, &__SuspendFlagLock); | |
| } | |
| /** | |
| * Exit a critical section entered with `vTaskSuspendAll`. | |
| */ | |
| static inline BaseType_t xTaskResumeAll(void) | |
| { | |
| recursivemutex_unlock(&__SuspendFlagLock); | |
| return pdTRUE; | |
| } | |
| /** | |
| * Exit a critical section entered with `vTaskSuspendAll`. | |
| */ | |
| static inline void vTaskResumeAll(void) | |
| { | |
| recursivemutex_unlock(&__SuspendFlagLock); | |
| } | |
| /** | |
| * Task creation API. CHERIoT RTOS does not permit dynamic thread creation and | |
| * so this simply provides a warning so that ported code can be modified to | |
| * avoid the API. | |
| */ | |
| #define xTaskCreate(...) \ | |
| _Pragma("GCC warning \"Dynamic thread creation is not supported\"")( \ | |
| TaskHandle_t) - \ | |
| 1 | |
| /** | |
| * Task creation API. CHERIoT RTOS does not permit dynamic thread creation and | |
| * so this simply provides a warning so that ported code can be modified to | |
| * avoid the API. | |
| */ | |
| #define xTaskCreateStatic(...) \ | |
| _Pragma("GCC warning \"Dynamic thread creation is not supported\"")( \ | |
| TaskHandle_t) - \ | |
| 1 |