1 /* --------------------------------------------------------------------------
2 * Copyright (c) 2013-2017 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
26 #include CMSIS_device_header
28 #include "cmsis_os2.h" // ::CMSIS:RTOS2
29 #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 /*---------------------------------------------------------------------------*/
38 #if ((__ARM_ARCH_7M__ == 1U) || \
39 (__ARM_ARCH_7EM__ == 1U) || \
40 (__ARM_ARCH_8M_MAIN__ == 1U))
41 #define IS_IRQ_MASKED() ((__get_PRIMASK() != 0U) || ((KernelState == osKernelRunning) && (__get_BASEPRI() != 0U)))
43 #define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
46 #if (__ARM_ARCH_7A__ == 1U)
47 #define IS_IRQ() (__get_mode() == 0x12U)
49 #define IS_IRQ_MODE() (__get_IPSR() != 0U)
50 #define IS_IRQ() (IS_IRQ_MODE() || IS_IRQ_MASKED())
54 #define MAX_BITS_TASK_NOTIFY 31U
55 #define MAX_BITS_EVENT_GROUPS 24U
57 #define THREAD_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_TASK_NOTIFY) - 1U))
58 #define EVENT_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_EVENT_GROUPS) - 1U))
60 /* Kernel version and identification string definition */
61 #define KERNEL_VERSION (((uint32_t)tskKERNEL_VERSION_MAJOR * 10000000UL) | \
62 ((uint32_t)tskKERNEL_VERSION_MINOR * 10000UL) | \
63 ((uint32_t)tskKERNEL_VERSION_BUILD * 1UL))
65 #define KERNEL_ID "FreeRTOS V9.0.0"
67 /* Timer callback information structure definition */
73 /* Kernel initialization state */
74 static osKernelState_t KernelState;
76 /* Heap region definition used by heap_5 variant */
77 #if defined(RTE_RTOS_FreeRTOS_HEAP_5)
78 #if (configAPPLICATION_ALLOCATED_HEAP == 1)
80 The application writer has already defined the array used for the RTOS
81 heap - probably so it can be placed in a special segment or address.
83 extern uint8_t ucHeap[configTOTAL_HEAP_SIZE];
85 static uint8_t ucHeap[configTOTAL_HEAP_SIZE];
86 #endif /* configAPPLICATION_ALLOCATED_HEAP */
88 static HeapRegion_t xHeapRegions[] = {
89 { ucHeap, configTOTAL_HEAP_SIZE },
92 #endif /* RTE_RTOS_FreeRTOS_HEAP_5 */
94 /*---------------------------------------------------------------------------*/
96 #if (__ARM_ARCH_7A__ == 0U)
97 /* FreeRTOS SysTick handler prototypes */
98 extern void SysTick_Handler (void);
99 extern void xPortSysTickHandler (void);
101 void SysTick_Handler (void) {
102 /* Clear overflow flag */
105 /* Call tick handler */
106 xPortSysTickHandler();
110 /*---------------------------------------------------------------------------*/
112 osStatus_t osKernelInitialize (void) {
119 #if defined(RTE_RTOS_FreeRTOS_HEAP_5)
120 vPortDefineHeapRegions (xHeapRegions);
122 KernelState = osKernelReady;
129 osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) {
136 if (version != NULL) {
137 version->api = KERNEL_VERSION;
138 version->kernel = KERNEL_VERSION;
141 if ((id_buf != NULL) && (id_size != 0U)) {
142 if (id_size > sizeof(KERNEL_ID)) {
143 id_size = sizeof(KERNEL_ID);
145 memcpy(id_buf, KERNEL_ID, id_size);
153 osKernelState_t osKernelGetState (void) {
154 osKernelState_t state;
157 state = osKernelError;
160 switch (xTaskGetSchedulerState()) {
161 case taskSCHEDULER_RUNNING:
162 state = osKernelRunning;
165 case taskSCHEDULER_SUSPENDED:
166 state = osKernelLocked;
169 case taskSCHEDULER_NOT_STARTED:
171 if (KernelState == osKernelReady) {
172 state = osKernelReady;
174 state = osKernelInactive;
182 osStatus_t osKernelStart (void) {
189 KernelState = osKernelRunning;
190 vTaskStartScheduler();
197 int32_t osKernelLock (void) {
201 lock = (int32_t)osErrorISR;
204 switch (xTaskGetSchedulerState()) {
205 case taskSCHEDULER_SUSPENDED:
209 case taskSCHEDULER_RUNNING:
214 case taskSCHEDULER_NOT_STARTED:
216 lock = (int32_t)osError;
224 int32_t osKernelUnlock (void) {
228 lock = (int32_t)osErrorISR;
231 switch (xTaskGetSchedulerState()) {
232 case taskSCHEDULER_SUSPENDED:
233 if (xTaskResumeAll() == pdTRUE) {
236 lock = (int32_t)osError;
240 case taskSCHEDULER_RUNNING:
244 case taskSCHEDULER_NOT_STARTED:
246 lock = (int32_t)osError;
254 int32_t osKernelRestoreLock (int32_t lock) {
257 lock = (int32_t)osErrorISR;
260 switch (xTaskGetSchedulerState()) {
261 case taskSCHEDULER_SUSPENDED:
262 case taskSCHEDULER_RUNNING:
267 if ((lock != 0) || (xTaskResumeAll() != pdTRUE)) {
268 lock = (int32_t)osError;
273 case taskSCHEDULER_NOT_STARTED:
275 lock = (int32_t)osError;
283 uint64_t osKernelGetTickCount (void) {
287 ticks = xTaskGetTickCountFromISR();
289 ticks = xTaskGetTickCount();
292 return ((uint64_t)ticks);
295 uint32_t osKernelGetTickFreq (void) {
301 freq = configTICK_RATE_HZ;
307 uint32_t osKernelGetSysTimerCount (void) {
311 portDISABLE_INTERRUPTS();
313 ticks = xTaskGetTickCount();
315 #if (__ARM_ARCH_7A__ == 1U)
316 #if (__CORTEX_A == 9U)
317 /* Cortex-A9 uses Private Timer */
318 val = PTIM_GetLoadValue() - PTIM_GetCurrentValue();
319 val += ticks * (PTIM_GetLoadValue() + 1U);
322 val = SysTick->LOAD - SysTick->VAL;
324 if ((SysTick->CTRL >> 16) & 1U) {
326 val = SysTick->LOAD - SysTick->VAL;
329 val += ticks * (SysTick->LOAD + 1U);
332 portENABLE_INTERRUPTS();
337 uint32_t osKernelGetSysTimerFreq (void) {
338 return (configCPU_CLOCK_HZ);
341 /*---------------------------------------------------------------------------*/
343 osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) {
353 if (!IS_IRQ() && (func != NULL)) {
354 stack = configMINIMAL_STACK_SIZE;
355 prio = (UBaseType_t)osPriorityNormal;
362 if (attr->name != NULL) {
365 if (attr->priority != osPriorityNone) {
366 prio = (UBaseType_t)attr->priority;
369 if ((prio < osPriorityIdle) || (prio > osPriorityISR) || ((attr->attr_bits & osThreadJoinable) == osThreadJoinable)) {
373 if (attr->stack_size > 0U) {
374 stack = attr->stack_size;
377 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTask_t)) &&
378 (attr->stack_mem != NULL) && (attr->stack_size > 0U)) {
382 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) && (attr->stack_mem == NULL)) {
392 h = xTaskCreateStatic ((TaskFunction_t)func, name, stack, argument, prio, (StackType_t *)attr->stack_mem,
393 (StaticTask_t *)attr->cb_mem);
397 if (xTaskCreate ((TaskFunction_t)func, name, stack, argument, prio, &h) != pdPASS) {
404 return ((osThreadId_t)h);
407 const char *osThreadGetName (osThreadId_t thread_id) {
410 if (IS_IRQ() || (thread_id == NULL)) {
413 name = pcTaskGetName ((TaskHandle_t)thread_id);
419 osThreadId_t osThreadGetId (void) {
425 id = (osThreadId_t)xTaskGetCurrentTaskHandle();
431 osThreadState_t osThreadGetState (osThreadId_t thread_id) {
432 osThreadState_t state;
434 if (IS_IRQ() || (thread_id == NULL)) {
435 state = osThreadError;
438 switch (eTaskGetState ((TaskHandle_t)thread_id)) {
439 case eRunning: state = osThreadRunning; break;
440 case eReady: state = osThreadReady; break;
442 case eSuspended: state = osThreadBlocked; break;
443 case eDeleted: state = osThreadTerminated; break;
445 default: state = osThreadError; break;
452 uint32_t osThreadGetStackSpace (osThreadId_t thread_id) {
455 if (IS_IRQ() || (thread_id == NULL)) {
458 sz = (uint32_t)uxTaskGetStackHighWaterMark ((TaskHandle_t)thread_id);
464 osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) {
470 else if ((thread_id == NULL) || (priority < osPriorityIdle) || (priority > osPriorityISR)) {
471 stat = osErrorParameter;
475 vTaskPrioritySet ((TaskHandle_t)thread_id, (UBaseType_t)priority);
481 osPriority_t osThreadGetPriority (osThreadId_t thread_id) {
484 if (IS_IRQ() || (thread_id == NULL)) {
485 prio = osPriorityError;
487 prio = (osPriority_t)uxTaskPriorityGet ((TaskHandle_t)thread_id);
493 osStatus_t osThreadYield (void) {
506 osStatus_t osThreadSuspend (osThreadId_t thread_id) {
512 else if (thread_id == NULL) {
513 stat = osErrorParameter;
517 vTaskSuspend ((TaskHandle_t)thread_id);
523 osStatus_t osThreadResume (osThreadId_t thread_id) {
529 else if (thread_id == NULL) {
530 stat = osErrorParameter;
534 vTaskResume ((TaskHandle_t)thread_id);
540 __NO_RETURN void osThreadExit (void) {
541 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
547 osStatus_t osThreadTerminate (osThreadId_t thread_id) {
549 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
555 else if (thread_id == NULL) {
556 stat = osErrorParameter;
559 tstate = eTaskGetState ((TaskHandle_t)thread_id);
561 if (tstate != eDeleted) {
563 vTaskDelete ((TaskHandle_t)thread_id);
565 stat = osErrorResource;
575 uint32_t osThreadGetCount (void) {
581 count = uxTaskGetNumberOfTasks();
587 uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) {
591 if (IS_IRQ() || (thread_array == NULL) || (array_items == 0U)) {
596 count = uxTaskGetNumberOfTasks();
597 task = pvPortMalloc (count * sizeof(TaskStatus_t));
600 count = uxTaskGetSystemState (task, count, NULL);
602 for (i = 0U; (i < count) && (i < array_items); i++) {
603 thread_array[i] = (osThreadId_t)task[i].xHandle;
607 (void)xTaskResumeAll();
615 uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) {
616 TaskHandle_t thread = (TaskHandle_t)thread_id;
618 if ((thread == NULL) || ((flags & THREAD_FLAGS_INVALID_BITS) != 0U)) {
619 flags = (uint32_t)osErrorParameter;
622 if (xTaskNotifyFromISR (thread, flags, eSetBits, NULL) != pdPASS) {
623 flags = (uint32_t)osError;
627 if (xTaskNotify (thread, flags, eSetBits) != pdPASS) {
628 flags = (uint32_t)osError;
631 /* Return flags after setting */
635 uint32_t osThreadFlagsClear (uint32_t flags) {
637 uint32_t rflags, cflags;
640 rflags = (uint32_t)osErrorISR;
642 else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) {
643 rflags = (uint32_t)osErrorParameter;
646 thread = xTaskGetCurrentTaskHandle();
648 if (xTaskNotifyAndQuery (thread, 0, eNoAction, &cflags) == pdPASS) {
652 if (xTaskNotify (thread, cflags, eSetValueWithOverwrite) != pdPASS) {
653 rflags = (uint32_t)osError;
657 rflags = (uint32_t)osError;
661 /* Return flags before clearing */
665 uint32_t osThreadFlagsGet (void) {
670 rflags = (uint32_t)osErrorISR;
673 thread = xTaskGetCurrentTaskHandle();
675 if (xTaskNotifyAndQuery (thread, 0, eNoAction, &rflags) != pdPASS) {
676 rflags = (uint32_t)osError;
683 uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) {
684 uint32_t rflags, nval;
689 rflags = (uint32_t)osErrorISR;
691 else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) {
692 rflags = (uint32_t)osErrorParameter;
695 if ((options & osFlagsNoClear) == osFlagsNoClear) {
703 t0 = xTaskGetTickCount();
705 if (xTaskNotifyWait (0, clear, &nval, timeout) == pdPASS) {
708 if ((options & osFlagsWaitAll) == osFlagsWaitAll) {
709 if ((flags & rflags) == flags) {
713 rflags = (uint32_t)osErrorResource;
718 if ((flags & rflags) != 0) {
722 rflags = (uint32_t)osErrorResource;
729 rflags = (uint32_t)osErrorResource;
731 rflags = (uint32_t)osErrorTimeout;
736 while ((xTaskGetTickCount() - t0) < timeout);
739 /* Return flags before clearing */
743 osStatus_t osDelay (uint32_t ticks) {
760 osStatus_t osDelayUntil (uint64_t ticks) {
769 tcnt = xTaskGetTickCount();
771 vTaskDelayUntil (&tcnt, (TickType_t)ticks);
777 /*---------------------------------------------------------------------------*/
779 static void TimerCallback (TimerHandle_t hTimer) {
780 TimerCallback_t *callb;
782 callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer);
785 callb->func (callb->arg);
789 osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) {
792 TimerCallback_t *callb;
798 if (!IS_IRQ() && (func != NULL)) {
799 /* Allocate memory to store callback function and argument */
800 callb = pvPortMalloc (sizeof(TimerCallback_t));
804 callb->arg = argument;
806 if (type == osTimerOnce) {
816 if (attr->name != NULL) {
820 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTimer_t))) {
824 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
834 h = xTimerCreateStatic (name, 1, reload, callb, TimerCallback, (StaticTimer_t *)attr->cb_mem);
838 h = xTimerCreate (name, 1, reload, callb, TimerCallback);
844 return ((osTimerId_t)h);
847 const char *osTimerGetName (osTimerId_t timer_id) {
850 if (IS_IRQ() || (timer_id == NULL)) {
853 p = pcTimerGetName ((TimerHandle_t)timer_id);
859 osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks) {
865 else if (timer_id == NULL) {
866 stat = osErrorParameter;
869 if (xTimerChangePeriod ((TimerHandle_t)timer_id, ticks, 0) == pdPASS) {
872 stat = osErrorResource;
879 osStatus_t osTimerStop (osTimerId_t timer_id) {
885 else if (timer_id == NULL) {
886 stat = osErrorParameter;
889 if (xTimerIsTimerActive ((TimerHandle_t)timer_id) == pdFALSE) {
890 stat = osErrorResource;
893 if (xTimerStop ((TimerHandle_t)timer_id, 0) == pdPASS) {
904 uint32_t osTimerIsRunning (osTimerId_t timer_id) {
907 if (IS_IRQ() || (timer_id == NULL)) {
910 running = xTimerIsTimerActive ((TimerHandle_t)timer_id);
916 osStatus_t osTimerDelete (osTimerId_t timer_id) {
918 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
919 TimerCallback_t *callb;
924 else if (timer_id == NULL) {
925 stat = osErrorParameter;
928 callb = (TimerCallback_t *)pvTimerGetTimerID ((TimerHandle_t)timer_id);
930 if (xTimerDelete ((TimerHandle_t)timer_id, 0) == pdPASS) {
934 stat = osErrorResource;
944 /*---------------------------------------------------------------------------*/
946 osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr) {
947 EventGroupHandle_t h;
956 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticEventGroup_t))) {
960 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
970 h = xEventGroupCreateStatic (attr->cb_mem);
974 h = xEventGroupCreate();
979 return ((osEventFlagsId_t)h);
982 uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) {
985 if ((ef_id == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
986 rflags = (uint32_t)osErrorParameter;
989 if (xEventGroupSetBitsFromISR ((EventGroupHandle_t)ef_id, (EventBits_t)flags, NULL) == pdPASS) {
992 rflags = (uint32_t)osErrorResource;
996 rflags = xEventGroupSetBits ((EventGroupHandle_t)ef_id, (EventBits_t)flags);
1002 uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) {
1005 if ((ef_id == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1006 rflags = (uint32_t)osErrorParameter;
1008 else if (IS_IRQ()) {
1009 rflags = xEventGroupGetBitsFromISR ((EventGroupHandle_t)ef_id);
1011 if (xEventGroupClearBitsFromISR ((EventGroupHandle_t)ef_id, (EventBits_t)flags) == pdFAIL) {
1012 rflags = (uint32_t)osErrorResource;
1016 rflags = xEventGroupClearBits ((EventGroupHandle_t)ef_id, (EventBits_t)flags);
1022 uint32_t osEventFlagsGet (osEventFlagsId_t ef_id) {
1025 if (ef_id == NULL) {
1028 else if (IS_IRQ()) {
1029 rflags = xEventGroupGetBitsFromISR ((EventGroupHandle_t)ef_id);
1032 rflags = xEventGroupGetBits ((EventGroupHandle_t)ef_id);
1038 uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) {
1039 BaseType_t wait_all;
1040 BaseType_t exit_clr;
1043 if ((ef_id == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1044 rflags = (uint32_t)osErrorParameter;
1046 else if (IS_IRQ()) {
1047 rflags = (uint32_t)osErrorISR;
1050 if (options & osFlagsWaitAll) {
1056 if (options & osFlagsNoClear) {
1062 rflags = xEventGroupWaitBits ((EventGroupHandle_t)ef_id, (EventBits_t)flags, exit_clr,
1064 (TickType_t)timeout);
1065 if (options & osFlagsWaitAll) {
1066 if (flags != rflags) {
1068 rflags = (uint32_t)osErrorTimeout;
1070 rflags = (uint32_t)osErrorResource;
1075 if ((flags & rflags) == 0U) {
1077 rflags = (uint32_t)osErrorTimeout;
1079 rflags = (uint32_t)osErrorResource;
1088 osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id) {
1091 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1095 else if (ef_id == NULL) {
1096 stat = osErrorParameter;
1100 vEventGroupDelete ((EventGroupHandle_t)ef_id);
1109 /*---------------------------------------------------------------------------*/
1111 osMutexId_t osMutexNew (const osMutexAttr_t *attr) {
1112 SemaphoreHandle_t mutex;
1121 type = attr->attr_bits;
1126 if ((type & osMutexRecursive) == osMutexRecursive) {
1132 if ((type & osMutexRobust) != osMutexRobust) {
1136 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
1140 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1151 mutex = xSemaphoreCreateRecursiveMutexStatic (attr->cb_mem);
1154 mutex = xSemaphoreCreateMutexStatic (attr->cb_mem);
1160 mutex = xSemaphoreCreateRecursiveMutex ();
1162 mutex = xSemaphoreCreateMutex ();
1167 if ((mutex != NULL) && (rmtx != 0U)) {
1168 mutex = (SemaphoreHandle_t)((uint32_t)mutex | 1U);
1173 return ((osMutexId_t)mutex);
1176 osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
1177 SemaphoreHandle_t mutex;
1181 mutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1183 rmtx = (uint32_t)mutex_id & 1U;
1190 else if (mutex == NULL) {
1191 stat = osErrorParameter;
1195 if (xSemaphoreTakeRecursive (mutex, timeout) != pdPASS) {
1196 if (timeout != 0U) {
1197 stat = osErrorTimeout;
1199 stat = osErrorResource;
1204 if (xSemaphoreTake (mutex, timeout) != pdPASS) {
1205 if (timeout != 0U) {
1206 stat = osErrorTimeout;
1208 stat = osErrorResource;
1217 osStatus_t osMutexRelease (osMutexId_t mutex_id) {
1218 SemaphoreHandle_t mutex;
1222 mutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1224 rmtx = (uint32_t)mutex_id & 1U;
1231 else if (mutex == NULL) {
1232 stat = osErrorParameter;
1236 if (xSemaphoreGiveRecursive (mutex) != pdPASS) {
1237 stat = osErrorResource;
1241 if (xSemaphoreGive (mutex) != pdPASS) {
1242 stat = osErrorResource;
1250 osThreadId_t osMutexGetOwner (osMutexId_t mutex_id) {
1251 SemaphoreHandle_t mutex;
1254 mutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1256 if (IS_IRQ() || (mutex == NULL)) {
1259 owner = (osThreadId_t)xSemaphoreGetMutexHolder (mutex);
1265 osStatus_t osMutexDelete (osMutexId_t mutex_id) {
1267 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1268 SemaphoreHandle_t mutex;
1270 mutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1275 else if (mutex == NULL) {
1276 stat = osErrorParameter;
1280 vSemaphoreDelete (mutex);
1289 /*---------------------------------------------------------------------------*/
1291 osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) {
1292 SemaphoreHandle_t h;
1297 if (!IS_IRQ() && (max_count > 0U) && (initial_count <= max_count)) {
1301 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
1305 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1315 if (max_count == 1U) {
1317 h = xSemaphoreCreateBinaryStatic ((StaticSemaphore_t *)attr->cb_mem);
1320 h = xSemaphoreCreateBinary();
1323 if ((h != NULL) && (initial_count != 0U)) {
1324 if (xSemaphoreGive (h) != pdPASS) {
1325 vSemaphoreDelete (h);
1332 h = xSemaphoreCreateCountingStatic (max_count, initial_count, (StaticSemaphore_t *)attr->cb_mem);
1335 h = xSemaphoreCreateCounting (max_count, initial_count);
1344 osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) {
1349 if (semaphore_id == NULL) {
1350 stat = osErrorParameter;
1352 else if (IS_IRQ()) {
1353 if (timeout != 0U) {
1354 stat = osErrorParameter;
1357 if (xSemaphoreTakeFromISR ((SemaphoreHandle_t)semaphore_id, NULL) != pdPASS) {
1358 stat = osErrorResource;
1363 if (xSemaphoreTake ((SemaphoreHandle_t)semaphore_id, (TickType_t)timeout) != pdPASS) {
1364 if (timeout != 0U) {
1365 stat = osErrorTimeout;
1367 stat = osErrorResource;
1375 osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id) {
1380 if (semaphore_id == NULL) {
1381 stat = osErrorParameter;
1383 else if (IS_IRQ()) {
1384 if (xSemaphoreGiveFromISR ((SemaphoreHandle_t)semaphore_id, NULL) != pdTRUE) {
1385 stat = osErrorResource;
1389 if (xSemaphoreGive ((SemaphoreHandle_t)semaphore_id) != pdPASS) {
1390 stat = osErrorResource;
1397 uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id) {
1400 if (semaphore_id == NULL) {
1403 else if (IS_IRQ()) {
1404 count = uxQueueMessagesWaitingFromISR ((QueueHandle_t)semaphore_id);
1406 count = (uint32_t)uxSemaphoreGetCount ((SemaphoreHandle_t)semaphore_id);
1412 osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id) {
1415 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1419 else if (semaphore_id == NULL) {
1420 stat = osErrorParameter;
1424 vSemaphoreDelete ((SemaphoreHandle_t)semaphore_id);
1433 /*---------------------------------------------------------------------------*/
1435 osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) {
1441 if (!IS_IRQ() && (msg_count > 0U) && (msg_size > 0U)) {
1445 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticQueue_t)) &&
1446 (attr->mq_mem != NULL) && (attr->mq_size >= (msg_count * msg_size))) {
1450 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) &&
1451 (attr->mq_mem == NULL) && (attr->mq_size == 0U)) {
1461 h = xQueueCreateStatic (msg_count, msg_size, attr->mq_mem, attr->cb_mem);
1465 h = xQueueCreate (msg_count, msg_size);
1470 return ((osMessageQueueId_t)h);
1473 osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) {
1476 (void)msg_prio; /* Message priority is ignored */
1481 if ((mq_id == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
1482 stat = osErrorParameter;
1485 if (xQueueSendToBackFromISR ((QueueHandle_t)mq_id, msg_ptr, NULL) != pdTRUE) {
1486 stat = osErrorResource;
1491 if ((mq_id == NULL) || (msg_ptr == NULL)) {
1492 stat = osErrorParameter;
1495 if (xQueueSendToBack ((QueueHandle_t)mq_id, msg_ptr, (TickType_t)timeout) != pdPASS) {
1496 if (timeout != 0U) {
1497 stat = osErrorTimeout;
1499 stat = osErrorResource;
1508 osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) {
1511 (void)msg_prio; /* Message priority is ignored */
1516 if ((mq_id == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
1517 stat = osErrorParameter;
1520 if (xQueueReceiveFromISR ((QueueHandle_t)mq_id, msg_ptr, NULL) != pdPASS) {
1521 stat = osErrorResource;
1526 if ((mq_id == NULL) || (msg_ptr == NULL)) {
1527 stat = osErrorParameter;
1530 if (xQueueReceive ((QueueHandle_t)mq_id, msg_ptr, (TickType_t)timeout) != pdPASS) {
1531 if (timeout != 0U) {
1532 stat = osErrorTimeout;
1534 stat = osErrorResource;
1543 uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id) {
1544 StaticQueue_t *mq = (StaticQueue_t *)mq_id;
1550 /* capacity = pxQueue->uxLength */
1551 capacity = mq->uxDummy4[1];
1557 uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id) {
1558 StaticQueue_t *mq = (StaticQueue_t *)mq_id;
1564 /* size = pxQueue->uxItemSize */
1565 size = mq->uxDummy4[2];
1571 uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) {
1574 if (mq_id == NULL) {
1577 else if (IS_IRQ()) {
1578 count = uxQueueMessagesWaitingFromISR ((QueueHandle_t)mq_id);
1581 count = uxQueueMessagesWaiting ((QueueHandle_t)mq_id);
1584 return ((uint32_t)count);
1587 uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) {
1588 StaticQueue_t *mq = (StaticQueue_t *)mq_id;
1595 else if (IS_IRQ()) {
1596 isrm = taskENTER_CRITICAL_FROM_ISR();
1598 /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */
1599 space = mq->uxDummy4[1] - mq->uxDummy4[0];
1601 taskEXIT_CRITICAL_FROM_ISR(isrm);
1604 space = (uint32_t)uxQueueSpacesAvailable ((QueueHandle_t)mq);
1610 osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id) {
1616 else if (mq_id == NULL) {
1617 stat = osErrorParameter;
1621 (void)xQueueReset ((QueueHandle_t)mq_id);
1627 osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) {
1630 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1634 else if (mq_id == NULL) {
1635 stat = osErrorParameter;
1639 vQueueDelete ((QueueHandle_t)mq_id);
1648 /*---------------------------------------------------------------------------*/
1650 /* Callback function prototypes */
1651 extern void vApplicationIdleHook (void);
1652 extern void vApplicationTickHook (void);
1653 extern void vApplicationMallocFailedHook (void);
1654 extern void vApplicationDaemonTaskStartupHook (void);
1655 extern void vApplicationStackOverflowHook (TaskHandle_t xTask, signed char *pcTaskName);
1658 Dummy implementation of the callback function vApplicationIdleHook().
1660 #if (configUSE_IDLE_HOOK == 1)
1661 __WEAK void vApplicationIdleHook (void){}
1665 Dummy implementation of the callback function vApplicationTickHook().
1667 #if (configUSE_TICK_HOOK == 1)
1668 __WEAK void vApplicationTickHook (void){}
1672 Dummy implementation of the callback function vApplicationMallocFailedHook().
1674 #if (configUSE_MALLOC_FAILED_HOOK == 1)
1675 __WEAK void vApplicationMallocFailedHook (void){}
1679 Dummy implementation of the callback function vApplicationDaemonTaskStartupHook().
1681 #if (configUSE_DAEMON_TASK_STARTUP_HOOK == 1)
1682 __WEAK void vApplicationDaemonTaskStartupHook (void){}
1686 Dummy implementation of the callback function vApplicationStackOverflowHook().
1688 #if (configCHECK_FOR_STACK_OVERFLOW > 0)
1689 __WEAK void vApplicationStackOverflowHook (TaskHandle_t xTask, signed char *pcTaskName) {
1695 /*---------------------------------------------------------------------------*/
1697 /* External Idle and Timer task static memory allocation functions */
1698 extern void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize);
1699 extern void vApplicationGetTimerTaskMemory (StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize);
1701 /* Idle task control block and stack */
1702 static StaticTask_t Idle_TCB;
1703 static StackType_t Idle_Stack[configMINIMAL_STACK_SIZE];
1705 /* Timer task control block and stack */
1706 static StaticTask_t Timer_TCB;
1707 static StackType_t Timer_Stack[configTIMER_TASK_STACK_DEPTH];
1710 vApplicationGetIdleTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
1711 equals to 1 and is required for static memory allocation support.
1713 void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {
1714 *ppxIdleTaskTCBBuffer = &Idle_TCB;
1715 *ppxIdleTaskStackBuffer = &Idle_Stack[0];
1716 *pulIdleTaskStackSize = (uint32_t)configMINIMAL_STACK_SIZE;
1720 vApplicationGetTimerTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
1721 equals to 1 and is required for static memory allocation support.
1723 void vApplicationGetTimerTaskMemory (StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) {
1724 *ppxTimerTaskTCBBuffer = &Timer_TCB;
1725 *ppxTimerTaskStackBuffer = &Timer_Stack[0];
1726 *pulTimerTaskStackSize = (uint32_t)configTIMER_TASK_STACK_DEPTH;