Save local changes (4 yrs later)
This commit is contained in:
parent
4e9d7b1334
commit
8111d591cb
60 changed files with 2039 additions and 279 deletions
|
@ -1,6 +1,5 @@
|
|||
/* --------------------------------------------------------------------------
|
||||
* Portions Copyright © 2019 STMicroelectronics International N.V. All rights reserved.
|
||||
* Copyright (c) 2013-2019 Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2013-2020 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
|
@ -24,13 +23,16 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "cmsis_os2.h" // ::CMSIS:RTOS2
|
||||
#include "cmsis_compiler.h"
|
||||
#include "cmsis_compiler.h" // Compiler agnostic definitions
|
||||
|
||||
#include "FreeRTOS.h" // ARM.FreeRTOS::RTOS:Core
|
||||
#include "task.h" // ARM.FreeRTOS::RTOS:Core
|
||||
#include "event_groups.h" // ARM.FreeRTOS::RTOS:Event Groups
|
||||
#include "semphr.h" // ARM.FreeRTOS::RTOS:Core
|
||||
|
||||
#include "freertos_mpool.h" // osMemoryPool definitions
|
||||
#include "freertos_os2.h" // Configuration check and setup
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef __ARM_ARCH_6M__
|
||||
#define __ARM_ARCH_6M__ 0
|
||||
|
@ -73,7 +75,9 @@
|
|||
#define IS_IRQ_MODE() (__get_IPSR() != 0U)
|
||||
#endif
|
||||
|
||||
#define IS_IRQ() (IS_IRQ_MODE() || (IS_IRQ_MASKED() && (KernelState == osKernelRunning)))
|
||||
#define IS_IRQ() IS_IRQ_MODE()
|
||||
|
||||
#define SVCall_IRQ_NBR (IRQn_Type) -5 /* SVCall_IRQ_NBR added as SV_Call handler name is not the same for CM0 and for all other CMx */
|
||||
|
||||
/* Limits */
|
||||
#define MAX_BITS_TASK_NOTIFY 31U
|
||||
|
@ -108,7 +112,7 @@ static osKernelState_t KernelState = osKernelInactive;
|
|||
definition configHEAP_5_REGIONS as parameter. Overriding configHEAP_5_REGIONS
|
||||
is possible by defining it globally or in FreeRTOSConfig.h.
|
||||
*/
|
||||
#if defined(USE_FREERTOS_HEAP_5)
|
||||
#if defined(USE_FreeRTOS_HEAP_5)
|
||||
#if (configAPPLICATION_ALLOCATED_HEAP == 0)
|
||||
/*
|
||||
FreeRTOS heap is not defined by the application.
|
||||
|
@ -138,7 +142,7 @@ static osKernelState_t KernelState = osKernelInactive;
|
|||
*/
|
||||
#define HEAP_5_REGION_SETUP 0
|
||||
#endif /* configAPPLICATION_ALLOCATED_HEAP */
|
||||
#endif /* USE_FREERTOS_HEAP_5 */
|
||||
#endif /* USE_FreeRTOS_HEAP_5 */
|
||||
|
||||
#if defined(SysTick)
|
||||
#undef SysTick_Handler
|
||||
|
@ -151,6 +155,7 @@ extern void xPortSysTickHandler (void);
|
|||
/*
|
||||
SysTick handler implementation that also clears overflow flag.
|
||||
*/
|
||||
#if (USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION == 0)
|
||||
void SysTick_Handler (void) {
|
||||
/* Clear overflow flag */
|
||||
SysTick->CTRL;
|
||||
|
@ -160,6 +165,7 @@ void SysTick_Handler (void) {
|
|||
xPortSysTickHandler();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* SysTick */
|
||||
|
||||
/*
|
||||
|
@ -170,16 +176,23 @@ __STATIC_INLINE void SVC_Setup (void) {
|
|||
/* Service Call interrupt might be configured before kernel start */
|
||||
/* and when its priority is lower or equal to BASEPRI, svc intruction */
|
||||
/* causes a Hard Fault. */
|
||||
|
||||
/*
|
||||
* the call below has introduced a regression compared to revious release
|
||||
* The issue was logged under:https://github.com/ARM-software/CMSIS-FreeRTOS/issues/35
|
||||
* until it is correctly fixed, the code below is commented
|
||||
*/
|
||||
/* NVIC_SetPriority (SVCall_IRQn, 0U); */
|
||||
NVIC_SetPriority (SVCall_IRQ_NBR, 0U);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
Function macro used to retrieve semaphore count from ISR
|
||||
*/
|
||||
#ifndef uxSemaphoreGetCountFromISR
|
||||
#define uxSemaphoreGetCountFromISR( xSemaphore ) uxQueueMessagesWaitingFromISR( ( QueueHandle_t ) ( xSemaphore ) )
|
||||
#endif
|
||||
|
||||
/* Get OS Tick count value */
|
||||
static uint32_t OS_Tick_GetCount (void);
|
||||
/* Get OS Tick overflow status */
|
||||
static uint32_t OS_Tick_GetOverflow (void);
|
||||
/* Get OS Tick interval */
|
||||
static uint32_t OS_Tick_GetInterval (void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
osStatus_t osKernelInitialize (void) {
|
||||
|
@ -190,7 +203,10 @@ osStatus_t osKernelInitialize (void) {
|
|||
}
|
||||
else {
|
||||
if (KernelState == osKernelInactive) {
|
||||
#if defined(USE_FREERTOS_HEAP_5) && (HEAP_5_REGION_SETUP == 1)
|
||||
#if defined(USE_TRACE_EVENT_RECORDER)
|
||||
EvrFreeRTOSSetup(0U);
|
||||
#endif
|
||||
#if defined(USE_FreeRTOS_HEAP_5) && (HEAP_5_REGION_SETUP == 1)
|
||||
vPortDefineHeapRegions (configHEAP_5_REGIONS);
|
||||
#endif
|
||||
KernelState = osKernelReady;
|
||||
|
@ -380,6 +396,22 @@ uint32_t osKernelGetTickFreq (void) {
|
|||
return (configTICK_RATE_HZ);
|
||||
}
|
||||
|
||||
/* Get OS Tick count value */
|
||||
static uint32_t OS_Tick_GetCount (void) {
|
||||
uint32_t load = SysTick->LOAD;
|
||||
return (load - SysTick->VAL);
|
||||
}
|
||||
|
||||
/* Get OS Tick overflow status */
|
||||
static uint32_t OS_Tick_GetOverflow (void) {
|
||||
return ((SysTick->CTRL >> 16) & 1U);
|
||||
}
|
||||
|
||||
/* Get OS Tick interval */
|
||||
static uint32_t OS_Tick_GetInterval (void) {
|
||||
return (SysTick->LOAD + 1U);
|
||||
}
|
||||
|
||||
uint32_t osKernelGetSysTimerCount (void) {
|
||||
uint32_t irqmask = IS_IRQ_MASKED();
|
||||
TickType_t ticks;
|
||||
|
@ -388,8 +420,14 @@ uint32_t osKernelGetSysTimerCount (void) {
|
|||
__disable_irq();
|
||||
|
||||
ticks = xTaskGetTickCount();
|
||||
val = OS_Tick_GetCount();
|
||||
|
||||
if (OS_Tick_GetOverflow() != 0U) {
|
||||
val = OS_Tick_GetCount();
|
||||
ticks++;
|
||||
}
|
||||
val += ticks * OS_Tick_GetInterval();
|
||||
|
||||
val = ticks * ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );
|
||||
if (irqmask == 0U) {
|
||||
__enable_irq();
|
||||
}
|
||||
|
@ -452,14 +490,18 @@ osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAtt
|
|||
}
|
||||
|
||||
if (mem == 1) {
|
||||
hTask = xTaskCreateStatic ((TaskFunction_t)func, name, stack, argument, prio, (StackType_t *)attr->stack_mem,
|
||||
(StaticTask_t *)attr->cb_mem);
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
hTask = xTaskCreateStatic ((TaskFunction_t)func, name, stack, argument, prio, (StackType_t *)attr->stack_mem,
|
||||
(StaticTask_t *)attr->cb_mem);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (mem == 0) {
|
||||
if (xTaskCreate ((TaskFunction_t)func, name, (uint16_t)stack, argument, prio, &hTask) != pdPASS) {
|
||||
hTask = NULL;
|
||||
}
|
||||
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
if (xTaskCreate ((TaskFunction_t)func, name, (uint16_t)stack, argument, prio, &hTask) != pdPASS) {
|
||||
hTask = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -517,7 +559,7 @@ uint32_t osThreadGetStackSpace (osThreadId_t thread_id) {
|
|||
if (IS_IRQ() || (hTask == NULL)) {
|
||||
sz = 0U;
|
||||
} else {
|
||||
sz = (uint32_t)uxTaskGetStackHighWaterMark (hTask);
|
||||
sz = (uint32_t)(uxTaskGetStackHighWaterMark(hTask) * sizeof(StackType_t));
|
||||
}
|
||||
|
||||
return (sz);
|
||||
|
@ -548,7 +590,7 @@ osPriority_t osThreadGetPriority (osThreadId_t thread_id) {
|
|||
if (IS_IRQ() || (hTask == NULL)) {
|
||||
prio = osPriorityError;
|
||||
} else {
|
||||
prio = (osPriority_t)uxTaskPriorityGet (hTask);
|
||||
prio = (osPriority_t)((int32_t)uxTaskPriorityGet (hTask));
|
||||
}
|
||||
|
||||
return (prio);
|
||||
|
@ -567,6 +609,7 @@ osStatus_t osThreadYield (void) {
|
|||
return (stat);
|
||||
}
|
||||
|
||||
#if (configUSE_OS2_THREAD_SUSPEND_RESUME == 1)
|
||||
osStatus_t osThreadSuspend (osThreadId_t thread_id) {
|
||||
TaskHandle_t hTask = (TaskHandle_t)thread_id;
|
||||
osStatus_t stat;
|
||||
|
@ -602,6 +645,7 @@ osStatus_t osThreadResume (osThreadId_t thread_id) {
|
|||
|
||||
return (stat);
|
||||
}
|
||||
#endif /* (configUSE_OS2_THREAD_SUSPEND_RESUME == 1) */
|
||||
|
||||
__NO_RETURN void osThreadExit (void) {
|
||||
#ifndef USE_FreeRTOS_HEAP_1
|
||||
|
@ -651,6 +695,7 @@ uint32_t osThreadGetCount (void) {
|
|||
return (count);
|
||||
}
|
||||
|
||||
#if (configUSE_OS2_THREAD_ENUMERATE == 1)
|
||||
uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) {
|
||||
uint32_t i, count;
|
||||
TaskStatus_t *task;
|
||||
|
@ -678,7 +723,9 @@ uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) {
|
|||
|
||||
return (count);
|
||||
}
|
||||
#endif /* (configUSE_OS2_THREAD_ENUMERATE == 1) */
|
||||
|
||||
#if (configUSE_OS2_THREAD_FLAGS == 1)
|
||||
uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) {
|
||||
TaskHandle_t hTask = (TaskHandle_t)thread_id;
|
||||
uint32_t rflags;
|
||||
|
@ -829,6 +876,7 @@ uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout)
|
|||
/* Return flags before clearing */
|
||||
return (rflags);
|
||||
}
|
||||
#endif /* (configUSE_OS2_THREAD_FLAGS == 1) */
|
||||
|
||||
osStatus_t osDelay (uint32_t ticks) {
|
||||
osStatus_t stat;
|
||||
|
@ -876,6 +924,7 @@ osStatus_t osDelayUntil (uint32_t ticks) {
|
|||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if (configUSE_OS2_TIMER == 1)
|
||||
|
||||
static void TimerCallback (TimerHandle_t hTimer) {
|
||||
TimerCallback_t *callb;
|
||||
|
@ -932,13 +981,21 @@ osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument,
|
|||
}
|
||||
|
||||
if (mem == 1) {
|
||||
hTimer = xTimerCreateStatic (name, 1, reload, callb, TimerCallback, (StaticTimer_t *)attr->cb_mem);
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
hTimer = xTimerCreateStatic (name, 1, reload, callb, TimerCallback, (StaticTimer_t *)attr->cb_mem);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (mem == 0) {
|
||||
hTimer = xTimerCreate (name, 1, reload, callb, TimerCallback);
|
||||
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
hTimer = xTimerCreate (name, 1, reload, callb, TimerCallback);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if ((hTimer == NULL) && (callb != NULL)) {
|
||||
vPortFree (callb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1046,6 +1103,7 @@ osStatus_t osTimerDelete (osTimerId_t timer_id) {
|
|||
|
||||
return (stat);
|
||||
}
|
||||
#endif /* (configUSE_OS2_TIMER == 1) */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -1073,11 +1131,15 @@ osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr) {
|
|||
}
|
||||
|
||||
if (mem == 1) {
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
hEventGroup = xEventGroupCreateStatic (attr->cb_mem);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (mem == 0) {
|
||||
hEventGroup = xEventGroupCreate();
|
||||
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
hEventGroup = xEventGroupCreate();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1094,6 +1156,11 @@ uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) {
|
|||
rflags = (uint32_t)osErrorParameter;
|
||||
}
|
||||
else if (IS_IRQ()) {
|
||||
#if (configUSE_OS2_EVENTFLAGS_FROM_ISR == 0)
|
||||
(void)yield;
|
||||
/* Enable timers and xTimerPendFunctionCall function to support osEventFlagsSet from ISR */
|
||||
rflags = (uint32_t)osErrorResource;
|
||||
#else
|
||||
yield = pdFALSE;
|
||||
|
||||
if (xEventGroupSetBitsFromISR (hEventGroup, (EventBits_t)flags, &yield) == pdFAIL) {
|
||||
|
@ -1102,6 +1169,7 @@ uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) {
|
|||
rflags = flags;
|
||||
portYIELD_FROM_ISR (yield);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
rflags = xEventGroupSetBits (hEventGroup, (EventBits_t)flags);
|
||||
|
@ -1118,11 +1186,16 @@ uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) {
|
|||
rflags = (uint32_t)osErrorParameter;
|
||||
}
|
||||
else if (IS_IRQ()) {
|
||||
#if (configUSE_OS2_EVENTFLAGS_FROM_ISR == 0)
|
||||
/* Enable timers and xTimerPendFunctionCall function to support osEventFlagsSet from ISR */
|
||||
rflags = (uint32_t)osErrorResource;
|
||||
#else
|
||||
rflags = xEventGroupGetBitsFromISR (hEventGroup);
|
||||
|
||||
if (xEventGroupClearBitsFromISR (hEventGroup, (EventBits_t)flags) == pdFAIL) {
|
||||
rflags = (uint32_t)osErrorResource;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
rflags = xEventGroupClearBits (hEventGroup, (EventBits_t)flags);
|
||||
|
@ -1176,7 +1249,7 @@ uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t opti
|
|||
rflags = xEventGroupWaitBits (hEventGroup, (EventBits_t)flags, exit_clr, wait_all, (TickType_t)timeout);
|
||||
|
||||
if (options & osFlagsWaitAll) {
|
||||
if (flags != rflags) {
|
||||
if ((flags & rflags) != flags) {
|
||||
if (timeout > 0U) {
|
||||
rflags = (uint32_t)osErrorTimeout;
|
||||
} else {
|
||||
|
@ -1221,6 +1294,7 @@ osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id) {
|
|||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if (configUSE_OS2_MUTEX == 1)
|
||||
|
||||
osMutexId_t osMutexNew (const osMutexAttr_t *attr) {
|
||||
SemaphoreHandle_t hMutex;
|
||||
|
@ -1264,20 +1338,28 @@ osMutexId_t osMutexNew (const osMutexAttr_t *attr) {
|
|||
}
|
||||
|
||||
if (mem == 1) {
|
||||
if (rmtx != 0U) {
|
||||
hMutex = xSemaphoreCreateRecursiveMutexStatic (attr->cb_mem);
|
||||
}
|
||||
else {
|
||||
hMutex = xSemaphoreCreateMutexStatic (attr->cb_mem);
|
||||
}
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
if (rmtx != 0U) {
|
||||
#if (configUSE_RECURSIVE_MUTEXES == 1)
|
||||
hMutex = xSemaphoreCreateRecursiveMutexStatic (attr->cb_mem);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
hMutex = xSemaphoreCreateMutexStatic (attr->cb_mem);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (mem == 0) {
|
||||
if (rmtx != 0U) {
|
||||
hMutex = xSemaphoreCreateRecursiveMutex ();
|
||||
} else {
|
||||
hMutex = xSemaphoreCreateMutex ();
|
||||
}
|
||||
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
if (rmtx != 0U) {
|
||||
#if (configUSE_RECURSIVE_MUTEXES == 1)
|
||||
hMutex = xSemaphoreCreateRecursiveMutex ();
|
||||
#endif
|
||||
} else {
|
||||
hMutex = xSemaphoreCreateMutex ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1320,6 +1402,7 @@ osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
|
|||
}
|
||||
else {
|
||||
if (rmtx != 0U) {
|
||||
#if (configUSE_RECURSIVE_MUTEXES == 1)
|
||||
if (xSemaphoreTakeRecursive (hMutex, timeout) != pdPASS) {
|
||||
if (timeout != 0U) {
|
||||
stat = osErrorTimeout;
|
||||
|
@ -1327,6 +1410,7 @@ osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
|
|||
stat = osErrorResource;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (xSemaphoreTake (hMutex, timeout) != pdPASS) {
|
||||
|
@ -1361,9 +1445,11 @@ osStatus_t osMutexRelease (osMutexId_t mutex_id) {
|
|||
}
|
||||
else {
|
||||
if (rmtx != 0U) {
|
||||
#if (configUSE_RECURSIVE_MUTEXES == 1)
|
||||
if (xSemaphoreGiveRecursive (hMutex) != pdPASS) {
|
||||
stat = osErrorResource;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (xSemaphoreGive (hMutex) != pdPASS) {
|
||||
|
@ -1416,6 +1502,7 @@ osStatus_t osMutexDelete (osMutexId_t mutex_id) {
|
|||
|
||||
return (stat);
|
||||
}
|
||||
#endif /* (configUSE_OS2_MUTEX == 1) */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -1448,10 +1535,14 @@ osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, cons
|
|||
if (mem != -1) {
|
||||
if (max_count == 1U) {
|
||||
if (mem == 1) {
|
||||
hSemaphore = xSemaphoreCreateBinaryStatic ((StaticSemaphore_t *)attr->cb_mem);
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
hSemaphore = xSemaphoreCreateBinaryStatic ((StaticSemaphore_t *)attr->cb_mem);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
hSemaphore = xSemaphoreCreateBinary();
|
||||
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
hSemaphore = xSemaphoreCreateBinary();
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((hSemaphore != NULL) && (initial_count != 0U)) {
|
||||
|
@ -1463,10 +1554,14 @@ osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, cons
|
|||
}
|
||||
else {
|
||||
if (mem == 1) {
|
||||
hSemaphore = xSemaphoreCreateCountingStatic (max_count, initial_count, (StaticSemaphore_t *)attr->cb_mem);
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
hSemaphore = xSemaphoreCreateCountingStatic (max_count, initial_count, (StaticSemaphore_t *)attr->cb_mem);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
hSemaphore = xSemaphoreCreateCounting (max_count, initial_count);
|
||||
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
hSemaphore = xSemaphoreCreateCounting (max_count, initial_count);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1624,11 +1719,15 @@ osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, con
|
|||
}
|
||||
|
||||
if (mem == 1) {
|
||||
hQueue = xQueueCreateStatic (msg_count, msg_size, attr->mq_mem, attr->cb_mem);
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
hQueue = xQueueCreateStatic (msg_count, msg_size, attr->mq_mem, attr->cb_mem);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (mem == 0) {
|
||||
hQueue = xQueueCreate (msg_count, msg_size);
|
||||
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
hQueue = xQueueCreate (msg_count, msg_size);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1842,6 +1941,463 @@ osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) {
|
|||
return (stat);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifdef FREERTOS_MPOOL_H_
|
||||
|
||||
/* Static memory pool functions */
|
||||
static void FreeBlock (MemPool_t *mp, void *block);
|
||||
static void *AllocBlock (MemPool_t *mp);
|
||||
static void *CreateBlock (MemPool_t *mp);
|
||||
|
||||
osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) {
|
||||
MemPool_t *mp;
|
||||
const char *name;
|
||||
int32_t mem_cb, mem_mp;
|
||||
uint32_t sz;
|
||||
|
||||
if (IS_IRQ()) {
|
||||
mp = NULL;
|
||||
}
|
||||
else if ((block_count == 0U) || (block_size == 0U)) {
|
||||
mp = NULL;
|
||||
}
|
||||
else {
|
||||
mp = NULL;
|
||||
sz = MEMPOOL_ARR_SIZE (block_count, block_size);
|
||||
|
||||
name = NULL;
|
||||
mem_cb = -1;
|
||||
mem_mp = -1;
|
||||
|
||||
if (attr != NULL) {
|
||||
if (attr->name != NULL) {
|
||||
name = attr->name;
|
||||
}
|
||||
|
||||
if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(MemPool_t))) {
|
||||
/* Static control block is provided */
|
||||
mem_cb = 1;
|
||||
}
|
||||
else if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
|
||||
/* Allocate control block memory on heap */
|
||||
mem_cb = 0;
|
||||
}
|
||||
|
||||
if ((attr->mp_mem == NULL) && (attr->mp_size == 0U)) {
|
||||
/* Allocate memory array on heap */
|
||||
mem_mp = 0;
|
||||
}
|
||||
else {
|
||||
if (attr->mp_mem != NULL) {
|
||||
/* Check if array is 4-byte aligned */
|
||||
if (((uint32_t)attr->mp_mem & 3U) == 0U) {
|
||||
/* Check if array big enough */
|
||||
if (attr->mp_size >= sz) {
|
||||
/* Static memory pool array is provided */
|
||||
mem_mp = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Attributes not provided, allocate memory on heap */
|
||||
mem_cb = 0;
|
||||
mem_mp = 0;
|
||||
}
|
||||
|
||||
if (mem_cb == 0) {
|
||||
mp = pvPortMalloc (sizeof(MemPool_t));
|
||||
} else {
|
||||
mp = attr->cb_mem;
|
||||
}
|
||||
|
||||
if (mp != NULL) {
|
||||
/* Create a semaphore (max count == initial count == block_count) */
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
mp->sem = xSemaphoreCreateCountingStatic (block_count, block_count, &mp->mem_sem);
|
||||
#elif (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
mp->sem = xSemaphoreCreateCounting (block_count, block_count);
|
||||
#else
|
||||
mp->sem == NULL;
|
||||
#endif
|
||||
|
||||
if (mp->sem != NULL) {
|
||||
/* Setup memory array */
|
||||
if (mem_mp == 0) {
|
||||
mp->mem_arr = pvPortMalloc (sz);
|
||||
} else {
|
||||
mp->mem_arr = attr->mp_mem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((mp != NULL) && (mp->mem_arr != NULL)) {
|
||||
/* Memory pool can be created */
|
||||
mp->head = NULL;
|
||||
mp->mem_sz = sz;
|
||||
mp->name = name;
|
||||
mp->bl_sz = block_size;
|
||||
mp->bl_cnt = block_count;
|
||||
mp->n = 0U;
|
||||
|
||||
/* Set heap allocated memory flags */
|
||||
mp->status = MPOOL_STATUS;
|
||||
|
||||
if (mem_cb == 0) {
|
||||
/* Control block on heap */
|
||||
mp->status |= 1U;
|
||||
}
|
||||
if (mem_mp == 0) {
|
||||
/* Memory array on heap */
|
||||
mp->status |= 2U;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Memory pool cannot be created, release allocated resources */
|
||||
if ((mem_cb == 0) && (mp != NULL)) {
|
||||
/* Free control block memory */
|
||||
vPortFree (mp);
|
||||
}
|
||||
mp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (mp);
|
||||
}
|
||||
|
||||
const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id) {
|
||||
MemPool_t *mp = (osMemoryPoolId_t)mp_id;
|
||||
const char *p;
|
||||
|
||||
if (IS_IRQ()) {
|
||||
p = NULL;
|
||||
}
|
||||
else if (mp_id == NULL) {
|
||||
p = NULL;
|
||||
}
|
||||
else {
|
||||
p = mp->name;
|
||||
}
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) {
|
||||
MemPool_t *mp;
|
||||
void *block;
|
||||
uint32_t isrm;
|
||||
|
||||
if (mp_id == NULL) {
|
||||
/* Invalid input parameters */
|
||||
block = NULL;
|
||||
}
|
||||
else {
|
||||
block = NULL;
|
||||
|
||||
mp = (MemPool_t *)mp_id;
|
||||
|
||||
if ((mp->status & MPOOL_STATUS) == MPOOL_STATUS) {
|
||||
if (IS_IRQ()) {
|
||||
if (timeout == 0U) {
|
||||
if (xSemaphoreTakeFromISR (mp->sem, NULL) == pdTRUE) {
|
||||
if ((mp->status & MPOOL_STATUS) == MPOOL_STATUS) {
|
||||
isrm = taskENTER_CRITICAL_FROM_ISR();
|
||||
|
||||
/* Get a block from the free-list */
|
||||
block = AllocBlock(mp);
|
||||
|
||||
if (block == NULL) {
|
||||
/* List of free blocks is empty, 'create' new block */
|
||||
block = CreateBlock(mp);
|
||||
}
|
||||
|
||||
taskEXIT_CRITICAL_FROM_ISR(isrm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (xSemaphoreTake (mp->sem, (TickType_t)timeout) == pdTRUE) {
|
||||
if ((mp->status & MPOOL_STATUS) == MPOOL_STATUS) {
|
||||
taskENTER_CRITICAL();
|
||||
|
||||
/* Get a block from the free-list */
|
||||
block = AllocBlock(mp);
|
||||
|
||||
if (block == NULL) {
|
||||
/* List of free blocks is empty, 'create' new block */
|
||||
block = CreateBlock(mp);
|
||||
}
|
||||
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (block);
|
||||
}
|
||||
|
||||
osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) {
|
||||
MemPool_t *mp;
|
||||
osStatus_t stat;
|
||||
uint32_t isrm;
|
||||
BaseType_t yield;
|
||||
|
||||
if ((mp_id == NULL) || (block == NULL)) {
|
||||
/* Invalid input parameters */
|
||||
stat = osErrorParameter;
|
||||
}
|
||||
else {
|
||||
mp = (MemPool_t *)mp_id;
|
||||
|
||||
if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
|
||||
/* Invalid object status */
|
||||
stat = osErrorResource;
|
||||
}
|
||||
else if ((block < (void *)&mp->mem_arr[0]) || (block > (void*)&mp->mem_arr[mp->mem_sz-1])) {
|
||||
/* Block pointer outside of memory array area */
|
||||
stat = osErrorParameter;
|
||||
}
|
||||
else {
|
||||
stat = osOK;
|
||||
|
||||
if (IS_IRQ()) {
|
||||
if (uxSemaphoreGetCountFromISR (mp->sem) == mp->bl_cnt) {
|
||||
stat = osErrorResource;
|
||||
}
|
||||
else {
|
||||
isrm = taskENTER_CRITICAL_FROM_ISR();
|
||||
|
||||
/* Add block to the list of free blocks */
|
||||
FreeBlock(mp, block);
|
||||
|
||||
taskEXIT_CRITICAL_FROM_ISR(isrm);
|
||||
|
||||
yield = pdFALSE;
|
||||
xSemaphoreGiveFromISR (mp->sem, &yield);
|
||||
portYIELD_FROM_ISR (yield);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (uxSemaphoreGetCount (mp->sem) == mp->bl_cnt) {
|
||||
stat = osErrorResource;
|
||||
}
|
||||
else {
|
||||
taskENTER_CRITICAL();
|
||||
|
||||
/* Add block to the list of free blocks */
|
||||
FreeBlock(mp, block);
|
||||
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
xSemaphoreGive (mp->sem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (stat);
|
||||
}
|
||||
|
||||
uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) {
|
||||
MemPool_t *mp;
|
||||
uint32_t n;
|
||||
|
||||
if (mp_id == NULL) {
|
||||
/* Invalid input parameters */
|
||||
n = 0U;
|
||||
}
|
||||
else {
|
||||
mp = (MemPool_t *)mp_id;
|
||||
|
||||
if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
|
||||
/* Invalid object status */
|
||||
n = 0U;
|
||||
}
|
||||
else {
|
||||
n = mp->bl_cnt;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return maximum number of memory blocks */
|
||||
return (n);
|
||||
}
|
||||
|
||||
uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) {
|
||||
MemPool_t *mp;
|
||||
uint32_t sz;
|
||||
|
||||
if (mp_id == NULL) {
|
||||
/* Invalid input parameters */
|
||||
sz = 0U;
|
||||
}
|
||||
else {
|
||||
mp = (MemPool_t *)mp_id;
|
||||
|
||||
if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
|
||||
/* Invalid object status */
|
||||
sz = 0U;
|
||||
}
|
||||
else {
|
||||
sz = mp->bl_sz;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return memory block size in bytes */
|
||||
return (sz);
|
||||
}
|
||||
|
||||
uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id) {
|
||||
MemPool_t *mp;
|
||||
uint32_t n;
|
||||
|
||||
if (mp_id == NULL) {
|
||||
/* Invalid input parameters */
|
||||
n = 0U;
|
||||
}
|
||||
else {
|
||||
mp = (MemPool_t *)mp_id;
|
||||
|
||||
if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
|
||||
/* Invalid object status */
|
||||
n = 0U;
|
||||
}
|
||||
else {
|
||||
if (IS_IRQ()) {
|
||||
n = uxSemaphoreGetCountFromISR (mp->sem);
|
||||
} else {
|
||||
n = uxSemaphoreGetCount (mp->sem);
|
||||
}
|
||||
|
||||
n = mp->bl_cnt - n;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return number of memory blocks used */
|
||||
return (n);
|
||||
}
|
||||
|
||||
uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id) {
|
||||
MemPool_t *mp;
|
||||
uint32_t n;
|
||||
|
||||
if (mp_id == NULL) {
|
||||
/* Invalid input parameters */
|
||||
n = 0U;
|
||||
}
|
||||
else {
|
||||
mp = (MemPool_t *)mp_id;
|
||||
|
||||
if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
|
||||
/* Invalid object status */
|
||||
n = 0U;
|
||||
}
|
||||
else {
|
||||
if (IS_IRQ()) {
|
||||
n = uxSemaphoreGetCountFromISR (mp->sem);
|
||||
} else {
|
||||
n = uxSemaphoreGetCount (mp->sem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return number of memory blocks available */
|
||||
return (n);
|
||||
}
|
||||
|
||||
osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id) {
|
||||
MemPool_t *mp;
|
||||
osStatus_t stat;
|
||||
|
||||
if (mp_id == NULL) {
|
||||
/* Invalid input parameters */
|
||||
stat = osErrorParameter;
|
||||
}
|
||||
else if (IS_IRQ()) {
|
||||
stat = osErrorISR;
|
||||
}
|
||||
else {
|
||||
mp = (MemPool_t *)mp_id;
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
|
||||
/* Invalidate control block status */
|
||||
mp->status = mp->status & 3U;
|
||||
|
||||
/* Wake-up tasks waiting for pool semaphore */
|
||||
while (xSemaphoreGive (mp->sem) == pdTRUE);
|
||||
|
||||
mp->head = NULL;
|
||||
mp->bl_sz = 0U;
|
||||
mp->bl_cnt = 0U;
|
||||
|
||||
if ((mp->status & 2U) != 0U) {
|
||||
/* Memory pool array allocated on heap */
|
||||
vPortFree (mp->mem_arr);
|
||||
}
|
||||
if ((mp->status & 1U) != 0U) {
|
||||
/* Memory pool control block allocated on heap */
|
||||
vPortFree (mp);
|
||||
}
|
||||
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
stat = osOK;
|
||||
}
|
||||
|
||||
return (stat);
|
||||
}
|
||||
|
||||
/*
|
||||
Create new block given according to the current block index.
|
||||
*/
|
||||
static void *CreateBlock (MemPool_t *mp) {
|
||||
MemPoolBlock_t *p = NULL;
|
||||
|
||||
if (mp->n < mp->bl_cnt) {
|
||||
/* Unallocated blocks exist, set pointer to new block */
|
||||
p = (void *)(mp->mem_arr + (mp->bl_sz * mp->n));
|
||||
|
||||
/* Increment block index */
|
||||
mp->n += 1U;
|
||||
}
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
/*
|
||||
Allocate a block by reading the list of free blocks.
|
||||
*/
|
||||
static void *AllocBlock (MemPool_t *mp) {
|
||||
MemPoolBlock_t *p = NULL;
|
||||
|
||||
if (mp->head != NULL) {
|
||||
/* List of free block exists, get head block */
|
||||
p = mp->head;
|
||||
|
||||
/* Head block is now next on the list */
|
||||
mp->head = p->next;
|
||||
}
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
/*
|
||||
Free block by putting it to the list of free blocks.
|
||||
*/
|
||||
static void FreeBlock (MemPool_t *mp, void *block) {
|
||||
MemPoolBlock_t *p = block;
|
||||
|
||||
/* Store current head into block memory space */
|
||||
p->next = mp->head;
|
||||
|
||||
/* Store current block as new head */
|
||||
mp->head = p;
|
||||
}
|
||||
#endif /* FREERTOS_MPOOL_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/* Callback function prototypes */
|
||||
|
@ -1886,28 +2442,25 @@ __WEAK void vApplicationDaemonTaskStartupHook (void){}
|
|||
__WEAK void vApplicationStackOverflowHook (TaskHandle_t xTask, signed char *pcTaskName) {
|
||||
(void)xTask;
|
||||
(void)pcTaskName;
|
||||
configASSERT(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
/* External Idle and Timer task static memory allocation functions */
|
||||
extern void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize);
|
||||
extern void vApplicationGetTimerTaskMemory (StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize);
|
||||
|
||||
/* Idle task control block and stack */
|
||||
static StaticTask_t Idle_TCB;
|
||||
static StackType_t Idle_Stack[configMINIMAL_STACK_SIZE];
|
||||
|
||||
/* Timer task control block and stack */
|
||||
static StaticTask_t Timer_TCB;
|
||||
static StackType_t Timer_Stack[configTIMER_TASK_STACK_DEPTH];
|
||||
|
||||
/*
|
||||
vApplicationGetIdleTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
|
||||
equals to 1 and is required for static memory allocation support.
|
||||
*/
|
||||
void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {
|
||||
__WEAK void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {
|
||||
/* Idle task control block and stack */
|
||||
static StaticTask_t Idle_TCB;
|
||||
static StackType_t Idle_Stack[configMINIMAL_STACK_SIZE];
|
||||
|
||||
*ppxIdleTaskTCBBuffer = &Idle_TCB;
|
||||
*ppxIdleTaskStackBuffer = &Idle_Stack[0];
|
||||
*pulIdleTaskStackSize = (uint32_t)configMINIMAL_STACK_SIZE;
|
||||
|
@ -1917,8 +2470,13 @@ void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackTy
|
|||
vApplicationGetTimerTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
|
||||
equals to 1 and is required for static memory allocation support.
|
||||
*/
|
||||
void vApplicationGetTimerTaskMemory (StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) {
|
||||
__WEAK void vApplicationGetTimerTaskMemory (StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) {
|
||||
/* Timer task control block and stack */
|
||||
static StaticTask_t Timer_TCB;
|
||||
static StackType_t Timer_Stack[configTIMER_TASK_STACK_DEPTH];
|
||||
|
||||
*ppxTimerTaskTCBBuffer = &Timer_TCB;
|
||||
*ppxTimerTaskStackBuffer = &Timer_Stack[0];
|
||||
*pulTimerTaskStackSize = (uint32_t)configTIMER_TASK_STACK_DEPTH;
|
||||
}
|
||||
#endif
|
||||
|
|
63
Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_mpool.h
vendored
Normal file
63
Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_mpool.h
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* --------------------------------------------------------------------------
|
||||
* Copyright (c) 2013-2020 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Name: freertos_mpool.h
|
||||
* Purpose: CMSIS RTOS2 wrapper for FreeRTOS
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef FREERTOS_MPOOL_H_
|
||||
#define FREERTOS_MPOOL_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* Memory Pool implementation definitions */
|
||||
#define MPOOL_STATUS 0x5EED0000U
|
||||
|
||||
/* Memory Block header */
|
||||
typedef struct {
|
||||
void *next; /* Pointer to next block */
|
||||
} MemPoolBlock_t;
|
||||
|
||||
/* Memory Pool control block */
|
||||
typedef struct MemPoolDef_t {
|
||||
MemPoolBlock_t *head; /* Pointer to head block */
|
||||
SemaphoreHandle_t sem; /* Pool semaphore handle */
|
||||
uint8_t *mem_arr; /* Pool memory array */
|
||||
uint32_t mem_sz; /* Pool memory array size */
|
||||
const char *name; /* Pointer to name string */
|
||||
uint32_t bl_sz; /* Size of a single block */
|
||||
uint32_t bl_cnt; /* Number of blocks */
|
||||
uint32_t n; /* Block allocation index */
|
||||
volatile uint32_t status; /* Object status flags */
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
StaticSemaphore_t mem_sem; /* Semaphore object memory */
|
||||
#endif
|
||||
} MemPool_t;
|
||||
|
||||
/* No need to hide static object type, just align to coding style */
|
||||
#define StaticMemPool_t MemPool_t
|
||||
|
||||
/* Define memory pool control block size */
|
||||
#define MEMPOOL_CB_SIZE (sizeof(StaticMemPool_t))
|
||||
|
||||
/* Define size of the byte array required to create count of blocks of given size */
|
||||
#define MEMPOOL_ARR_SIZE(bl_count, bl_size) (((((bl_size) + (4 - 1)) / 4) * 4)*(bl_count))
|
||||
|
||||
#endif /* FREERTOS_MPOOL_H_ */
|
310
Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_os2.h
vendored
Normal file
310
Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_os2.h
vendored
Normal file
|
@ -0,0 +1,310 @@
|
|||
/* --------------------------------------------------------------------------
|
||||
* Copyright (c) 2013-2020 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Name: freertos_os2.h
|
||||
* Purpose: CMSIS RTOS2 wrapper for FreeRTOS
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef FREERTOS_OS2_H_
|
||||
#define FREERTOS_OS2_H_
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "FreeRTOS.h" // ARM.FreeRTOS::RTOS:Core
|
||||
|
||||
#include CMSIS_device_header
|
||||
|
||||
/*
|
||||
CMSIS-RTOS2 FreeRTOS image size optimization definitions.
|
||||
|
||||
Note: Definitions configUSE_OS2 can be used to optimize FreeRTOS image size when
|
||||
certain functionality is not required when using CMSIS-RTOS2 API.
|
||||
In general optimization decisions are left to the tool chain but in cases
|
||||
when coding style prevents it to optimize the code following optional
|
||||
definitions can be used.
|
||||
*/
|
||||
|
||||
/*
|
||||
Option to exclude CMSIS-RTOS2 functions osThreadSuspend and osThreadResume from
|
||||
the application image.
|
||||
*/
|
||||
#ifndef configUSE_OS2_THREAD_SUSPEND_RESUME
|
||||
#define configUSE_OS2_THREAD_SUSPEND_RESUME 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
Option to exclude CMSIS-RTOS2 function osThreadEnumerate from the application image.
|
||||
*/
|
||||
#ifndef configUSE_OS2_THREAD_ENUMERATE
|
||||
#define configUSE_OS2_THREAD_ENUMERATE 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
Option to disable CMSIS-RTOS2 function osEventFlagsSet and osEventFlagsClear
|
||||
operation from ISR.
|
||||
*/
|
||||
#ifndef configUSE_OS2_EVENTFLAGS_FROM_ISR
|
||||
#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
Option to exclude CMSIS-RTOS2 Thread Flags API functions from the application image.
|
||||
*/
|
||||
#ifndef configUSE_OS2_THREAD_FLAGS
|
||||
#define configUSE_OS2_THREAD_FLAGS configUSE_TASK_NOTIFICATIONS
|
||||
#endif
|
||||
|
||||
/*
|
||||
Option to exclude CMSIS-RTOS2 Timer API functions from the application image.
|
||||
*/
|
||||
#ifndef configUSE_OS2_TIMER
|
||||
#define configUSE_OS2_TIMER configUSE_TIMERS
|
||||
#endif
|
||||
|
||||
/*
|
||||
Option to exclude CMSIS-RTOS2 Mutex API functions from the application image.
|
||||
*/
|
||||
#ifndef configUSE_OS2_MUTEX
|
||||
#define configUSE_OS2_MUTEX configUSE_MUTEXES
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
CMSIS-RTOS2 FreeRTOS configuration check (FreeRTOSConfig.h).
|
||||
|
||||
Note: CMSIS-RTOS API requires functions included by using following definitions.
|
||||
In case if certain API function is not used compiler will optimize it away.
|
||||
*/
|
||||
#if (INCLUDE_xSemaphoreGetMutexHolder == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 function osMutexGetOwner uses FreeRTOS function xSemaphoreGetMutexHolder. In case if
|
||||
osMutexGetOwner is not used in the application image, compiler will optimize it away.
|
||||
Set #define INCLUDE_xSemaphoreGetMutexHolder 1 to fix this error.
|
||||
*/
|
||||
#error "Definition INCLUDE_xSemaphoreGetMutexHolder must equal 1 to implement Mutex Management API."
|
||||
#endif
|
||||
#if (INCLUDE_vTaskDelay == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 function osDelay uses FreeRTOS function vTaskDelay. In case if
|
||||
osDelay is not used in the application image, compiler will optimize it away.
|
||||
Set #define INCLUDE_vTaskDelay 1 to fix this error.
|
||||
*/
|
||||
#error "Definition INCLUDE_vTaskDelay must equal 1 to implement Generic Wait Functions API."
|
||||
#endif
|
||||
#if (INCLUDE_vTaskDelayUntil == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 function osDelayUntil uses FreeRTOS function vTaskDelayUntil. In case if
|
||||
osDelayUntil is not used in the application image, compiler will optimize it away.
|
||||
Set #define INCLUDE_vTaskDelayUntil 1 to fix this error.
|
||||
*/
|
||||
#error "Definition INCLUDE_vTaskDelayUntil must equal 1 to implement Generic Wait Functions API."
|
||||
#endif
|
||||
#if (INCLUDE_vTaskDelete == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 function osThreadTerminate and osThreadExit uses FreeRTOS function
|
||||
vTaskDelete. In case if they are not used in the application image, compiler
|
||||
will optimize them away.
|
||||
Set #define INCLUDE_vTaskDelete 1 to fix this error.
|
||||
*/
|
||||
#error "Definition INCLUDE_vTaskDelete must equal 1 to implement Thread Management API."
|
||||
#endif
|
||||
#if (INCLUDE_xTaskGetCurrentTaskHandle == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 API uses FreeRTOS function xTaskGetCurrentTaskHandle to implement
|
||||
functions osThreadGetId, osThreadFlagsClear and osThreadFlagsGet. In case if these
|
||||
functions are not used in the application image, compiler will optimize them away.
|
||||
Set #define INCLUDE_xTaskGetCurrentTaskHandle 1 to fix this error.
|
||||
*/
|
||||
#error "Definition INCLUDE_xTaskGetCurrentTaskHandle must equal 1 to implement Thread Management API."
|
||||
#endif
|
||||
#if (INCLUDE_xTaskGetSchedulerState == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 API uses FreeRTOS function xTaskGetSchedulerState to implement Kernel
|
||||
tick handling and therefore it is vital that xTaskGetSchedulerState is included into
|
||||
the application image.
|
||||
Set #define INCLUDE_xTaskGetSchedulerState 1 to fix this error.
|
||||
*/
|
||||
#error "Definition INCLUDE_xTaskGetSchedulerState must equal 1 to implement Kernel Information and Control API."
|
||||
#endif
|
||||
#if (INCLUDE_uxTaskGetStackHighWaterMark == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 function osThreadGetStackSpace uses FreeRTOS function uxTaskGetStackHighWaterMark.
|
||||
In case if osThreadGetStackSpace is not used in the application image, compiler will
|
||||
optimize it away.
|
||||
Set #define INCLUDE_uxTaskGetStackHighWaterMark 1 to fix this error.
|
||||
*/
|
||||
#error "Definition INCLUDE_uxTaskGetStackHighWaterMark must equal 1 to implement Thread Management API."
|
||||
#endif
|
||||
#if (INCLUDE_uxTaskPriorityGet == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 function osThreadGetPriority uses FreeRTOS function uxTaskPriorityGet. In case if
|
||||
osThreadGetPriority is not used in the application image, compiler will optimize it away.
|
||||
Set #define INCLUDE_uxTaskPriorityGet 1 to fix this error.
|
||||
*/
|
||||
#error "Definition INCLUDE_uxTaskPriorityGet must equal 1 to implement Thread Management API."
|
||||
#endif
|
||||
#if (INCLUDE_vTaskPrioritySet == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 function osThreadSetPriority uses FreeRTOS function vTaskPrioritySet. In case if
|
||||
osThreadSetPriority is not used in the application image, compiler will optimize it away.
|
||||
Set #define INCLUDE_vTaskPrioritySet 1 to fix this error.
|
||||
*/
|
||||
#error "Definition INCLUDE_vTaskPrioritySet must equal 1 to implement Thread Management API."
|
||||
#endif
|
||||
#if (INCLUDE_eTaskGetState == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 API uses FreeRTOS function vTaskDelayUntil to implement functions osThreadGetState
|
||||
and osThreadTerminate. In case if these functions are not used in the application image,
|
||||
compiler will optimize them away.
|
||||
Set #define INCLUDE_eTaskGetState 1 to fix this error.
|
||||
*/
|
||||
#error "Definition INCLUDE_eTaskGetState must equal 1 to implement Thread Management API."
|
||||
#endif
|
||||
#if (INCLUDE_vTaskSuspend == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 API uses FreeRTOS functions vTaskSuspend and vTaskResume to implement
|
||||
functions osThreadSuspend and osThreadResume. In case if these functions are not
|
||||
used in the application image, compiler will optimize them away.
|
||||
Set #define INCLUDE_vTaskSuspend 1 to fix this error.
|
||||
|
||||
Alternatively, if the application does not use osThreadSuspend and
|
||||
osThreadResume they can be excluded from the image code by setting:
|
||||
#define configUSE_OS2_THREAD_SUSPEND_RESUME 0 (in FreeRTOSConfig.h)
|
||||
*/
|
||||
#if (configUSE_OS2_THREAD_SUSPEND_RESUME == 1)
|
||||
#error "Definition INCLUDE_vTaskSuspend must equal 1 to implement Kernel Information and Control API."
|
||||
#endif
|
||||
#endif
|
||||
#if (INCLUDE_xTimerPendFunctionCall == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 function osEventFlagsSet and osEventFlagsClear, when called from
|
||||
the ISR, call FreeRTOS functions xEventGroupSetBitsFromISR and
|
||||
xEventGroupClearBitsFromISR which are only enabled if timers are operational and
|
||||
xTimerPendFunctionCall in enabled.
|
||||
Set #define INCLUDE_xTimerPendFunctionCall 1 and #define configUSE_TIMERS 1
|
||||
to fix this error.
|
||||
|
||||
Alternatively, if the application does not use osEventFlagsSet and osEventFlagsClear
|
||||
from the ISR their operation from ISR can be restricted by setting:
|
||||
#define configUSE_OS2_EVENTFLAGS_FROM_ISR 0 (in FreeRTOSConfig.h)
|
||||
*/
|
||||
#if (configUSE_OS2_EVENTFLAGS_FROM_ISR == 1)
|
||||
#error "Definition INCLUDE_xTimerPendFunctionCall must equal 1 to implement Event Flags API."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (configUSE_TIMERS == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 Timer Management API functions use FreeRTOS timer functions to implement
|
||||
timer management. In case if these functions are not used in the application image,
|
||||
compiler will optimize them away.
|
||||
Set #define configUSE_TIMERS 1 to fix this error.
|
||||
|
||||
Alternatively, if the application does not use timer functions they can be
|
||||
excluded from the image code by setting:
|
||||
#define configUSE_OS2_TIMER 0 (in FreeRTOSConfig.h)
|
||||
*/
|
||||
#if (configUSE_OS2_TIMER == 1)
|
||||
#error "Definition configUSE_TIMERS must equal 1 to implement Timer Management API."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (configUSE_MUTEXES == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 Mutex Management API functions use FreeRTOS mutex functions to implement
|
||||
mutex management. In case if these functions are not used in the application image,
|
||||
compiler will optimize them away.
|
||||
Set #define configUSE_MUTEXES 1 to fix this error.
|
||||
|
||||
Alternatively, if the application does not use mutex functions they can be
|
||||
excluded from the image code by setting:
|
||||
#define configUSE_OS2_MUTEX 0 (in FreeRTOSConfig.h)
|
||||
*/
|
||||
#if (configUSE_OS2_MUTEX == 1)
|
||||
#error "Definition configUSE_MUTEXES must equal 1 to implement Mutex Management API."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (configUSE_COUNTING_SEMAPHORES == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 Memory Pool functions use FreeRTOS function xSemaphoreCreateCounting
|
||||
to implement memory pools. In case if these functions are not used in the application image,
|
||||
compiler will optimize them away.
|
||||
Set #define configUSE_COUNTING_SEMAPHORES 1 to fix this error.
|
||||
*/
|
||||
#error "Definition configUSE_COUNTING_SEMAPHORES must equal 1 to implement Memory Pool API."
|
||||
#endif
|
||||
#if (configUSE_TASK_NOTIFICATIONS == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 Thread Flags API functions use FreeRTOS Task Notification functions to implement
|
||||
thread flag management. In case if these functions are not used in the application image,
|
||||
compiler will optimize them away.
|
||||
Set #define configUSE_TASK_NOTIFICATIONS 1 to fix this error.
|
||||
|
||||
Alternatively, if the application does not use thread flags functions they can be
|
||||
excluded from the image code by setting:
|
||||
#define configUSE_OS2_THREAD_FLAGS 0 (in FreeRTOSConfig.h)
|
||||
*/
|
||||
#if (configUSE_OS2_THREAD_FLAGS == 1)
|
||||
#error "Definition configUSE_TASK_NOTIFICATIONS must equal 1 to implement Thread Flags API."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (configUSE_TRACE_FACILITY == 0)
|
||||
/*
|
||||
CMSIS-RTOS2 function osThreadEnumerate requires FreeRTOS function uxTaskGetSystemState
|
||||
which is only enabled if configUSE_TRACE_FACILITY == 1.
|
||||
Set #define configUSE_TRACE_FACILITY 1 to fix this error.
|
||||
|
||||
Alternatively, if the application does not use osThreadEnumerate it can be
|
||||
excluded from the image code by setting:
|
||||
#define configUSE_OS2_THREAD_ENUMERATE 0 (in FreeRTOSConfig.h)
|
||||
*/
|
||||
#if (configUSE_OS2_THREAD_ENUMERATE == 1)
|
||||
#error "Definition configUSE_TRACE_FACILITY must equal 1 to implement osThreadEnumerate."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (configUSE_16_BIT_TICKS == 1)
|
||||
/*
|
||||
CMSIS-RTOS2 wrapper for FreeRTOS relies on 32-bit tick timer which is also optimal on
|
||||
a 32-bit CPU architectures.
|
||||
Set #define configUSE_16_BIT_TICKS 0 to fix this error.
|
||||
*/
|
||||
#error "Definition configUSE_16_BIT_TICKS must be zero to implement CMSIS-RTOS2 API."
|
||||
#endif
|
||||
|
||||
#if (configMAX_PRIORITIES != 56)
|
||||
/*
|
||||
CMSIS-RTOS2 defines 56 different priorities (see osPriority_t) and portable CMSIS-RTOS2
|
||||
implementation should implement the same number of priorities.
|
||||
Set #define configMAX_PRIORITIES 56 to fix this error.
|
||||
*/
|
||||
#error "Definition configMAX_PRIORITIES must equal 56 to implement Thread Management API."
|
||||
#endif
|
||||
#if (configUSE_PORT_OPTIMISED_TASK_SELECTION != 0)
|
||||
/*
|
||||
CMSIS-RTOS2 requires handling of 56 different priorities (see osPriority_t) while FreeRTOS port
|
||||
optimised selection for Cortex core only handles 32 different priorities.
|
||||
Set #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 to fix this error.
|
||||
*/
|
||||
#error "Definition configUSE_PORT_OPTIMISED_TASK_SELECTION must be zero to implement Thread Management API."
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_OS2_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue