blob: 398ff58b6c2b1079007de698c60fca849b92c0a4 [file] [log] [blame]
#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