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
27 #include "cmsis_os2.h" // ::CMSIS:RTOS2
28 #include "cmsis_compiler.h"
30 #include "FreeRTOS.h" // ARM.FreeRTOS::RTOS:Core
31 #include "task.h" // ARM.FreeRTOS::RTOS:Core
32 #include "event_groups.h" // ARM.FreeRTOS::RTOS:Event Groups
33 #include "semphr.h" // ARM.FreeRTOS::RTOS:Core
35 /*---------------------------------------------------------------------------*/
36 #ifndef __ARM_ARCH_6M__
37 #define __ARM_ARCH_6M__ 0
39 #ifndef __ARM_ARCH_7M__
40 #define __ARM_ARCH_7M__ 0
42 #ifndef __ARM_ARCH_7EM__
43 #define __ARM_ARCH_7EM__ 0
45 #ifndef __ARM_ARCH_8M_MAIN__
46 #define __ARM_ARCH_8M_MAIN__ 0
48 #ifndef __ARM_ARCH_7A__
49 #define __ARM_ARCH_7A__ 0
52 #if ((__ARM_ARCH_7M__ == 1U) || \
53 (__ARM_ARCH_7EM__ == 1U) || \
54 (__ARM_ARCH_8M_MAIN__ == 1U))
55 #define IS_IRQ_MASKED() ((__get_PRIMASK() != 0U) || ((KernelState == osKernelRunning) && (__get_BASEPRI() != 0U)))
56 #elif (__ARM_ARCH_6M__ == 1U)
57 #define IS_IRQ_MASKED() ((__get_PRIMASK() != 0U) && (KernelState == osKernelRunning))
59 #define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
62 #if (__ARM_ARCH_7A__ == 1U)
63 #define IS_IRQ() (__get_mode() == 0x12U)
65 #define IS_IRQ_MODE() (__get_IPSR() != 0U)
66 #define IS_IRQ() (IS_IRQ_MODE() || IS_IRQ_MASKED())
70 #define MAX_BITS_TASK_NOTIFY 31U
71 #define MAX_BITS_EVENT_GROUPS 24U
73 #define THREAD_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_TASK_NOTIFY) - 1U))
74 #define EVENT_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_EVENT_GROUPS) - 1U))
76 /* Kernel version and identification string definition */
77 #define KERNEL_VERSION (((uint32_t)tskKERNEL_VERSION_MAJOR * 10000000UL) | \
78 ((uint32_t)tskKERNEL_VERSION_MINOR * 10000UL) | \
79 ((uint32_t)tskKERNEL_VERSION_BUILD * 1UL))
81 #define KERNEL_ID "FreeRTOS V9.0.0"
83 /* Timer callback information structure definition */
89 /* Kernel initialization state */
90 static osKernelState_t KernelState;
92 /* Heap region definition used by heap_5 variant */
93 #if defined(RTE_RTOS_FreeRTOS_HEAP_5)
94 #if (configAPPLICATION_ALLOCATED_HEAP == 1)
96 The application writer has already defined the array used for the RTOS
97 heap - probably so it can be placed in a special segment or address.
99 extern uint8_t ucHeap[configTOTAL_HEAP_SIZE];
101 static uint8_t ucHeap[configTOTAL_HEAP_SIZE];
102 #endif /* configAPPLICATION_ALLOCATED_HEAP */
104 static HeapRegion_t xHeapRegions[] = {
105 { ucHeap, configTOTAL_HEAP_SIZE },
108 #endif /* RTE_RTOS_FreeRTOS_HEAP_5 */
111 /* FreeRTOS tick timer interrupt handler prototype */
112 extern void xPortSysTickHandler (void);
115 SysTick handler implementation that also clears overflow flag.
117 void SysTick_Handler (void) {
118 /* Clear overflow flag */
121 /* Call tick handler */
122 xPortSysTickHandler();
126 /*---------------------------------------------------------------------------*/
128 osStatus_t osKernelInitialize (void) {
135 if (KernelState == osKernelInactive) {
136 #if defined(RTE_RTOS_FreeRTOS_HEAP_5)
137 vPortDefineHeapRegions (xHeapRegions);
139 KernelState = osKernelReady;
149 osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) {
156 if (version != NULL) {
157 version->api = KERNEL_VERSION;
158 version->kernel = KERNEL_VERSION;
161 if ((id_buf != NULL) && (id_size != 0U)) {
162 if (id_size > sizeof(KERNEL_ID)) {
163 id_size = sizeof(KERNEL_ID);
165 memcpy(id_buf, KERNEL_ID, id_size);
173 osKernelState_t osKernelGetState (void) {
174 osKernelState_t state;
177 state = osKernelError;
180 switch (xTaskGetSchedulerState()) {
181 case taskSCHEDULER_RUNNING:
182 state = osKernelRunning;
185 case taskSCHEDULER_SUSPENDED:
186 state = osKernelLocked;
189 case taskSCHEDULER_NOT_STARTED:
191 if (KernelState == osKernelReady) {
192 state = osKernelReady;
194 state = osKernelInactive;
202 osStatus_t osKernelStart (void) {
209 if (KernelState == osKernelReady) {
210 KernelState = osKernelRunning;
211 vTaskStartScheduler();
221 int32_t osKernelLock (void) {
225 lock = (int32_t)osErrorISR;
228 switch (xTaskGetSchedulerState()) {
229 case taskSCHEDULER_SUSPENDED:
233 case taskSCHEDULER_RUNNING:
238 case taskSCHEDULER_NOT_STARTED:
240 lock = (int32_t)osError;
248 int32_t osKernelUnlock (void) {
252 lock = (int32_t)osErrorISR;
255 switch (xTaskGetSchedulerState()) {
256 case taskSCHEDULER_SUSPENDED:
259 if (xTaskResumeAll() != pdTRUE) {
260 if (xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED) {
261 lock = (int32_t)osError;
266 case taskSCHEDULER_RUNNING:
270 case taskSCHEDULER_NOT_STARTED:
272 lock = (int32_t)osError;
280 int32_t osKernelRestoreLock (int32_t lock) {
283 lock = (int32_t)osErrorISR;
286 switch (xTaskGetSchedulerState()) {
287 case taskSCHEDULER_SUSPENDED:
288 case taskSCHEDULER_RUNNING:
294 lock = (int32_t)osError;
297 if (xTaskResumeAll() != pdTRUE) {
298 if (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) {
299 lock = (int32_t)osError;
306 case taskSCHEDULER_NOT_STARTED:
308 lock = (int32_t)osError;
316 uint32_t osKernelGetTickCount (void) {
320 ticks = xTaskGetTickCountFromISR();
322 ticks = xTaskGetTickCount();
328 uint32_t osKernelGetTickFreq (void) {
329 return (configTICK_RATE_HZ);
332 uint32_t osKernelGetSysTimerCount (void) {
336 portDISABLE_INTERRUPTS();
338 ticks = xTaskGetTickCount();
339 val = OS_Tick_GetCount();
341 if (OS_Tick_GetOverflow() != 0U) {
342 val = OS_Tick_GetCount();
345 val += ticks * OS_Tick_GetInterval();
347 portENABLE_INTERRUPTS();
352 uint32_t osKernelGetSysTimerFreq (void) {
353 return (configCPU_CLOCK_HZ);
356 /*---------------------------------------------------------------------------*/
358 osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) {
368 if (!IS_IRQ() && (func != NULL)) {
369 stack = configMINIMAL_STACK_SIZE;
370 prio = (UBaseType_t)osPriorityNormal;
377 if (attr->name != NULL) {
380 if (attr->priority != osPriorityNone) {
381 prio = (UBaseType_t)attr->priority;
384 if ((prio < osPriorityIdle) || (prio > osPriorityISR) || ((attr->attr_bits & osThreadJoinable) == osThreadJoinable)) {
388 if (attr->stack_size > 0U) {
389 stack = attr->stack_size / sizeof(StackType_t);
390 // in freeRTOS Stack is not in Bytes, but in sizeof(StackType_t) which is 4 in this case.
391 // look here http://www.freertos.org/a00125.html at parameter usStackDepth in xTaskCreate
394 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTask_t)) &&
395 (attr->stack_mem != NULL) && (attr->stack_size > 0U)) {
399 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) && (attr->stack_mem == NULL)) {
409 h = xTaskCreateStatic ((TaskFunction_t)func, name, stack, argument, prio, (StackType_t *)attr->stack_mem,
410 (StaticTask_t *)attr->cb_mem);
414 if (xTaskCreate ((TaskFunction_t)func, name, (uint16_t)stack, argument, prio, &h) != pdPASS) {
421 return ((osThreadId_t)h);
424 const char *osThreadGetName (osThreadId_t thread_id) {
427 if (IS_IRQ() || (thread_id == NULL)) {
430 name = pcTaskGetName ((TaskHandle_t)thread_id);
436 osThreadId_t osThreadGetId (void) {
442 id = (osThreadId_t)xTaskGetCurrentTaskHandle();
448 osThreadState_t osThreadGetState (osThreadId_t thread_id) {
449 osThreadState_t state;
451 if (IS_IRQ() || (thread_id == NULL)) {
452 state = osThreadError;
455 switch (eTaskGetState ((TaskHandle_t)thread_id)) {
456 case eRunning: state = osThreadRunning; break;
457 case eReady: state = osThreadReady; break;
459 case eSuspended: state = osThreadBlocked; break;
460 case eDeleted: state = osThreadTerminated; break;
462 default: state = osThreadError; break;
469 uint32_t osThreadGetStackSpace (osThreadId_t thread_id) {
472 if (IS_IRQ() || (thread_id == NULL)) {
475 sz = (uint32_t)uxTaskGetStackHighWaterMark ((TaskHandle_t)thread_id);
481 osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) {
487 else if ((thread_id == NULL) || (priority < osPriorityIdle) || (priority > osPriorityISR)) {
488 stat = osErrorParameter;
492 vTaskPrioritySet ((TaskHandle_t)thread_id, (UBaseType_t)priority);
498 osPriority_t osThreadGetPriority (osThreadId_t thread_id) {
501 if (IS_IRQ() || (thread_id == NULL)) {
502 prio = osPriorityError;
504 prio = (osPriority_t)uxTaskPriorityGet ((TaskHandle_t)thread_id);
510 osStatus_t osThreadYield (void) {
523 osStatus_t osThreadSuspend (osThreadId_t thread_id) {
529 else if (thread_id == NULL) {
530 stat = osErrorParameter;
534 vTaskSuspend ((TaskHandle_t)thread_id);
540 osStatus_t osThreadResume (osThreadId_t thread_id) {
546 else if (thread_id == NULL) {
547 stat = osErrorParameter;
551 vTaskResume ((TaskHandle_t)thread_id);
557 __NO_RETURN void osThreadExit (void) {
558 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
564 osStatus_t osThreadTerminate (osThreadId_t thread_id) {
566 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
572 else if (thread_id == NULL) {
573 stat = osErrorParameter;
576 tstate = eTaskGetState ((TaskHandle_t)thread_id);
578 if (tstate != eDeleted) {
580 vTaskDelete ((TaskHandle_t)thread_id);
582 stat = osErrorResource;
592 uint32_t osThreadGetCount (void) {
598 count = uxTaskGetNumberOfTasks();
604 uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) {
608 if (IS_IRQ() || (thread_array == NULL) || (array_items == 0U)) {
613 count = uxTaskGetNumberOfTasks();
614 task = pvPortMalloc (count * sizeof(TaskStatus_t));
617 count = uxTaskGetSystemState (task, count, NULL);
619 for (i = 0U; (i < count) && (i < array_items); i++) {
620 thread_array[i] = (osThreadId_t)task[i].xHandle;
624 (void)xTaskResumeAll();
632 uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) {
633 TaskHandle_t thread = (TaskHandle_t)thread_id;
635 if ((thread == NULL) || ((flags & THREAD_FLAGS_INVALID_BITS) != 0U)) {
636 flags = (uint32_t)osErrorParameter;
639 if (xTaskNotifyFromISR (thread, flags, eSetBits, NULL) != pdPASS) {
640 flags = (uint32_t)osError;
644 if (xTaskNotify (thread, flags, eSetBits) != pdPASS) {
645 flags = (uint32_t)osError;
648 /* Return flags after setting */
652 uint32_t osThreadFlagsClear (uint32_t flags) {
654 uint32_t rflags, cflags;
657 rflags = (uint32_t)osErrorISR;
659 else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) {
660 rflags = (uint32_t)osErrorParameter;
663 thread = xTaskGetCurrentTaskHandle();
665 if (xTaskNotifyAndQuery (thread, 0, eNoAction, &cflags) == pdPASS) {
669 if (xTaskNotify (thread, cflags, eSetValueWithOverwrite) != pdPASS) {
670 rflags = (uint32_t)osError;
674 rflags = (uint32_t)osError;
678 /* Return flags before clearing */
682 uint32_t osThreadFlagsGet (void) {
687 rflags = (uint32_t)osErrorISR;
690 thread = xTaskGetCurrentTaskHandle();
692 if (xTaskNotifyAndQuery (thread, 0, eNoAction, &rflags) != pdPASS) {
693 rflags = (uint32_t)osError;
700 uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) {
701 uint32_t rflags, nval;
706 rflags = (uint32_t)osErrorISR;
708 else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) {
709 rflags = (uint32_t)osErrorParameter;
712 if ((options & osFlagsNoClear) == osFlagsNoClear) {
720 t0 = xTaskGetTickCount();
722 if (xTaskNotifyWait (0, clear, &nval, timeout) == pdPASS) {
725 if ((options & osFlagsWaitAll) == osFlagsWaitAll) {
726 if ((flags & rflags) == flags) {
730 rflags = (uint32_t)osErrorResource;
735 if ((flags & rflags) != 0) {
739 rflags = (uint32_t)osErrorResource;
746 rflags = (uint32_t)osErrorResource;
748 rflags = (uint32_t)osErrorTimeout;
753 while ((xTaskGetTickCount() - t0) < timeout);
756 /* Return flags before clearing */
760 osStatus_t osDelay (uint32_t ticks) {
777 osStatus_t osDelayUntil (uint32_t ticks) {
786 tcnt = xTaskGetTickCount();
788 vTaskDelayUntil (&tcnt, (TickType_t)ticks);
794 /*---------------------------------------------------------------------------*/
796 static void TimerCallback (TimerHandle_t hTimer) {
797 TimerCallback_t *callb;
799 callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer);
802 callb->func (callb->arg);
806 osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) {
809 TimerCallback_t *callb;
815 if (!IS_IRQ() && (func != NULL)) {
816 /* Allocate memory to store callback function and argument */
817 callb = pvPortMalloc (sizeof(TimerCallback_t));
821 callb->arg = argument;
823 if (type == osTimerOnce) {
833 if (attr->name != NULL) {
837 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTimer_t))) {
841 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
851 h = xTimerCreateStatic (name, 1, reload, callb, TimerCallback, (StaticTimer_t *)attr->cb_mem);
855 h = xTimerCreate (name, 1, reload, callb, TimerCallback);
861 return ((osTimerId_t)h);
864 const char *osTimerGetName (osTimerId_t timer_id) {
867 if (IS_IRQ() || (timer_id == NULL)) {
870 p = pcTimerGetName ((TimerHandle_t)timer_id);
876 osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks) {
882 else if (timer_id == NULL) {
883 stat = osErrorParameter;
886 if (xTimerChangePeriod ((TimerHandle_t)timer_id, ticks, 0) == pdPASS) {
889 stat = osErrorResource;
896 osStatus_t osTimerStop (osTimerId_t timer_id) {
902 else if (timer_id == NULL) {
903 stat = osErrorParameter;
906 if (xTimerIsTimerActive ((TimerHandle_t)timer_id) == pdFALSE) {
907 stat = osErrorResource;
910 if (xTimerStop ((TimerHandle_t)timer_id, 0) == pdPASS) {
921 uint32_t osTimerIsRunning (osTimerId_t timer_id) {
924 if (IS_IRQ() || (timer_id == NULL)) {
927 running = (uint32_t)xTimerIsTimerActive ((TimerHandle_t)timer_id);
933 osStatus_t osTimerDelete (osTimerId_t timer_id) {
935 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
936 TimerCallback_t *callb;
941 else if (timer_id == NULL) {
942 stat = osErrorParameter;
945 callb = (TimerCallback_t *)pvTimerGetTimerID ((TimerHandle_t)timer_id);
947 if (xTimerDelete ((TimerHandle_t)timer_id, 0) == pdPASS) {
951 stat = osErrorResource;
961 /*---------------------------------------------------------------------------*/
963 osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr) {
964 EventGroupHandle_t h;
973 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticEventGroup_t))) {
977 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
987 h = xEventGroupCreateStatic (attr->cb_mem);
991 h = xEventGroupCreate();
996 return ((osEventFlagsId_t)h);
999 uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) {
1002 if ((ef_id == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1003 rflags = (uint32_t)osErrorParameter;
1005 else if (IS_IRQ()) {
1006 if (xEventGroupSetBitsFromISR ((EventGroupHandle_t)ef_id, (EventBits_t)flags, NULL) == pdPASS) {
1009 rflags = (uint32_t)osErrorResource;
1013 rflags = xEventGroupSetBits ((EventGroupHandle_t)ef_id, (EventBits_t)flags);
1019 uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) {
1022 if ((ef_id == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1023 rflags = (uint32_t)osErrorParameter;
1025 else if (IS_IRQ()) {
1026 rflags = xEventGroupGetBitsFromISR ((EventGroupHandle_t)ef_id);
1028 if (xEventGroupClearBitsFromISR ((EventGroupHandle_t)ef_id, (EventBits_t)flags) == pdFAIL) {
1029 rflags = (uint32_t)osErrorResource;
1033 rflags = xEventGroupClearBits ((EventGroupHandle_t)ef_id, (EventBits_t)flags);
1039 uint32_t osEventFlagsGet (osEventFlagsId_t ef_id) {
1042 if (ef_id == NULL) {
1045 else if (IS_IRQ()) {
1046 rflags = xEventGroupGetBitsFromISR ((EventGroupHandle_t)ef_id);
1049 rflags = xEventGroupGetBits ((EventGroupHandle_t)ef_id);
1055 uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) {
1056 BaseType_t wait_all;
1057 BaseType_t exit_clr;
1060 if ((ef_id == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1061 rflags = (uint32_t)osErrorParameter;
1063 else if (IS_IRQ()) {
1064 rflags = (uint32_t)osErrorISR;
1067 if (options & osFlagsWaitAll) {
1073 if (options & osFlagsNoClear) {
1079 rflags = xEventGroupWaitBits ((EventGroupHandle_t)ef_id, (EventBits_t)flags, exit_clr,
1081 (TickType_t)timeout);
1082 if (options & osFlagsWaitAll) {
1083 if (flags != rflags) {
1085 rflags = (uint32_t)osErrorTimeout;
1087 rflags = (uint32_t)osErrorResource;
1092 if ((flags & rflags) == 0U) {
1094 rflags = (uint32_t)osErrorTimeout;
1096 rflags = (uint32_t)osErrorResource;
1105 osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id) {
1108 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1112 else if (ef_id == NULL) {
1113 stat = osErrorParameter;
1117 vEventGroupDelete ((EventGroupHandle_t)ef_id);
1126 /*---------------------------------------------------------------------------*/
1128 osMutexId_t osMutexNew (const osMutexAttr_t *attr) {
1129 SemaphoreHandle_t mutex;
1138 type = attr->attr_bits;
1143 if ((type & osMutexRecursive) == osMutexRecursive) {
1149 if ((type & osMutexRobust) != osMutexRobust) {
1153 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
1157 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1168 mutex = xSemaphoreCreateRecursiveMutexStatic (attr->cb_mem);
1171 mutex = xSemaphoreCreateMutexStatic (attr->cb_mem);
1177 mutex = xSemaphoreCreateRecursiveMutex ();
1179 mutex = xSemaphoreCreateMutex ();
1184 if ((mutex != NULL) && (rmtx != 0U)) {
1185 mutex = (SemaphoreHandle_t)((uint32_t)mutex | 1U);
1190 return ((osMutexId_t)mutex);
1193 osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
1194 SemaphoreHandle_t mutex;
1198 mutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1200 rmtx = (uint32_t)mutex_id & 1U;
1207 else if (mutex == NULL) {
1208 stat = osErrorParameter;
1212 if (xSemaphoreTakeRecursive (mutex, timeout) != pdPASS) {
1213 if (timeout != 0U) {
1214 stat = osErrorTimeout;
1216 stat = osErrorResource;
1221 if (xSemaphoreTake (mutex, timeout) != pdPASS) {
1222 if (timeout != 0U) {
1223 stat = osErrorTimeout;
1225 stat = osErrorResource;
1234 osStatus_t osMutexRelease (osMutexId_t mutex_id) {
1235 SemaphoreHandle_t mutex;
1239 mutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1241 rmtx = (uint32_t)mutex_id & 1U;
1248 else if (mutex == NULL) {
1249 stat = osErrorParameter;
1253 if (xSemaphoreGiveRecursive (mutex) != pdPASS) {
1254 stat = osErrorResource;
1258 if (xSemaphoreGive (mutex) != pdPASS) {
1259 stat = osErrorResource;
1267 osThreadId_t osMutexGetOwner (osMutexId_t mutex_id) {
1268 SemaphoreHandle_t mutex;
1271 mutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1273 if (IS_IRQ() || (mutex == NULL)) {
1276 owner = (osThreadId_t)xSemaphoreGetMutexHolder (mutex);
1282 osStatus_t osMutexDelete (osMutexId_t mutex_id) {
1284 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1285 SemaphoreHandle_t mutex;
1287 mutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1292 else if (mutex == NULL) {
1293 stat = osErrorParameter;
1297 vSemaphoreDelete (mutex);
1306 /*---------------------------------------------------------------------------*/
1308 osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) {
1309 SemaphoreHandle_t h;
1314 if (!IS_IRQ() && (max_count > 0U) && (initial_count <= max_count)) {
1318 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
1322 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1332 if (max_count == 1U) {
1334 h = xSemaphoreCreateBinaryStatic ((StaticSemaphore_t *)attr->cb_mem);
1337 h = xSemaphoreCreateBinary();
1340 if ((h != NULL) && (initial_count != 0U)) {
1341 if (xSemaphoreGive (h) != pdPASS) {
1342 vSemaphoreDelete (h);
1349 h = xSemaphoreCreateCountingStatic (max_count, initial_count, (StaticSemaphore_t *)attr->cb_mem);
1352 h = xSemaphoreCreateCounting (max_count, initial_count);
1361 osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) {
1366 if (semaphore_id == NULL) {
1367 stat = osErrorParameter;
1369 else if (IS_IRQ()) {
1370 if (timeout != 0U) {
1371 stat = osErrorParameter;
1374 if (xSemaphoreTakeFromISR ((SemaphoreHandle_t)semaphore_id, NULL) != pdPASS) {
1375 stat = osErrorResource;
1380 if (xSemaphoreTake ((SemaphoreHandle_t)semaphore_id, (TickType_t)timeout) != pdPASS) {
1381 if (timeout != 0U) {
1382 stat = osErrorTimeout;
1384 stat = osErrorResource;
1392 osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id) {
1397 if (semaphore_id == NULL) {
1398 stat = osErrorParameter;
1400 else if (IS_IRQ()) {
1401 if (xSemaphoreGiveFromISR ((SemaphoreHandle_t)semaphore_id, NULL) != pdTRUE) {
1402 stat = osErrorResource;
1406 if (xSemaphoreGive ((SemaphoreHandle_t)semaphore_id) != pdPASS) {
1407 stat = osErrorResource;
1414 uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id) {
1417 if (semaphore_id == NULL) {
1420 else if (IS_IRQ()) {
1421 count = uxQueueMessagesWaitingFromISR ((QueueHandle_t)semaphore_id);
1423 count = (uint32_t)uxSemaphoreGetCount ((SemaphoreHandle_t)semaphore_id);
1429 osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id) {
1432 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1436 else if (semaphore_id == NULL) {
1437 stat = osErrorParameter;
1441 vSemaphoreDelete ((SemaphoreHandle_t)semaphore_id);
1450 /*---------------------------------------------------------------------------*/
1452 osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) {
1458 if (!IS_IRQ() && (msg_count > 0U) && (msg_size > 0U)) {
1462 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticQueue_t)) &&
1463 (attr->mq_mem != NULL) && (attr->mq_size >= (msg_count * msg_size))) {
1467 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) &&
1468 (attr->mq_mem == NULL) && (attr->mq_size == 0U)) {
1478 h = xQueueCreateStatic (msg_count, msg_size, attr->mq_mem, attr->cb_mem);
1482 h = xQueueCreate (msg_count, msg_size);
1487 return ((osMessageQueueId_t)h);
1490 osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) {
1493 (void)msg_prio; /* Message priority is ignored */
1498 if ((mq_id == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
1499 stat = osErrorParameter;
1502 if (xQueueSendToBackFromISR ((QueueHandle_t)mq_id, msg_ptr, NULL) != pdTRUE) {
1503 stat = osErrorResource;
1508 if ((mq_id == NULL) || (msg_ptr == NULL)) {
1509 stat = osErrorParameter;
1512 if (xQueueSendToBack ((QueueHandle_t)mq_id, msg_ptr, (TickType_t)timeout) != pdPASS) {
1513 if (timeout != 0U) {
1514 stat = osErrorTimeout;
1516 stat = osErrorResource;
1525 osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) {
1528 (void)msg_prio; /* Message priority is ignored */
1533 if ((mq_id == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
1534 stat = osErrorParameter;
1537 if (xQueueReceiveFromISR ((QueueHandle_t)mq_id, msg_ptr, NULL) != pdPASS) {
1538 stat = osErrorResource;
1543 if ((mq_id == NULL) || (msg_ptr == NULL)) {
1544 stat = osErrorParameter;
1547 if (xQueueReceive ((QueueHandle_t)mq_id, msg_ptr, (TickType_t)timeout) != pdPASS) {
1548 if (timeout != 0U) {
1549 stat = osErrorTimeout;
1551 stat = osErrorResource;
1560 uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id) {
1561 StaticQueue_t *mq = (StaticQueue_t *)mq_id;
1567 /* capacity = pxQueue->uxLength */
1568 capacity = mq->uxDummy4[1];
1574 uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id) {
1575 StaticQueue_t *mq = (StaticQueue_t *)mq_id;
1581 /* size = pxQueue->uxItemSize */
1582 size = mq->uxDummy4[2];
1588 uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) {
1591 if (mq_id == NULL) {
1594 else if (IS_IRQ()) {
1595 count = uxQueueMessagesWaitingFromISR ((QueueHandle_t)mq_id);
1598 count = uxQueueMessagesWaiting ((QueueHandle_t)mq_id);
1601 return ((uint32_t)count);
1604 uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) {
1605 StaticQueue_t *mq = (StaticQueue_t *)mq_id;
1612 else if (IS_IRQ()) {
1613 isrm = taskENTER_CRITICAL_FROM_ISR();
1615 /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */
1616 space = mq->uxDummy4[1] - mq->uxDummy4[0];
1618 taskEXIT_CRITICAL_FROM_ISR(isrm);
1621 space = (uint32_t)uxQueueSpacesAvailable ((QueueHandle_t)mq);
1627 osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id) {
1633 else if (mq_id == NULL) {
1634 stat = osErrorParameter;
1638 (void)xQueueReset ((QueueHandle_t)mq_id);
1644 osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) {
1647 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1651 else if (mq_id == NULL) {
1652 stat = osErrorParameter;
1656 vQueueDelete ((QueueHandle_t)mq_id);
1665 /*---------------------------------------------------------------------------*/
1667 /* Callback function prototypes */
1668 extern void vApplicationIdleHook (void);
1669 extern void vApplicationTickHook (void);
1670 extern void vApplicationMallocFailedHook (void);
1671 extern void vApplicationDaemonTaskStartupHook (void);
1672 extern void vApplicationStackOverflowHook (TaskHandle_t xTask, signed char *pcTaskName);
1675 Dummy implementation of the callback function vApplicationIdleHook().
1677 #if (configUSE_IDLE_HOOK == 1)
1678 __WEAK void vApplicationIdleHook (void){}
1682 Dummy implementation of the callback function vApplicationTickHook().
1684 #if (configUSE_TICK_HOOK == 1)
1685 __WEAK void vApplicationTickHook (void){}
1689 Dummy implementation of the callback function vApplicationMallocFailedHook().
1691 #if (configUSE_MALLOC_FAILED_HOOK == 1)
1692 __WEAK void vApplicationMallocFailedHook (void){}
1696 Dummy implementation of the callback function vApplicationDaemonTaskStartupHook().
1698 #if (configUSE_DAEMON_TASK_STARTUP_HOOK == 1)
1699 __WEAK void vApplicationDaemonTaskStartupHook (void){}
1703 Dummy implementation of the callback function vApplicationStackOverflowHook().
1705 #if (configCHECK_FOR_STACK_OVERFLOW > 0)
1706 __WEAK void vApplicationStackOverflowHook (TaskHandle_t xTask, signed char *pcTaskName) {
1712 /*---------------------------------------------------------------------------*/
1714 /* External Idle and Timer task static memory allocation functions */
1715 extern void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize);
1716 extern void vApplicationGetTimerTaskMemory (StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize);
1718 /* Idle task control block and stack */
1719 static StaticTask_t Idle_TCB;
1720 static StackType_t Idle_Stack[configMINIMAL_STACK_SIZE];
1722 /* Timer task control block and stack */
1723 static StaticTask_t Timer_TCB;
1724 static StackType_t Timer_Stack[configTIMER_TASK_STACK_DEPTH];
1727 vApplicationGetIdleTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
1728 equals to 1 and is required for static memory allocation support.
1730 void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {
1731 *ppxIdleTaskTCBBuffer = &Idle_TCB;
1732 *ppxIdleTaskStackBuffer = &Idle_Stack[0];
1733 *pulIdleTaskStackSize = (uint32_t)configMINIMAL_STACK_SIZE;
1737 vApplicationGetTimerTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
1738 equals to 1 and is required for static memory allocation support.
1740 void vApplicationGetTimerTaskMemory (StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) {
1741 *ppxTimerTaskTCBBuffer = &Timer_TCB;
1742 *ppxTimerTaskStackBuffer = &Timer_Stack[0];
1743 *pulTimerTaskStackSize = (uint32_t)configTIMER_TASK_STACK_DEPTH;