1 /* --------------------------------------------------------------------------
2 * Copyright (c) 2013-2019 Arm Limited. All rights reserved.
4 * SPDX-License-Identifier: Apache-2.0
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 * Purpose: CMSIS RTOS2 wrapper for FreeRTOS
21 *---------------------------------------------------------------------------*/
25 #include "RTE_Components.h" // Component selection
27 #include "cmsis_os2.h" // ::CMSIS:RTOS2
28 #include "cmsis_compiler.h"
31 #include "FreeRTOS.h" // ARM.FreeRTOS::RTOS:Core
32 #include "task.h" // ARM.FreeRTOS::RTOS:Core
33 #include "event_groups.h" // ARM.FreeRTOS::RTOS:Event Groups
34 #include "semphr.h" // ARM.FreeRTOS::RTOS:Core
36 /*---------------------------------------------------------------------------*/
37 #ifndef __ARM_ARCH_6M__
38 #define __ARM_ARCH_6M__ 0
40 #ifndef __ARM_ARCH_7M__
41 #define __ARM_ARCH_7M__ 0
43 #ifndef __ARM_ARCH_7EM__
44 #define __ARM_ARCH_7EM__ 0
46 #ifndef __ARM_ARCH_8M_MAIN__
47 #define __ARM_ARCH_8M_MAIN__ 0
49 #ifndef __ARM_ARCH_7A__
50 #define __ARM_ARCH_7A__ 0
53 #if ((__ARM_ARCH_7M__ == 1U) || \
54 (__ARM_ARCH_7EM__ == 1U) || \
55 (__ARM_ARCH_8M_MAIN__ == 1U))
56 #define IS_IRQ_MASKED() ((__get_PRIMASK() != 0U) || (__get_BASEPRI() != 0U))
57 #elif (__ARM_ARCH_6M__ == 1U)
58 #define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
59 #elif (__ARM_ARCH_7A__ == 1U)
61 #define CPSR_MASKBIT_I 0x80U
63 #define IS_IRQ_MASKED() ((__get_CPSR() & CPSR_MASKBIT_I) != 0U)
65 #define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
68 #if (__ARM_ARCH_7A__ == 1U)
69 /* CPSR mode bitmasks */
70 #define CPSR_MODE_USER 0x10U
71 #define CPSR_MODE_SYSTEM 0x1FU
73 #define IS_IRQ_MODE() ((__get_mode() != CPSR_MODE_USER) && (__get_mode() != CPSR_MODE_SYSTEM))
75 #define IS_IRQ_MODE() (__get_IPSR() != 0U)
78 #define IS_IRQ() (IS_IRQ_MODE() || (IS_IRQ_MASKED() && (KernelState == osKernelRunning)))
81 #define MAX_BITS_TASK_NOTIFY 31U
82 #define MAX_BITS_EVENT_GROUPS 24U
84 #define THREAD_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_TASK_NOTIFY) - 1U))
85 #define EVENT_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_EVENT_GROUPS) - 1U))
87 /* Kernel version and identification string definition (major.minor.rev: mmnnnrrrr dec) */
88 #define KERNEL_VERSION (((uint32_t)tskKERNEL_VERSION_MAJOR * 10000000UL) | \
89 ((uint32_t)tskKERNEL_VERSION_MINOR * 10000UL) | \
90 ((uint32_t)tskKERNEL_VERSION_BUILD * 1UL))
92 #define KERNEL_ID ("FreeRTOS " tskKERNEL_VERSION_NUMBER)
94 /* Timer callback information structure definition */
100 /* Kernel initialization state */
101 static osKernelState_t KernelState = osKernelInactive;
104 Heap region definition used by heap_5 variant
106 Define configAPPLICATION_ALLOCATED_HEAP as nonzero value in FreeRTOSConfig.h if
107 heap regions are already defined and vPortDefineHeapRegions is called in application.
109 Otherwise vPortDefineHeapRegions will be called by osKernelInitialize using
110 definition configHEAP_5_REGIONS as parameter. Overriding configHEAP_5_REGIONS
111 is possible by defining it globally or in FreeRTOSConfig.h.
113 #if defined(RTE_RTOS_FreeRTOS_HEAP_5)
114 #if (configAPPLICATION_ALLOCATED_HEAP == 0)
116 FreeRTOS heap is not defined by the application.
117 Single region of size configTOTAL_HEAP_SIZE (defined in FreeRTOSConfig.h)
118 is provided by default. Define configHEAP_5_REGIONS to provide custom
121 #define HEAP_5_REGION_SETUP 1
123 #ifndef configHEAP_5_REGIONS
124 #define configHEAP_5_REGIONS xHeapRegions
126 static uint8_t ucHeap[configTOTAL_HEAP_SIZE];
128 static HeapRegion_t xHeapRegions[] = {
129 { ucHeap, configTOTAL_HEAP_SIZE },
133 /* Global definition is provided to override default heap array */
134 extern HeapRegion_t configHEAP_5_REGIONS[];
138 The application already defined the array used for the FreeRTOS heap and
139 called vPortDefineHeapRegions to initialize heap.
141 #define HEAP_5_REGION_SETUP 0
142 #endif /* configAPPLICATION_ALLOCATED_HEAP */
143 #endif /* RTE_RTOS_FreeRTOS_HEAP_5 */
146 #undef SysTick_Handler
148 /* CMSIS SysTick interrupt handler prototype */
149 extern void SysTick_Handler (void);
150 /* FreeRTOS tick timer interrupt handler prototype */
151 extern void xPortSysTickHandler (void);
154 SysTick handler implementation that also clears overflow flag.
156 void SysTick_Handler (void) {
157 /* Clear overflow flag */
160 if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
161 /* Call tick handler */
162 xPortSysTickHandler();
168 Setup SVC to reset value.
170 __STATIC_INLINE void SVC_Setup (void) {
171 #if (__ARM_ARCH_7A__ == 0U)
172 /* Service Call interrupt might be configured before kernel start */
173 /* and when its priority is lower or equal to BASEPRI, svc intruction */
174 /* causes a Hard Fault. */
175 NVIC_SetPriority (SVCall_IRQn, 0U);
179 /*---------------------------------------------------------------------------*/
181 osStatus_t osKernelInitialize (void) {
188 if (KernelState == osKernelInactive) {
189 #if defined(RTE_Compiler_EventRecorder)
190 EvrFreeRTOSSetup(0U);
192 #if defined(RTE_RTOS_FreeRTOS_HEAP_5) && (HEAP_5_REGION_SETUP == 1)
193 vPortDefineHeapRegions (configHEAP_5_REGIONS);
195 KernelState = osKernelReady;
205 osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) {
207 if (version != NULL) {
208 /* Version encoding is major.minor.rev: mmnnnrrrr dec */
209 version->api = KERNEL_VERSION;
210 version->kernel = KERNEL_VERSION;
213 if ((id_buf != NULL) && (id_size != 0U)) {
214 if (id_size > sizeof(KERNEL_ID)) {
215 id_size = sizeof(KERNEL_ID);
217 memcpy(id_buf, KERNEL_ID, id_size);
223 osKernelState_t osKernelGetState (void) {
224 osKernelState_t state;
226 switch (xTaskGetSchedulerState()) {
227 case taskSCHEDULER_RUNNING:
228 state = osKernelRunning;
231 case taskSCHEDULER_SUSPENDED:
232 state = osKernelLocked;
235 case taskSCHEDULER_NOT_STARTED:
237 if (KernelState == osKernelReady) {
238 state = osKernelReady;
240 state = osKernelInactive;
248 osStatus_t osKernelStart (void) {
255 if (KernelState == osKernelReady) {
256 /* Ensure SVC priority is at the reset value */
258 /* Change state to enable IRQ masking check */
259 KernelState = osKernelRunning;
260 /* Start the kernel scheduler */
261 vTaskStartScheduler();
271 int32_t osKernelLock (void) {
275 lock = (int32_t)osErrorISR;
278 switch (xTaskGetSchedulerState()) {
279 case taskSCHEDULER_SUSPENDED:
283 case taskSCHEDULER_RUNNING:
288 case taskSCHEDULER_NOT_STARTED:
290 lock = (int32_t)osError;
298 int32_t osKernelUnlock (void) {
302 lock = (int32_t)osErrorISR;
305 switch (xTaskGetSchedulerState()) {
306 case taskSCHEDULER_SUSPENDED:
309 if (xTaskResumeAll() != pdTRUE) {
310 if (xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED) {
311 lock = (int32_t)osError;
316 case taskSCHEDULER_RUNNING:
320 case taskSCHEDULER_NOT_STARTED:
322 lock = (int32_t)osError;
330 int32_t osKernelRestoreLock (int32_t lock) {
333 lock = (int32_t)osErrorISR;
336 switch (xTaskGetSchedulerState()) {
337 case taskSCHEDULER_SUSPENDED:
338 case taskSCHEDULER_RUNNING:
344 lock = (int32_t)osError;
347 if (xTaskResumeAll() != pdTRUE) {
348 if (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) {
349 lock = (int32_t)osError;
356 case taskSCHEDULER_NOT_STARTED:
358 lock = (int32_t)osError;
366 uint32_t osKernelGetTickCount (void) {
370 ticks = xTaskGetTickCountFromISR();
372 ticks = xTaskGetTickCount();
378 uint32_t osKernelGetTickFreq (void) {
379 return (configTICK_RATE_HZ);
382 uint32_t osKernelGetSysTimerCount (void) {
383 uint32_t irqmask = IS_IRQ_MASKED();
389 ticks = xTaskGetTickCount();
390 val = OS_Tick_GetCount();
392 if (OS_Tick_GetOverflow() != 0U) {
393 val = OS_Tick_GetCount();
396 val += ticks * OS_Tick_GetInterval();
405 uint32_t osKernelGetSysTimerFreq (void) {
406 return (configCPU_CLOCK_HZ);
409 /*---------------------------------------------------------------------------*/
411 osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) {
420 if (!IS_IRQ() && (func != NULL)) {
421 stack = configMINIMAL_STACK_SIZE;
422 prio = (UBaseType_t)osPriorityNormal;
428 if (attr->name != NULL) {
431 if (attr->priority != osPriorityNone) {
432 prio = (UBaseType_t)attr->priority;
435 if ((prio < osPriorityIdle) || (prio > osPriorityISR) || ((attr->attr_bits & osThreadJoinable) == osThreadJoinable)) {
439 if (attr->stack_size > 0U) {
440 /* In FreeRTOS stack is not in bytes, but in sizeof(StackType_t) which is 4 on ARM ports. */
441 /* Stack size should be therefore 4 byte aligned in order to avoid division caused side effects */
442 stack = attr->stack_size / sizeof(StackType_t);
445 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTask_t)) &&
446 (attr->stack_mem != NULL) && (attr->stack_size > 0U)) {
450 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) && (attr->stack_mem == NULL)) {
460 hTask = xTaskCreateStatic ((TaskFunction_t)func, name, stack, argument, prio, (StackType_t *)attr->stack_mem,
461 (StaticTask_t *)attr->cb_mem);
465 if (xTaskCreate ((TaskFunction_t)func, name, (uint16_t)stack, argument, prio, &hTask) != pdPASS) {
472 return ((osThreadId_t)hTask);
475 const char *osThreadGetName (osThreadId_t thread_id) {
476 TaskHandle_t hTask = (TaskHandle_t)thread_id;
479 if (IS_IRQ() || (hTask == NULL)) {
482 name = pcTaskGetName (hTask);
488 osThreadId_t osThreadGetId (void) {
491 id = (osThreadId_t)xTaskGetCurrentTaskHandle();
496 osThreadState_t osThreadGetState (osThreadId_t thread_id) {
497 TaskHandle_t hTask = (TaskHandle_t)thread_id;
498 osThreadState_t state;
500 if (IS_IRQ() || (hTask == NULL)) {
501 state = osThreadError;
504 switch (eTaskGetState (hTask)) {
505 case eRunning: state = osThreadRunning; break;
506 case eReady: state = osThreadReady; break;
508 case eSuspended: state = osThreadBlocked; break;
509 case eDeleted: state = osThreadTerminated; break;
511 default: state = osThreadError; break;
518 uint32_t osThreadGetStackSpace (osThreadId_t thread_id) {
519 TaskHandle_t hTask = (TaskHandle_t)thread_id;
522 if (IS_IRQ() || (hTask == NULL)) {
525 sz = (uint32_t)(uxTaskGetStackHighWaterMark(hTask) * sizeof(StackType_t));
531 osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) {
532 TaskHandle_t hTask = (TaskHandle_t)thread_id;
538 else if ((hTask == NULL) || (priority < osPriorityIdle) || (priority > osPriorityISR)) {
539 stat = osErrorParameter;
543 vTaskPrioritySet (hTask, (UBaseType_t)priority);
549 osPriority_t osThreadGetPriority (osThreadId_t thread_id) {
550 TaskHandle_t hTask = (TaskHandle_t)thread_id;
553 if (IS_IRQ() || (hTask == NULL)) {
554 prio = osPriorityError;
556 prio = (osPriority_t)uxTaskPriorityGet (hTask);
562 osStatus_t osThreadYield (void) {
575 osStatus_t osThreadSuspend (osThreadId_t thread_id) {
576 TaskHandle_t hTask = (TaskHandle_t)thread_id;
582 else if (hTask == NULL) {
583 stat = osErrorParameter;
587 vTaskSuspend (hTask);
593 osStatus_t osThreadResume (osThreadId_t thread_id) {
594 TaskHandle_t hTask = (TaskHandle_t)thread_id;
600 else if (hTask == NULL) {
601 stat = osErrorParameter;
611 __NO_RETURN void osThreadExit (void) {
612 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
618 osStatus_t osThreadTerminate (osThreadId_t thread_id) {
619 TaskHandle_t hTask = (TaskHandle_t)thread_id;
621 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
627 else if (hTask == NULL) {
628 stat = osErrorParameter;
631 tstate = eTaskGetState (hTask);
633 if (tstate != eDeleted) {
637 stat = osErrorResource;
647 uint32_t osThreadGetCount (void) {
653 count = uxTaskGetNumberOfTasks();
659 uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) {
663 if (IS_IRQ() || (thread_array == NULL) || (array_items == 0U)) {
668 count = uxTaskGetNumberOfTasks();
669 task = pvPortMalloc (count * sizeof(TaskStatus_t));
672 count = uxTaskGetSystemState (task, count, NULL);
674 for (i = 0U; (i < count) && (i < array_items); i++) {
675 thread_array[i] = (osThreadId_t)task[i].xHandle;
679 (void)xTaskResumeAll();
687 uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) {
688 TaskHandle_t hTask = (TaskHandle_t)thread_id;
692 if ((hTask == NULL) || ((flags & THREAD_FLAGS_INVALID_BITS) != 0U)) {
693 rflags = (uint32_t)osErrorParameter;
696 rflags = (uint32_t)osError;
701 (void)xTaskNotifyFromISR (hTask, flags, eSetBits, &yield);
702 (void)xTaskNotifyAndQueryFromISR (hTask, 0, eNoAction, &rflags, NULL);
704 portYIELD_FROM_ISR (yield);
707 (void)xTaskNotify (hTask, flags, eSetBits);
708 (void)xTaskNotifyAndQuery (hTask, 0, eNoAction, &rflags);
711 /* Return flags after setting */
715 uint32_t osThreadFlagsClear (uint32_t flags) {
717 uint32_t rflags, cflags;
720 rflags = (uint32_t)osErrorISR;
722 else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) {
723 rflags = (uint32_t)osErrorParameter;
726 hTask = xTaskGetCurrentTaskHandle();
728 if (xTaskNotifyAndQuery (hTask, 0, eNoAction, &cflags) == pdPASS) {
732 if (xTaskNotify (hTask, cflags, eSetValueWithOverwrite) != pdPASS) {
733 rflags = (uint32_t)osError;
737 rflags = (uint32_t)osError;
741 /* Return flags before clearing */
745 uint32_t osThreadFlagsGet (void) {
750 rflags = (uint32_t)osErrorISR;
753 hTask = xTaskGetCurrentTaskHandle();
755 if (xTaskNotifyAndQuery (hTask, 0, eNoAction, &rflags) != pdPASS) {
756 rflags = (uint32_t)osError;
763 uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) {
764 uint32_t rflags, nval;
766 TickType_t t0, td, tout;
770 rflags = (uint32_t)osErrorISR;
772 else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) {
773 rflags = (uint32_t)osErrorParameter;
776 if ((options & osFlagsNoClear) == osFlagsNoClear) {
785 t0 = xTaskGetTickCount();
787 rval = xTaskNotifyWait (0, clear, &nval, tout);
789 if (rval == pdPASS) {
793 if ((options & osFlagsWaitAll) == osFlagsWaitAll) {
794 if ((flags & rflags) == flags) {
798 rflags = (uint32_t)osErrorResource;
804 if ((flags & rflags) != 0) {
808 rflags = (uint32_t)osErrorResource;
815 td = xTaskGetTickCount() - t0;
825 rflags = (uint32_t)osErrorResource;
827 rflags = (uint32_t)osErrorTimeout;
831 while (rval != pdFAIL);
834 /* Return flags before clearing */
838 osStatus_t osDelay (uint32_t ticks) {
855 osStatus_t osDelayUntil (uint32_t ticks) {
856 TickType_t tcnt, delay;
864 tcnt = xTaskGetTickCount();
866 /* Determine remaining number of ticks to delay */
867 delay = (TickType_t)ticks - tcnt;
869 /* Check if target tick has not expired */
870 if((delay != 0U) && (0 == (delay >> (8 * sizeof(TickType_t) - 1)))) {
871 vTaskDelayUntil (&tcnt, delay);
875 /* No delay or already expired */
876 stat = osErrorParameter;
883 /*---------------------------------------------------------------------------*/
885 static void TimerCallback (TimerHandle_t hTimer) {
886 TimerCallback_t *callb;
888 callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer);
891 callb->func (callb->arg);
895 osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) {
897 TimerHandle_t hTimer;
898 TimerCallback_t *callb;
904 if (!IS_IRQ() && (func != NULL)) {
905 /* Allocate memory to store callback function and argument */
906 callb = pvPortMalloc (sizeof(TimerCallback_t));
910 callb->arg = argument;
912 if (type == osTimerOnce) {
922 if (attr->name != NULL) {
926 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTimer_t))) {
930 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
940 hTimer = xTimerCreateStatic (name, 1, reload, callb, TimerCallback, (StaticTimer_t *)attr->cb_mem);
944 hTimer = xTimerCreate (name, 1, reload, callb, TimerCallback);
950 return ((osTimerId_t)hTimer);
953 const char *osTimerGetName (osTimerId_t timer_id) {
954 TimerHandle_t hTimer = (TimerHandle_t)timer_id;
957 if (IS_IRQ() || (hTimer == NULL)) {
960 p = pcTimerGetName (hTimer);
966 osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks) {
967 TimerHandle_t hTimer = (TimerHandle_t)timer_id;
973 else if (hTimer == NULL) {
974 stat = osErrorParameter;
977 if (xTimerChangePeriod (hTimer, ticks, 0) == pdPASS) {
980 stat = osErrorResource;
987 osStatus_t osTimerStop (osTimerId_t timer_id) {
988 TimerHandle_t hTimer = (TimerHandle_t)timer_id;
994 else if (hTimer == NULL) {
995 stat = osErrorParameter;
998 if (xTimerIsTimerActive (hTimer) == pdFALSE) {
999 stat = osErrorResource;
1002 if (xTimerStop (hTimer, 0) == pdPASS) {
1013 uint32_t osTimerIsRunning (osTimerId_t timer_id) {
1014 TimerHandle_t hTimer = (TimerHandle_t)timer_id;
1017 if (IS_IRQ() || (hTimer == NULL)) {
1020 running = (uint32_t)xTimerIsTimerActive (hTimer);
1026 osStatus_t osTimerDelete (osTimerId_t timer_id) {
1027 TimerHandle_t hTimer = (TimerHandle_t)timer_id;
1029 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1030 TimerCallback_t *callb;
1035 else if (hTimer == NULL) {
1036 stat = osErrorParameter;
1039 callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer);
1041 if (xTimerDelete (hTimer, 0) == pdPASS) {
1045 stat = osErrorResource;
1055 /*---------------------------------------------------------------------------*/
1057 osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr) {
1058 EventGroupHandle_t hEventGroup;
1067 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticEventGroup_t))) {
1071 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1081 hEventGroup = xEventGroupCreateStatic (attr->cb_mem);
1085 hEventGroup = xEventGroupCreate();
1090 return ((osEventFlagsId_t)hEventGroup);
1093 uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) {
1094 EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1098 if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1099 rflags = (uint32_t)osErrorParameter;
1101 else if (IS_IRQ()) {
1104 if (xEventGroupSetBitsFromISR (hEventGroup, (EventBits_t)flags, &yield) == pdFAIL) {
1105 rflags = (uint32_t)osErrorResource;
1108 portYIELD_FROM_ISR (yield);
1112 rflags = xEventGroupSetBits (hEventGroup, (EventBits_t)flags);
1118 uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) {
1119 EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1122 if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1123 rflags = (uint32_t)osErrorParameter;
1125 else if (IS_IRQ()) {
1126 rflags = xEventGroupGetBitsFromISR (hEventGroup);
1128 if (xEventGroupClearBitsFromISR (hEventGroup, (EventBits_t)flags) == pdFAIL) {
1129 rflags = (uint32_t)osErrorResource;
1133 rflags = xEventGroupClearBits (hEventGroup, (EventBits_t)flags);
1139 uint32_t osEventFlagsGet (osEventFlagsId_t ef_id) {
1140 EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1143 if (ef_id == NULL) {
1146 else if (IS_IRQ()) {
1147 rflags = xEventGroupGetBitsFromISR (hEventGroup);
1150 rflags = xEventGroupGetBits (hEventGroup);
1156 uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) {
1157 EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1158 BaseType_t wait_all;
1159 BaseType_t exit_clr;
1162 if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1163 rflags = (uint32_t)osErrorParameter;
1165 else if (IS_IRQ()) {
1166 rflags = (uint32_t)osErrorISR;
1169 if (options & osFlagsWaitAll) {
1175 if (options & osFlagsNoClear) {
1181 rflags = xEventGroupWaitBits (hEventGroup, (EventBits_t)flags, exit_clr, wait_all, (TickType_t)timeout);
1183 if (options & osFlagsWaitAll) {
1184 if ((flags & rflags) != flags) {
1186 rflags = (uint32_t)osErrorTimeout;
1188 rflags = (uint32_t)osErrorResource;
1193 if ((flags & rflags) == 0U) {
1195 rflags = (uint32_t)osErrorTimeout;
1197 rflags = (uint32_t)osErrorResource;
1206 osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id) {
1207 EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1210 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1214 else if (hEventGroup == NULL) {
1215 stat = osErrorParameter;
1219 vEventGroupDelete (hEventGroup);
1228 /*---------------------------------------------------------------------------*/
1230 osMutexId_t osMutexNew (const osMutexAttr_t *attr) {
1231 SemaphoreHandle_t hMutex;
1235 #if (configQUEUE_REGISTRY_SIZE > 0)
1243 type = attr->attr_bits;
1248 if ((type & osMutexRecursive) == osMutexRecursive) {
1254 if ((type & osMutexRobust) != osMutexRobust) {
1258 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
1262 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1273 hMutex = xSemaphoreCreateRecursiveMutexStatic (attr->cb_mem);
1276 hMutex = xSemaphoreCreateMutexStatic (attr->cb_mem);
1282 hMutex = xSemaphoreCreateRecursiveMutex ();
1284 hMutex = xSemaphoreCreateMutex ();
1289 #if (configQUEUE_REGISTRY_SIZE > 0)
1290 if (hMutex != NULL) {
1296 vQueueAddToRegistry (hMutex, name);
1300 if ((hMutex != NULL) && (rmtx != 0U)) {
1301 hMutex = (SemaphoreHandle_t)((uint32_t)hMutex | 1U);
1306 return ((osMutexId_t)hMutex);
1309 osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
1310 SemaphoreHandle_t hMutex;
1314 hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1316 rmtx = (uint32_t)mutex_id & 1U;
1323 else if (hMutex == NULL) {
1324 stat = osErrorParameter;
1328 if (xSemaphoreTakeRecursive (hMutex, timeout) != pdPASS) {
1329 if (timeout != 0U) {
1330 stat = osErrorTimeout;
1332 stat = osErrorResource;
1337 if (xSemaphoreTake (hMutex, timeout) != pdPASS) {
1338 if (timeout != 0U) {
1339 stat = osErrorTimeout;
1341 stat = osErrorResource;
1350 osStatus_t osMutexRelease (osMutexId_t mutex_id) {
1351 SemaphoreHandle_t hMutex;
1355 hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1357 rmtx = (uint32_t)mutex_id & 1U;
1364 else if (hMutex == NULL) {
1365 stat = osErrorParameter;
1369 if (xSemaphoreGiveRecursive (hMutex) != pdPASS) {
1370 stat = osErrorResource;
1374 if (xSemaphoreGive (hMutex) != pdPASS) {
1375 stat = osErrorResource;
1383 osThreadId_t osMutexGetOwner (osMutexId_t mutex_id) {
1384 SemaphoreHandle_t hMutex;
1387 hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1389 if (IS_IRQ() || (hMutex == NULL)) {
1392 owner = (osThreadId_t)xSemaphoreGetMutexHolder (hMutex);
1398 osStatus_t osMutexDelete (osMutexId_t mutex_id) {
1400 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1401 SemaphoreHandle_t hMutex;
1403 hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1408 else if (hMutex == NULL) {
1409 stat = osErrorParameter;
1412 #if (configQUEUE_REGISTRY_SIZE > 0)
1413 vQueueUnregisterQueue (hMutex);
1416 vSemaphoreDelete (hMutex);
1425 /*---------------------------------------------------------------------------*/
1427 osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) {
1428 SemaphoreHandle_t hSemaphore;
1430 #if (configQUEUE_REGISTRY_SIZE > 0)
1436 if (!IS_IRQ() && (max_count > 0U) && (initial_count <= max_count)) {
1440 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
1444 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1454 if (max_count == 1U) {
1456 hSemaphore = xSemaphoreCreateBinaryStatic ((StaticSemaphore_t *)attr->cb_mem);
1459 hSemaphore = xSemaphoreCreateBinary();
1462 if ((hSemaphore != NULL) && (initial_count != 0U)) {
1463 if (xSemaphoreGive (hSemaphore) != pdPASS) {
1464 vSemaphoreDelete (hSemaphore);
1471 hSemaphore = xSemaphoreCreateCountingStatic (max_count, initial_count, (StaticSemaphore_t *)attr->cb_mem);
1474 hSemaphore = xSemaphoreCreateCounting (max_count, initial_count);
1478 #if (configQUEUE_REGISTRY_SIZE > 0)
1479 if (hSemaphore != NULL) {
1485 vQueueAddToRegistry (hSemaphore, name);
1491 return ((osSemaphoreId_t)hSemaphore);
1494 osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) {
1495 SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
1501 if (hSemaphore == NULL) {
1502 stat = osErrorParameter;
1504 else if (IS_IRQ()) {
1505 if (timeout != 0U) {
1506 stat = osErrorParameter;
1511 if (xSemaphoreTakeFromISR (hSemaphore, &yield) != pdPASS) {
1512 stat = osErrorResource;
1514 portYIELD_FROM_ISR (yield);
1519 if (xSemaphoreTake (hSemaphore, (TickType_t)timeout) != pdPASS) {
1520 if (timeout != 0U) {
1521 stat = osErrorTimeout;
1523 stat = osErrorResource;
1531 osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id) {
1532 SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
1538 if (hSemaphore == NULL) {
1539 stat = osErrorParameter;
1541 else if (IS_IRQ()) {
1544 if (xSemaphoreGiveFromISR (hSemaphore, &yield) != pdTRUE) {
1545 stat = osErrorResource;
1547 portYIELD_FROM_ISR (yield);
1551 if (xSemaphoreGive (hSemaphore) != pdPASS) {
1552 stat = osErrorResource;
1559 uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id) {
1560 SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
1563 if (hSemaphore == NULL) {
1566 else if (IS_IRQ()) {
1567 count = uxQueueMessagesWaitingFromISR (hSemaphore);
1569 count = (uint32_t)uxSemaphoreGetCount (hSemaphore);
1575 osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id) {
1576 SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
1579 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1583 else if (hSemaphore == NULL) {
1584 stat = osErrorParameter;
1587 #if (configQUEUE_REGISTRY_SIZE > 0)
1588 vQueueUnregisterQueue (hSemaphore);
1592 vSemaphoreDelete (hSemaphore);
1601 /*---------------------------------------------------------------------------*/
1603 osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) {
1604 QueueHandle_t hQueue;
1606 #if (configQUEUE_REGISTRY_SIZE > 0)
1612 if (!IS_IRQ() && (msg_count > 0U) && (msg_size > 0U)) {
1616 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticQueue_t)) &&
1617 (attr->mq_mem != NULL) && (attr->mq_size >= (msg_count * msg_size))) {
1621 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) &&
1622 (attr->mq_mem == NULL) && (attr->mq_size == 0U)) {
1632 hQueue = xQueueCreateStatic (msg_count, msg_size, attr->mq_mem, attr->cb_mem);
1636 hQueue = xQueueCreate (msg_count, msg_size);
1640 #if (configQUEUE_REGISTRY_SIZE > 0)
1641 if (hQueue != NULL) {
1647 vQueueAddToRegistry (hQueue, name);
1653 return ((osMessageQueueId_t)hQueue);
1656 osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) {
1657 QueueHandle_t hQueue = (QueueHandle_t)mq_id;
1661 (void)msg_prio; /* Message priority is ignored */
1666 if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
1667 stat = osErrorParameter;
1672 if (xQueueSendToBackFromISR (hQueue, msg_ptr, &yield) != pdTRUE) {
1673 stat = osErrorResource;
1675 portYIELD_FROM_ISR (yield);
1680 if ((hQueue == NULL) || (msg_ptr == NULL)) {
1681 stat = osErrorParameter;
1684 if (xQueueSendToBack (hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) {
1685 if (timeout != 0U) {
1686 stat = osErrorTimeout;
1688 stat = osErrorResource;
1697 osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) {
1698 QueueHandle_t hQueue = (QueueHandle_t)mq_id;
1702 (void)msg_prio; /* Message priority is ignored */
1707 if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
1708 stat = osErrorParameter;
1713 if (xQueueReceiveFromISR (hQueue, msg_ptr, &yield) != pdPASS) {
1714 stat = osErrorResource;
1716 portYIELD_FROM_ISR (yield);
1721 if ((hQueue == NULL) || (msg_ptr == NULL)) {
1722 stat = osErrorParameter;
1725 if (xQueueReceive (hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) {
1726 if (timeout != 0U) {
1727 stat = osErrorTimeout;
1729 stat = osErrorResource;
1738 uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id) {
1739 StaticQueue_t *mq = (StaticQueue_t *)mq_id;
1745 /* capacity = pxQueue->uxLength */
1746 capacity = mq->uxDummy4[1];
1752 uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id) {
1753 StaticQueue_t *mq = (StaticQueue_t *)mq_id;
1759 /* size = pxQueue->uxItemSize */
1760 size = mq->uxDummy4[2];
1766 uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) {
1767 QueueHandle_t hQueue = (QueueHandle_t)mq_id;
1770 if (hQueue == NULL) {
1773 else if (IS_IRQ()) {
1774 count = uxQueueMessagesWaitingFromISR (hQueue);
1777 count = uxQueueMessagesWaiting (hQueue);
1780 return ((uint32_t)count);
1783 uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) {
1784 StaticQueue_t *mq = (StaticQueue_t *)mq_id;
1791 else if (IS_IRQ()) {
1792 isrm = taskENTER_CRITICAL_FROM_ISR();
1794 /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */
1795 space = mq->uxDummy4[1] - mq->uxDummy4[0];
1797 taskEXIT_CRITICAL_FROM_ISR(isrm);
1800 space = (uint32_t)uxQueueSpacesAvailable ((QueueHandle_t)mq);
1806 osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id) {
1807 QueueHandle_t hQueue = (QueueHandle_t)mq_id;
1813 else if (hQueue == NULL) {
1814 stat = osErrorParameter;
1818 (void)xQueueReset (hQueue);
1824 osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) {
1825 QueueHandle_t hQueue = (QueueHandle_t)mq_id;
1828 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1832 else if (hQueue == NULL) {
1833 stat = osErrorParameter;
1836 #if (configQUEUE_REGISTRY_SIZE > 0)
1837 vQueueUnregisterQueue (hQueue);
1841 vQueueDelete (hQueue);
1850 /*---------------------------------------------------------------------------*/
1852 /* Callback function prototypes */
1853 extern void vApplicationIdleHook (void);
1854 extern void vApplicationTickHook (void);
1855 extern void vApplicationMallocFailedHook (void);
1856 extern void vApplicationDaemonTaskStartupHook (void);
1857 extern void vApplicationStackOverflowHook (TaskHandle_t xTask, signed char *pcTaskName);
1860 Dummy implementation of the callback function vApplicationIdleHook().
1862 #if (configUSE_IDLE_HOOK == 1)
1863 __WEAK void vApplicationIdleHook (void){}
1867 Dummy implementation of the callback function vApplicationTickHook().
1869 #if (configUSE_TICK_HOOK == 1)
1870 __WEAK void vApplicationTickHook (void){}
1874 Dummy implementation of the callback function vApplicationMallocFailedHook().
1876 #if (configUSE_MALLOC_FAILED_HOOK == 1)
1877 __WEAK void vApplicationMallocFailedHook (void){}
1881 Dummy implementation of the callback function vApplicationDaemonTaskStartupHook().
1883 #if (configUSE_DAEMON_TASK_STARTUP_HOOK == 1)
1884 __WEAK void vApplicationDaemonTaskStartupHook (void){}
1888 Dummy implementation of the callback function vApplicationStackOverflowHook().
1890 #if (configCHECK_FOR_STACK_OVERFLOW > 0)
1891 __WEAK void vApplicationStackOverflowHook (TaskHandle_t xTask, signed char *pcTaskName) {
1897 /*---------------------------------------------------------------------------*/
1899 /* External Idle and Timer task static memory allocation functions */
1900 extern void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize);
1901 extern void vApplicationGetTimerTaskMemory (StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize);
1903 /* Idle task control block and stack */
1904 static StaticTask_t Idle_TCB;
1905 static StackType_t Idle_Stack[configMINIMAL_STACK_SIZE];
1907 /* Timer task control block and stack */
1908 static StaticTask_t Timer_TCB;
1909 static StackType_t Timer_Stack[configTIMER_TASK_STACK_DEPTH];
1912 vApplicationGetIdleTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
1913 equals to 1 and is required for static memory allocation support.
1915 void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {
1916 *ppxIdleTaskTCBBuffer = &Idle_TCB;
1917 *ppxIdleTaskStackBuffer = &Idle_Stack[0];
1918 *pulIdleTaskStackSize = (uint32_t)configMINIMAL_STACK_SIZE;
1922 vApplicationGetTimerTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
1923 equals to 1 and is required for static memory allocation support.
1925 void vApplicationGetTimerTaskMemory (StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) {
1926 *ppxTimerTaskTCBBuffer = &Timer_TCB;
1927 *ppxTimerTaskStackBuffer = &Timer_Stack[0];
1928 *pulTimerTaskStackSize = (uint32_t)configTIMER_TASK_STACK_DEPTH;