]> begriffs open source - cmsis-freertos/blob - CMSIS/RTOS2/FreeRTOS/Source/cmsis_os2.c
osEventFlagsWait: Fix flag comparison
[cmsis-freertos] / CMSIS / RTOS2 / FreeRTOS / Source / cmsis_os2.c
1 /* --------------------------------------------------------------------------
2  * Copyright (c) 2013-2019 Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
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
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  *      Name:    cmsis_os2.c
19  *      Purpose: CMSIS RTOS2 wrapper for FreeRTOS
20  *
21  *---------------------------------------------------------------------------*/
22
23 #include <string.h>
24
25 #include "RTE_Components.h"             // Component selection
26
27 #include "cmsis_os2.h"                  // ::CMSIS:RTOS2
28 #include "cmsis_compiler.h"
29 #include "os_tick.h"
30
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
35
36 /*---------------------------------------------------------------------------*/
37 #ifndef __ARM_ARCH_6M__
38   #define __ARM_ARCH_6M__         0
39 #endif
40 #ifndef __ARM_ARCH_7M__
41   #define __ARM_ARCH_7M__         0
42 #endif
43 #ifndef __ARM_ARCH_7EM__
44   #define __ARM_ARCH_7EM__        0
45 #endif
46 #ifndef __ARM_ARCH_8M_MAIN__
47   #define __ARM_ARCH_8M_MAIN__    0
48 #endif
49 #ifndef __ARM_ARCH_7A__
50   #define __ARM_ARCH_7A__         0
51 #endif
52
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)
60 /* CPSR mask bits */
61 #define CPSR_MASKBIT_I            0x80U
62
63 #define IS_IRQ_MASKED()           ((__get_CPSR() & CPSR_MASKBIT_I) != 0U)
64 #else
65 #define IS_IRQ_MASKED()           (__get_PRIMASK() != 0U)
66 #endif
67
68 #if    (__ARM_ARCH_7A__      == 1U)
69 /* CPSR mode bitmasks */
70 #define CPSR_MODE_USER            0x10U
71 #define CPSR_MODE_SYSTEM          0x1FU
72
73 #define IS_IRQ_MODE()             ((__get_mode() != CPSR_MODE_USER) && (__get_mode() != CPSR_MODE_SYSTEM))
74 #else
75 #define IS_IRQ_MODE()             (__get_IPSR() != 0U)
76 #endif
77
78 #define IS_IRQ()                  (IS_IRQ_MODE() || (IS_IRQ_MASKED() && (KernelState == osKernelRunning)))
79
80 /* Limits */
81 #define MAX_BITS_TASK_NOTIFY      31U
82 #define MAX_BITS_EVENT_GROUPS     24U
83
84 #define THREAD_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_TASK_NOTIFY)  - 1U))
85 #define EVENT_FLAGS_INVALID_BITS  (~((1UL << MAX_BITS_EVENT_GROUPS) - 1U))
86
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))
91
92 #define KERNEL_ID                 ("FreeRTOS " tskKERNEL_VERSION_NUMBER)
93
94 /* Timer callback information structure definition */
95 typedef struct {
96   osTimerFunc_t func;
97   void         *arg;
98 } TimerCallback_t;
99
100 /* Kernel initialization state */
101 static osKernelState_t KernelState = osKernelInactive;
102
103 /*
104   Heap region definition used by heap_5 variant
105
106   Define configAPPLICATION_ALLOCATED_HEAP as nonzero value in FreeRTOSConfig.h if
107   heap regions are already defined and vPortDefineHeapRegions is called in application.
108
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.
112 */
113 #if defined(RTE_RTOS_FreeRTOS_HEAP_5)
114 #if (configAPPLICATION_ALLOCATED_HEAP == 0)
115   /*
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
119     HeapRegion_t array.
120   */
121   #define HEAP_5_REGION_SETUP   1
122   
123   #ifndef configHEAP_5_REGIONS
124     #define configHEAP_5_REGIONS xHeapRegions
125
126     static uint8_t ucHeap[configTOTAL_HEAP_SIZE];
127
128     static HeapRegion_t xHeapRegions[] = {
129       { ucHeap, configTOTAL_HEAP_SIZE },
130       { NULL,   0                     }
131     };
132   #else
133     /* Global definition is provided to override default heap array */
134     extern HeapRegion_t configHEAP_5_REGIONS[];
135   #endif
136 #else
137   /*
138     The application already defined the array used for the FreeRTOS heap and
139     called vPortDefineHeapRegions to initialize heap.
140   */
141   #define HEAP_5_REGION_SETUP   0
142 #endif /* configAPPLICATION_ALLOCATED_HEAP */
143 #endif /* RTE_RTOS_FreeRTOS_HEAP_5 */
144
145 #if defined(SysTick)
146 #undef SysTick_Handler
147
148 /* CMSIS SysTick interrupt handler prototype */
149 extern void SysTick_Handler     (void);
150 /* FreeRTOS tick timer interrupt handler prototype */
151 extern void xPortSysTickHandler (void);
152
153 /*
154   SysTick handler implementation that also clears overflow flag.
155 */
156 void SysTick_Handler (void) {
157   /* Clear overflow flag */
158   SysTick->CTRL;
159
160   if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
161     /* Call tick handler */
162     xPortSysTickHandler();
163   }
164 }
165 #endif /* SysTick */
166
167 /*
168   Setup SVC to reset value.
169 */
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);
176 #endif
177 }
178
179 /*---------------------------------------------------------------------------*/
180
181 osStatus_t osKernelInitialize (void) {
182   osStatus_t stat;
183
184   if (IS_IRQ()) {
185     stat = osErrorISR;
186   }
187   else {
188     if (KernelState == osKernelInactive) {
189       #if defined(RTE_Compiler_EventRecorder)
190         EvrFreeRTOSSetup(0U);
191       #endif
192       #if defined(RTE_RTOS_FreeRTOS_HEAP_5) && (HEAP_5_REGION_SETUP == 1)
193         vPortDefineHeapRegions (configHEAP_5_REGIONS);
194       #endif
195       KernelState = osKernelReady;
196       stat = osOK;
197     } else {
198       stat = osError;
199     }
200   }
201
202   return (stat);
203 }
204
205 osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) {
206
207   if (version != NULL) {
208     /* Version encoding is major.minor.rev: mmnnnrrrr dec */
209     version->api    = KERNEL_VERSION;
210     version->kernel = KERNEL_VERSION;
211   }
212
213   if ((id_buf != NULL) && (id_size != 0U)) {
214     if (id_size > sizeof(KERNEL_ID)) {
215       id_size = sizeof(KERNEL_ID);
216     }
217     memcpy(id_buf, KERNEL_ID, id_size);
218   }
219
220   return (osOK);
221 }
222
223 osKernelState_t osKernelGetState (void) {
224   osKernelState_t state;
225
226   switch (xTaskGetSchedulerState()) {
227     case taskSCHEDULER_RUNNING:
228       state = osKernelRunning;
229       break;
230
231     case taskSCHEDULER_SUSPENDED:
232       state = osKernelLocked;
233       break;
234
235     case taskSCHEDULER_NOT_STARTED:
236     default:
237       if (KernelState == osKernelReady) {
238         state = osKernelReady;
239       } else {
240         state = osKernelInactive;
241       }
242       break;
243   }
244
245   return (state);
246 }
247
248 osStatus_t osKernelStart (void) {
249   osStatus_t stat;
250
251   if (IS_IRQ()) {
252     stat = osErrorISR;
253   }
254   else {
255     if (KernelState == osKernelReady) {
256       /* Ensure SVC priority is at the reset value */
257       SVC_Setup();
258       /* Change state to enable IRQ masking check */
259       KernelState = osKernelRunning;
260       /* Start the kernel scheduler */
261       vTaskStartScheduler();
262       stat = osOK;
263     } else {
264       stat = osError;
265     }
266   }
267
268   return (stat);
269 }
270
271 int32_t osKernelLock (void) {
272   int32_t lock;
273
274   if (IS_IRQ()) {
275     lock = (int32_t)osErrorISR;
276   }
277   else {
278     switch (xTaskGetSchedulerState()) {
279       case taskSCHEDULER_SUSPENDED:
280         lock = 1;
281         break;
282
283       case taskSCHEDULER_RUNNING:
284         vTaskSuspendAll();
285         lock = 0;
286         break;
287
288       case taskSCHEDULER_NOT_STARTED:
289       default:
290         lock = (int32_t)osError;
291         break;
292     }
293   }
294
295   return (lock);
296 }
297
298 int32_t osKernelUnlock (void) {
299   int32_t lock;
300
301   if (IS_IRQ()) {
302     lock = (int32_t)osErrorISR;
303   }
304   else {
305     switch (xTaskGetSchedulerState()) {
306       case taskSCHEDULER_SUSPENDED:
307         lock = 1;
308
309         if (xTaskResumeAll() != pdTRUE) {
310           if (xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED) {
311             lock = (int32_t)osError;
312           }
313         }
314         break;
315
316       case taskSCHEDULER_RUNNING:
317         lock = 0;
318         break;
319
320       case taskSCHEDULER_NOT_STARTED:
321       default:
322         lock = (int32_t)osError;
323         break;
324     }
325   }
326
327   return (lock);
328 }
329
330 int32_t osKernelRestoreLock (int32_t lock) {
331
332   if (IS_IRQ()) {
333     lock = (int32_t)osErrorISR;
334   }
335   else {
336     switch (xTaskGetSchedulerState()) {
337       case taskSCHEDULER_SUSPENDED:
338       case taskSCHEDULER_RUNNING:
339         if (lock == 1) {
340           vTaskSuspendAll();
341         }
342         else {
343           if (lock != 0) {
344             lock = (int32_t)osError;
345           }
346           else {
347             if (xTaskResumeAll() != pdTRUE) {
348               if (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) {
349                 lock = (int32_t)osError;
350               }
351             }
352           }
353         }
354         break;
355
356       case taskSCHEDULER_NOT_STARTED:
357       default:
358         lock = (int32_t)osError;
359         break;
360     }
361   }
362
363   return (lock);
364 }
365
366 uint32_t osKernelGetTickCount (void) {
367   TickType_t ticks;
368
369   if (IS_IRQ()) {
370     ticks = xTaskGetTickCountFromISR();
371   } else {
372     ticks = xTaskGetTickCount();
373   }
374
375   return (ticks);
376 }
377
378 uint32_t osKernelGetTickFreq (void) {
379   return (configTICK_RATE_HZ);
380 }
381
382 uint32_t osKernelGetSysTimerCount (void) {
383   uint32_t irqmask = IS_IRQ_MASKED();
384   TickType_t ticks;
385   uint32_t val;
386
387   __disable_irq();
388
389   ticks = xTaskGetTickCount();
390   val   = OS_Tick_GetCount();
391
392   if (OS_Tick_GetOverflow() != 0U) {
393     val = OS_Tick_GetCount();
394     ticks++;
395   }
396   val += ticks * OS_Tick_GetInterval();
397
398   if (irqmask == 0U) {
399     __enable_irq();
400   }
401
402   return (val);
403 }
404
405 uint32_t osKernelGetSysTimerFreq (void) {
406   return (configCPU_CLOCK_HZ);
407 }
408
409 /*---------------------------------------------------------------------------*/
410
411 osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) {
412   const char *name;
413   uint32_t stack;
414   TaskHandle_t hTask;
415   UBaseType_t prio;
416   int32_t mem;
417
418   hTask = NULL;
419
420   if (!IS_IRQ() && (func != NULL)) {
421     stack = configMINIMAL_STACK_SIZE;
422     prio  = (UBaseType_t)osPriorityNormal;
423
424     name = NULL;
425     mem  = -1;
426
427     if (attr != NULL) {
428       if (attr->name != NULL) {
429         name = attr->name;
430       }
431       if (attr->priority != osPriorityNone) {
432         prio = (UBaseType_t)attr->priority;
433       }
434
435       if ((prio < osPriorityIdle) || (prio > osPriorityISR) || ((attr->attr_bits & osThreadJoinable) == osThreadJoinable)) {
436         return (NULL);
437       }
438
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);
443       }
444
445       if ((attr->cb_mem    != NULL) && (attr->cb_size    >= sizeof(StaticTask_t)) &&
446           (attr->stack_mem != NULL) && (attr->stack_size >  0U)) {
447         mem = 1;
448       }
449       else {
450         if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) && (attr->stack_mem == NULL)) {
451           mem = 0;
452         }
453       }
454     }
455     else {
456       mem = 0;
457     }
458
459     if (mem == 1) {
460       hTask = xTaskCreateStatic ((TaskFunction_t)func, name, stack, argument, prio, (StackType_t  *)attr->stack_mem,
461                                                                                     (StaticTask_t *)attr->cb_mem);
462     }
463     else {
464       if (mem == 0) {
465         if (xTaskCreate ((TaskFunction_t)func, name, (uint16_t)stack, argument, prio, &hTask) != pdPASS) {
466           hTask = NULL;
467         }
468       }
469     }
470   }
471
472   return ((osThreadId_t)hTask);
473 }
474
475 const char *osThreadGetName (osThreadId_t thread_id) {
476   TaskHandle_t hTask = (TaskHandle_t)thread_id;
477   const char *name;
478
479   if (IS_IRQ() || (hTask == NULL)) {
480     name = NULL;
481   } else {
482     name = pcTaskGetName (hTask);
483   }
484
485   return (name);
486 }
487
488 osThreadId_t osThreadGetId (void) {
489   osThreadId_t id;
490
491   id = (osThreadId_t)xTaskGetCurrentTaskHandle();
492
493   return (id);
494 }
495
496 osThreadState_t osThreadGetState (osThreadId_t thread_id) {
497   TaskHandle_t hTask = (TaskHandle_t)thread_id;
498   osThreadState_t state;
499
500   if (IS_IRQ() || (hTask == NULL)) {
501     state = osThreadError;
502   }
503   else {
504     switch (eTaskGetState (hTask)) {
505       case eRunning:   state = osThreadRunning;    break;
506       case eReady:     state = osThreadReady;      break;
507       case eBlocked:
508       case eSuspended: state = osThreadBlocked;    break;
509       case eDeleted:   state = osThreadTerminated; break;
510       case eInvalid:
511       default:         state = osThreadError;      break;
512     }
513   }
514
515   return (state);
516 }
517
518 uint32_t osThreadGetStackSpace (osThreadId_t thread_id) {
519   TaskHandle_t hTask = (TaskHandle_t)thread_id;
520   uint32_t sz;
521
522   if (IS_IRQ() || (hTask == NULL)) {
523     sz = 0U;
524   } else {
525     sz = (uint32_t)(uxTaskGetStackHighWaterMark(hTask) * sizeof(StackType_t));
526   }
527
528   return (sz);
529 }
530
531 osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) {
532   TaskHandle_t hTask = (TaskHandle_t)thread_id;
533   osStatus_t stat;
534
535   if (IS_IRQ()) {
536     stat = osErrorISR;
537   }
538   else if ((hTask == NULL) || (priority < osPriorityIdle) || (priority > osPriorityISR)) {
539     stat = osErrorParameter;
540   }
541   else {
542     stat = osOK;
543     vTaskPrioritySet (hTask, (UBaseType_t)priority);
544   }
545
546   return (stat);
547 }
548
549 osPriority_t osThreadGetPriority (osThreadId_t thread_id) {
550   TaskHandle_t hTask = (TaskHandle_t)thread_id;
551   osPriority_t prio;
552
553   if (IS_IRQ() || (hTask == NULL)) {
554     prio = osPriorityError;
555   } else {
556     prio = (osPriority_t)uxTaskPriorityGet (hTask);
557   }
558
559   return (prio);
560 }
561
562 osStatus_t osThreadYield (void) {
563   osStatus_t stat;
564
565   if (IS_IRQ()) {
566     stat = osErrorISR;
567   } else {
568     stat = osOK;
569     taskYIELD();
570   }
571
572   return (stat);
573 }
574
575 osStatus_t osThreadSuspend (osThreadId_t thread_id) {
576   TaskHandle_t hTask = (TaskHandle_t)thread_id;
577   osStatus_t stat;
578
579   if (IS_IRQ()) {
580     stat = osErrorISR;
581   }
582   else if (hTask == NULL) {
583     stat = osErrorParameter;
584   }
585   else {
586     stat = osOK;
587     vTaskSuspend (hTask);
588   }
589
590   return (stat);
591 }
592
593 osStatus_t osThreadResume (osThreadId_t thread_id) {
594   TaskHandle_t hTask = (TaskHandle_t)thread_id;
595   osStatus_t stat;
596
597   if (IS_IRQ()) {
598     stat = osErrorISR;
599   }
600   else if (hTask == NULL) {
601     stat = osErrorParameter;
602   }
603   else {
604     stat = osOK;
605     vTaskResume (hTask);
606   }
607
608   return (stat);
609 }
610
611 __NO_RETURN void osThreadExit (void) {
612 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
613   vTaskDelete (NULL);
614 #endif
615   for (;;);
616 }
617
618 osStatus_t osThreadTerminate (osThreadId_t thread_id) {
619   TaskHandle_t hTask = (TaskHandle_t)thread_id;
620   osStatus_t stat;
621 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
622   eTaskState tstate;
623
624   if (IS_IRQ()) {
625     stat = osErrorISR;
626   }
627   else if (hTask == NULL) {
628     stat = osErrorParameter;
629   }
630   else {
631     tstate = eTaskGetState (hTask);
632
633     if (tstate != eDeleted) {
634       stat = osOK;
635       vTaskDelete (hTask);
636     } else {
637       stat = osErrorResource;
638     }
639   }
640 #else
641   stat = osError;
642 #endif
643
644   return (stat);
645 }
646
647 uint32_t osThreadGetCount (void) {
648   uint32_t count;
649
650   if (IS_IRQ()) {
651     count = 0U;
652   } else {
653     count = uxTaskGetNumberOfTasks();
654   }
655
656   return (count);
657 }
658
659 uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) {
660   uint32_t i, count;
661   TaskStatus_t *task;
662
663   if (IS_IRQ() || (thread_array == NULL) || (array_items == 0U)) {
664     count = 0U;
665   } else {
666     vTaskSuspendAll();
667
668     count = uxTaskGetNumberOfTasks();
669     task  = pvPortMalloc (count * sizeof(TaskStatus_t));
670
671     if (task != NULL) {
672       count = uxTaskGetSystemState (task, count, NULL);
673
674       for (i = 0U; (i < count) && (i < array_items); i++) {
675         thread_array[i] = (osThreadId_t)task[i].xHandle;
676       }
677       count = i;
678     }
679     (void)xTaskResumeAll();
680
681     vPortFree (task);
682   }
683
684   return (count);
685 }
686
687 uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) {
688   TaskHandle_t hTask = (TaskHandle_t)thread_id;
689   uint32_t rflags;
690   BaseType_t yield;
691
692   if ((hTask == NULL) || ((flags & THREAD_FLAGS_INVALID_BITS) != 0U)) {
693     rflags = (uint32_t)osErrorParameter;
694   }
695   else {
696     rflags = (uint32_t)osError;
697
698     if (IS_IRQ()) {
699       yield = pdFALSE;
700
701       (void)xTaskNotifyFromISR (hTask, flags, eSetBits, &yield);
702       (void)xTaskNotifyAndQueryFromISR (hTask, 0, eNoAction, &rflags, NULL);
703
704       portYIELD_FROM_ISR (yield);
705     }
706     else {
707       (void)xTaskNotify (hTask, flags, eSetBits);
708       (void)xTaskNotifyAndQuery (hTask, 0, eNoAction, &rflags);
709     }
710   }
711   /* Return flags after setting */
712   return (rflags);
713 }
714
715 uint32_t osThreadFlagsClear (uint32_t flags) {
716   TaskHandle_t hTask;
717   uint32_t rflags, cflags;
718
719   if (IS_IRQ()) {
720     rflags = (uint32_t)osErrorISR;
721   }
722   else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) {
723     rflags = (uint32_t)osErrorParameter;
724   }
725   else {
726     hTask = xTaskGetCurrentTaskHandle();
727
728     if (xTaskNotifyAndQuery (hTask, 0, eNoAction, &cflags) == pdPASS) {
729       rflags = cflags;
730       cflags &= ~flags;
731
732       if (xTaskNotify (hTask, cflags, eSetValueWithOverwrite) != pdPASS) {
733         rflags = (uint32_t)osError;
734       }
735     }
736     else {
737       rflags = (uint32_t)osError;
738     }
739   }
740
741   /* Return flags before clearing */
742   return (rflags);
743 }
744
745 uint32_t osThreadFlagsGet (void) {
746   TaskHandle_t hTask;
747   uint32_t rflags;
748
749   if (IS_IRQ()) {
750     rflags = (uint32_t)osErrorISR;
751   }
752   else {
753     hTask = xTaskGetCurrentTaskHandle();
754
755     if (xTaskNotifyAndQuery (hTask, 0, eNoAction, &rflags) != pdPASS) {
756       rflags = (uint32_t)osError;
757     }
758   }
759
760   return (rflags);
761 }
762
763 uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) {
764   uint32_t rflags, nval;
765   uint32_t clear;
766   TickType_t t0, td, tout;
767   BaseType_t rval;
768
769   if (IS_IRQ()) {
770     rflags = (uint32_t)osErrorISR;
771   }
772   else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) {
773     rflags = (uint32_t)osErrorParameter;
774   }
775   else {
776     if ((options & osFlagsNoClear) == osFlagsNoClear) {
777       clear = 0U;
778     } else {
779       clear = flags;
780     }
781
782     rflags = 0U;
783     tout   = timeout;
784
785     t0 = xTaskGetTickCount();
786     do {
787       rval = xTaskNotifyWait (0, clear, &nval, tout);
788
789       if (rval == pdPASS) {
790         rflags &= flags;
791         rflags |= nval;
792
793         if ((options & osFlagsWaitAll) == osFlagsWaitAll) {
794           if ((flags & rflags) == flags) {
795             break;
796           } else {
797             if (timeout == 0U) {
798               rflags = (uint32_t)osErrorResource;
799               break;
800             }
801           }
802         }
803         else {
804           if ((flags & rflags) != 0) {
805             break;
806           } else {
807             if (timeout == 0U) {
808               rflags = (uint32_t)osErrorResource;
809               break;
810             }
811           }
812         }
813
814         /* Update timeout */
815         td = xTaskGetTickCount() - t0;
816
817         if (td > tout) {
818           tout  = 0;
819         } else {
820           tout -= td;
821         }
822       }
823       else {
824         if (timeout == 0) {
825           rflags = (uint32_t)osErrorResource;
826         } else {
827           rflags = (uint32_t)osErrorTimeout;
828         }
829       }
830     }
831     while (rval != pdFAIL);
832   }
833
834   /* Return flags before clearing */
835   return (rflags);
836 }
837
838 osStatus_t osDelay (uint32_t ticks) {
839   osStatus_t stat;
840
841   if (IS_IRQ()) {
842     stat = osErrorISR;
843   }
844   else {
845     stat = osOK;
846
847     if (ticks != 0U) {
848       vTaskDelay(ticks);
849     }
850   }
851
852   return (stat);
853 }
854
855 osStatus_t osDelayUntil (uint32_t ticks) {
856   TickType_t tcnt, delay;
857   osStatus_t stat;
858
859   if (IS_IRQ()) {
860     stat = osErrorISR;
861   }
862   else {
863     stat = osOK;
864     tcnt = xTaskGetTickCount();
865
866     /* Determine remaining number of ticks to delay */
867     delay = (TickType_t)ticks - tcnt;
868
869     /* Check if target tick has not expired */
870     if((delay != 0U) && (0 == (delay >> (8 * sizeof(TickType_t) - 1)))) {
871       vTaskDelayUntil (&tcnt, delay);
872     }
873     else
874     {
875       /* No delay or already expired */
876       stat = osErrorParameter;
877     }
878   }
879
880   return (stat);
881 }
882
883 /*---------------------------------------------------------------------------*/
884
885 static void TimerCallback (TimerHandle_t hTimer) {
886   TimerCallback_t *callb;
887
888   callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer);
889
890   if (callb != NULL) {
891     callb->func (callb->arg);
892   }
893 }
894
895 osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) {
896   const char *name;
897   TimerHandle_t hTimer;
898   TimerCallback_t *callb;
899   UBaseType_t reload;
900   int32_t mem;
901
902   hTimer = NULL;
903
904   if (!IS_IRQ() && (func != NULL)) {
905     /* Allocate memory to store callback function and argument */
906     callb = pvPortMalloc (sizeof(TimerCallback_t));
907
908     if (callb != NULL) {
909       callb->func = func;
910       callb->arg  = argument;
911
912       if (type == osTimerOnce) {
913         reload = pdFALSE;
914       } else {
915         reload = pdTRUE;
916       }
917
918       mem  = -1;
919       name = NULL;
920
921       if (attr != NULL) {
922         if (attr->name != NULL) {
923           name = attr->name;
924         }
925
926         if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTimer_t))) {
927           mem = 1;
928         }
929         else {
930           if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
931             mem = 0;
932           }
933         }
934       }
935       else {
936         mem = 0;
937       }
938
939       if (mem == 1) {
940         hTimer = xTimerCreateStatic (name, 1, reload, callb, TimerCallback, (StaticTimer_t *)attr->cb_mem);
941       }
942       else {
943         if (mem == 0) {
944           hTimer = xTimerCreate (name, 1, reload, callb, TimerCallback);
945         }
946       }
947     }
948   }
949
950   return ((osTimerId_t)hTimer);
951 }
952
953 const char *osTimerGetName (osTimerId_t timer_id) {
954   TimerHandle_t hTimer = (TimerHandle_t)timer_id;
955   const char *p;
956
957   if (IS_IRQ() || (hTimer == NULL)) {
958     p = NULL;
959   } else {
960     p = pcTimerGetName (hTimer);
961   }
962
963   return (p);
964 }
965
966 osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks) {
967   TimerHandle_t hTimer = (TimerHandle_t)timer_id;
968   osStatus_t stat;
969
970   if (IS_IRQ()) {
971     stat = osErrorISR;
972   }
973   else if (hTimer == NULL) {
974     stat = osErrorParameter;
975   }
976   else {
977     if (xTimerChangePeriod (hTimer, ticks, 0) == pdPASS) {
978       stat = osOK;
979     } else {
980       stat = osErrorResource;
981     }
982   }
983
984   return (stat);
985 }
986
987 osStatus_t osTimerStop (osTimerId_t timer_id) {
988   TimerHandle_t hTimer = (TimerHandle_t)timer_id;
989   osStatus_t stat;
990
991   if (IS_IRQ()) {
992     stat = osErrorISR;
993   }
994   else if (hTimer == NULL) {
995     stat = osErrorParameter;
996   }
997   else {
998     if (xTimerIsTimerActive (hTimer) == pdFALSE) {
999       stat = osErrorResource;
1000     }
1001     else {
1002       if (xTimerStop (hTimer, 0) == pdPASS) {
1003         stat = osOK;
1004       } else {
1005         stat = osError;
1006       }
1007     }
1008   }
1009
1010   return (stat);
1011 }
1012
1013 uint32_t osTimerIsRunning (osTimerId_t timer_id) {
1014   TimerHandle_t hTimer = (TimerHandle_t)timer_id;
1015   uint32_t running;
1016
1017   if (IS_IRQ() || (hTimer == NULL)) {
1018     running = 0U;
1019   } else {
1020     running = (uint32_t)xTimerIsTimerActive (hTimer);
1021   }
1022
1023   return (running);
1024 }
1025
1026 osStatus_t osTimerDelete (osTimerId_t timer_id) {
1027   TimerHandle_t hTimer = (TimerHandle_t)timer_id;
1028   osStatus_t stat;
1029 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1030   TimerCallback_t *callb;
1031
1032   if (IS_IRQ()) {
1033     stat = osErrorISR;
1034   }
1035   else if (hTimer == NULL) {
1036     stat = osErrorParameter;
1037   }
1038   else {
1039     callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer);
1040
1041     if (xTimerDelete (hTimer, 0) == pdPASS) {
1042       vPortFree (callb);
1043       stat = osOK;
1044     } else {
1045       stat = osErrorResource;
1046     }
1047   }
1048 #else
1049   stat = osError;
1050 #endif
1051
1052   return (stat);
1053 }
1054
1055 /*---------------------------------------------------------------------------*/
1056
1057 osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr) {
1058   EventGroupHandle_t hEventGroup;
1059   int32_t mem;
1060
1061   hEventGroup = NULL;
1062
1063   if (!IS_IRQ()) {
1064     mem = -1;
1065
1066     if (attr != NULL) {
1067       if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticEventGroup_t))) {
1068         mem = 1;
1069       }
1070       else {
1071         if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1072           mem = 0;
1073         }
1074       }
1075     }
1076     else {
1077       mem = 0;
1078     }
1079
1080     if (mem == 1) {
1081       hEventGroup = xEventGroupCreateStatic (attr->cb_mem);
1082     }
1083     else {
1084       if (mem == 0) {
1085         hEventGroup = xEventGroupCreate();
1086       }
1087     }
1088   }
1089
1090   return ((osEventFlagsId_t)hEventGroup);
1091 }
1092
1093 uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) {
1094   EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1095   uint32_t rflags;
1096   BaseType_t yield;
1097
1098   if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1099     rflags = (uint32_t)osErrorParameter;
1100   }
1101   else if (IS_IRQ()) {
1102     yield = pdFALSE;
1103
1104     if (xEventGroupSetBitsFromISR (hEventGroup, (EventBits_t)flags, &yield) == pdFAIL) {
1105       rflags = (uint32_t)osErrorResource;
1106     } else {
1107       rflags = flags;
1108       portYIELD_FROM_ISR (yield);
1109     }
1110   }
1111   else {
1112     rflags = xEventGroupSetBits (hEventGroup, (EventBits_t)flags);
1113   }
1114
1115   return (rflags);
1116 }
1117
1118 uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) {
1119   EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1120   uint32_t rflags;
1121
1122   if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1123     rflags = (uint32_t)osErrorParameter;
1124   }
1125   else if (IS_IRQ()) {
1126     rflags = xEventGroupGetBitsFromISR (hEventGroup);
1127
1128     if (xEventGroupClearBitsFromISR (hEventGroup, (EventBits_t)flags) == pdFAIL) {
1129       rflags = (uint32_t)osErrorResource;
1130     }
1131   }
1132   else {
1133     rflags = xEventGroupClearBits (hEventGroup, (EventBits_t)flags);
1134   }
1135
1136   return (rflags);
1137 }
1138
1139 uint32_t osEventFlagsGet (osEventFlagsId_t ef_id) {
1140   EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1141   uint32_t rflags;
1142
1143   if (ef_id == NULL) {
1144     rflags = 0U;
1145   }
1146   else if (IS_IRQ()) {
1147     rflags = xEventGroupGetBitsFromISR (hEventGroup);
1148   }
1149   else {
1150     rflags = xEventGroupGetBits (hEventGroup);
1151   }
1152
1153   return (rflags);
1154 }
1155
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;
1160   uint32_t rflags;
1161
1162   if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1163     rflags = (uint32_t)osErrorParameter;
1164   }
1165   else if (IS_IRQ()) {
1166     rflags = (uint32_t)osErrorISR;
1167   }
1168   else {
1169     if (options & osFlagsWaitAll) {
1170       wait_all = pdTRUE;
1171     } else {
1172       wait_all = pdFAIL;
1173     }
1174
1175     if (options & osFlagsNoClear) {
1176       exit_clr = pdFAIL;
1177     } else {
1178       exit_clr = pdTRUE;
1179     }
1180
1181     rflags = xEventGroupWaitBits (hEventGroup, (EventBits_t)flags, exit_clr, wait_all, (TickType_t)timeout);
1182
1183     if (options & osFlagsWaitAll) {
1184       if ((flags & rflags) != flags) {
1185         if (timeout > 0U) {
1186           rflags = (uint32_t)osErrorTimeout;
1187         } else {
1188           rflags = (uint32_t)osErrorResource;
1189         }
1190       }
1191     }
1192     else {
1193       if ((flags & rflags) == 0U) {
1194         if (timeout > 0U) {
1195           rflags = (uint32_t)osErrorTimeout;
1196         } else {
1197           rflags = (uint32_t)osErrorResource;
1198         }
1199       }
1200     }
1201   }
1202
1203   return (rflags);
1204 }
1205
1206 osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id) {
1207   EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1208   osStatus_t stat;
1209
1210 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1211   if (IS_IRQ()) {
1212     stat = osErrorISR;
1213   }
1214   else if (hEventGroup == NULL) {
1215     stat = osErrorParameter;
1216   }
1217   else {
1218     stat = osOK;
1219     vEventGroupDelete (hEventGroup);
1220   }
1221 #else
1222   stat = osError;
1223 #endif
1224
1225   return (stat);
1226 }
1227
1228 /*---------------------------------------------------------------------------*/
1229
1230 osMutexId_t osMutexNew (const osMutexAttr_t *attr) {
1231   SemaphoreHandle_t hMutex;
1232   uint32_t type;
1233   uint32_t rmtx;
1234   int32_t  mem;
1235   #if (configQUEUE_REGISTRY_SIZE > 0)
1236   const char *name;
1237   #endif
1238
1239   hMutex = NULL;
1240
1241   if (!IS_IRQ()) {
1242     if (attr != NULL) {
1243       type = attr->attr_bits;
1244     } else {
1245       type = 0U;
1246     }
1247
1248     if ((type & osMutexRecursive) == osMutexRecursive) {
1249       rmtx = 1U;
1250     } else {
1251       rmtx = 0U;
1252     }
1253
1254     if ((type & osMutexRobust) != osMutexRobust) {
1255       mem = -1;
1256
1257       if (attr != NULL) {
1258         if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
1259           mem = 1;
1260         }
1261         else {
1262           if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1263             mem = 0;
1264           }
1265         }
1266       }
1267       else {
1268         mem = 0;
1269       }
1270
1271       if (mem == 1) {
1272         if (rmtx != 0U) {
1273           hMutex = xSemaphoreCreateRecursiveMutexStatic (attr->cb_mem);
1274         }
1275         else {
1276           hMutex = xSemaphoreCreateMutexStatic (attr->cb_mem);
1277         }
1278       }
1279       else {
1280         if (mem == 0) {
1281           if (rmtx != 0U) {
1282             hMutex = xSemaphoreCreateRecursiveMutex ();
1283           } else {
1284             hMutex = xSemaphoreCreateMutex ();
1285           }
1286         }
1287       }
1288
1289       #if (configQUEUE_REGISTRY_SIZE > 0)
1290       if (hMutex != NULL) {
1291         if (attr != NULL) {
1292           name = attr->name;
1293         } else {
1294           name = NULL;
1295         }
1296         vQueueAddToRegistry (hMutex, name);
1297       }
1298       #endif
1299
1300       if ((hMutex != NULL) && (rmtx != 0U)) {
1301         hMutex = (SemaphoreHandle_t)((uint32_t)hMutex | 1U);
1302       }
1303     }
1304   }
1305
1306   return ((osMutexId_t)hMutex);
1307 }
1308
1309 osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
1310   SemaphoreHandle_t hMutex;
1311   osStatus_t stat;
1312   uint32_t rmtx;
1313
1314   hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1315
1316   rmtx = (uint32_t)mutex_id & 1U;
1317
1318   stat = osOK;
1319
1320   if (IS_IRQ()) {
1321     stat = osErrorISR;
1322   }
1323   else if (hMutex == NULL) {
1324     stat = osErrorParameter;
1325   }
1326   else {
1327     if (rmtx != 0U) {
1328       if (xSemaphoreTakeRecursive (hMutex, timeout) != pdPASS) {
1329         if (timeout != 0U) {
1330           stat = osErrorTimeout;
1331         } else {
1332           stat = osErrorResource;
1333         }
1334       }
1335     }
1336     else {
1337       if (xSemaphoreTake (hMutex, timeout) != pdPASS) {
1338         if (timeout != 0U) {
1339           stat = osErrorTimeout;
1340         } else {
1341           stat = osErrorResource;
1342         }
1343       }
1344     }
1345   }
1346
1347   return (stat);
1348 }
1349
1350 osStatus_t osMutexRelease (osMutexId_t mutex_id) {
1351   SemaphoreHandle_t hMutex;
1352   osStatus_t stat;
1353   uint32_t rmtx;
1354
1355   hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1356
1357   rmtx = (uint32_t)mutex_id & 1U;
1358
1359   stat = osOK;
1360
1361   if (IS_IRQ()) {
1362     stat = osErrorISR;
1363   }
1364   else if (hMutex == NULL) {
1365     stat = osErrorParameter;
1366   }
1367   else {
1368     if (rmtx != 0U) {
1369       if (xSemaphoreGiveRecursive (hMutex) != pdPASS) {
1370         stat = osErrorResource;
1371       }
1372     }
1373     else {
1374       if (xSemaphoreGive (hMutex) != pdPASS) {
1375         stat = osErrorResource;
1376       }
1377     }
1378   }
1379
1380   return (stat);
1381 }
1382
1383 osThreadId_t osMutexGetOwner (osMutexId_t mutex_id) {
1384   SemaphoreHandle_t hMutex;
1385   osThreadId_t owner;
1386
1387   hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1388
1389   if (IS_IRQ() || (hMutex == NULL)) {
1390     owner = NULL;
1391   } else {
1392     owner = (osThreadId_t)xSemaphoreGetMutexHolder (hMutex);
1393   }
1394
1395   return (owner);
1396 }
1397
1398 osStatus_t osMutexDelete (osMutexId_t mutex_id) {
1399   osStatus_t stat;
1400 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1401   SemaphoreHandle_t hMutex;
1402
1403   hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1404
1405   if (IS_IRQ()) {
1406     stat = osErrorISR;
1407   }
1408   else if (hMutex == NULL) {
1409     stat = osErrorParameter;
1410   }
1411   else {
1412     #if (configQUEUE_REGISTRY_SIZE > 0)
1413     vQueueUnregisterQueue (hMutex);
1414     #endif
1415     stat = osOK;
1416     vSemaphoreDelete (hMutex);
1417   }
1418 #else
1419   stat = osError;
1420 #endif
1421
1422   return (stat);
1423 }
1424
1425 /*---------------------------------------------------------------------------*/
1426
1427 osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) {
1428   SemaphoreHandle_t hSemaphore;
1429   int32_t mem;
1430   #if (configQUEUE_REGISTRY_SIZE > 0)
1431   const char *name;
1432   #endif
1433
1434   hSemaphore = NULL;
1435
1436   if (!IS_IRQ() && (max_count > 0U) && (initial_count <= max_count)) {
1437     mem = -1;
1438
1439     if (attr != NULL) {
1440       if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
1441         mem = 1;
1442       }
1443       else {
1444         if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1445           mem = 0;
1446         }
1447       }
1448     }
1449     else {
1450       mem = 0;
1451     }
1452
1453     if (mem != -1) {
1454       if (max_count == 1U) {
1455         if (mem == 1) {
1456           hSemaphore = xSemaphoreCreateBinaryStatic ((StaticSemaphore_t *)attr->cb_mem);
1457         }
1458         else {
1459           hSemaphore = xSemaphoreCreateBinary();
1460         }
1461
1462         if ((hSemaphore != NULL) && (initial_count != 0U)) {
1463           if (xSemaphoreGive (hSemaphore) != pdPASS) {
1464             vSemaphoreDelete (hSemaphore);
1465             hSemaphore = NULL;
1466           }
1467         }
1468       }
1469       else {
1470         if (mem == 1) {
1471           hSemaphore = xSemaphoreCreateCountingStatic (max_count, initial_count, (StaticSemaphore_t *)attr->cb_mem);
1472         }
1473         else {
1474           hSemaphore = xSemaphoreCreateCounting (max_count, initial_count);
1475         }
1476       }
1477       
1478       #if (configQUEUE_REGISTRY_SIZE > 0)
1479       if (hSemaphore != NULL) {
1480         if (attr != NULL) {
1481           name = attr->name;
1482         } else {
1483           name = NULL;
1484         }
1485         vQueueAddToRegistry (hSemaphore, name);
1486       }
1487       #endif
1488     }
1489   }
1490
1491   return ((osSemaphoreId_t)hSemaphore);
1492 }
1493
1494 osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) {
1495   SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
1496   osStatus_t stat;
1497   BaseType_t yield;
1498
1499   stat = osOK;
1500
1501   if (hSemaphore == NULL) {
1502     stat = osErrorParameter;
1503   }
1504   else if (IS_IRQ()) {
1505     if (timeout != 0U) {
1506       stat = osErrorParameter;
1507     }
1508     else {
1509       yield = pdFALSE;
1510
1511       if (xSemaphoreTakeFromISR (hSemaphore, &yield) != pdPASS) {
1512         stat = osErrorResource;
1513       } else {
1514         portYIELD_FROM_ISR (yield);
1515       }
1516     }
1517   }
1518   else {
1519     if (xSemaphoreTake (hSemaphore, (TickType_t)timeout) != pdPASS) {
1520       if (timeout != 0U) {
1521         stat = osErrorTimeout;
1522       } else {
1523         stat = osErrorResource;
1524       }
1525     }
1526   }
1527
1528   return (stat);
1529 }
1530
1531 osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id) {
1532   SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
1533   osStatus_t stat;
1534   BaseType_t yield;
1535
1536   stat = osOK;
1537
1538   if (hSemaphore == NULL) {
1539     stat = osErrorParameter;
1540   }
1541   else if (IS_IRQ()) {
1542     yield = pdFALSE;
1543
1544     if (xSemaphoreGiveFromISR (hSemaphore, &yield) != pdTRUE) {
1545       stat = osErrorResource;
1546     } else {
1547       portYIELD_FROM_ISR (yield);
1548     }
1549   }
1550   else {
1551     if (xSemaphoreGive (hSemaphore) != pdPASS) {
1552       stat = osErrorResource;
1553     }
1554   }
1555
1556   return (stat);
1557 }
1558
1559 uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id) {
1560   SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
1561   uint32_t count;
1562
1563   if (hSemaphore == NULL) {
1564     count = 0U;
1565   }
1566   else if (IS_IRQ()) {
1567     count = uxQueueMessagesWaitingFromISR (hSemaphore);
1568   } else {
1569     count = (uint32_t)uxSemaphoreGetCount (hSemaphore);
1570   }
1571
1572   return (count);
1573 }
1574
1575 osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id) {
1576   SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
1577   osStatus_t stat;
1578
1579 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1580   if (IS_IRQ()) {
1581     stat = osErrorISR;
1582   }
1583   else if (hSemaphore == NULL) {
1584     stat = osErrorParameter;
1585   }
1586   else {
1587     #if (configQUEUE_REGISTRY_SIZE > 0)
1588     vQueueUnregisterQueue (hSemaphore);
1589     #endif
1590
1591     stat = osOK;
1592     vSemaphoreDelete (hSemaphore);
1593   }
1594 #else
1595   stat = osError;
1596 #endif
1597
1598   return (stat);
1599 }
1600
1601 /*---------------------------------------------------------------------------*/
1602
1603 osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) {
1604   QueueHandle_t hQueue;
1605   int32_t mem;
1606   #if (configQUEUE_REGISTRY_SIZE > 0)
1607   const char *name;
1608   #endif
1609
1610   hQueue = NULL;
1611
1612   if (!IS_IRQ() && (msg_count > 0U) && (msg_size > 0U)) {
1613     mem = -1;
1614
1615     if (attr != NULL) {
1616       if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticQueue_t)) &&
1617           (attr->mq_mem != NULL) && (attr->mq_size >= (msg_count * msg_size))) {
1618         mem = 1;
1619       }
1620       else {
1621         if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) &&
1622             (attr->mq_mem == NULL) && (attr->mq_size == 0U)) {
1623           mem = 0;
1624         }
1625       }
1626     }
1627     else {
1628       mem = 0;
1629     }
1630
1631     if (mem == 1) {
1632       hQueue = xQueueCreateStatic (msg_count, msg_size, attr->mq_mem, attr->cb_mem);
1633     }
1634     else {
1635       if (mem == 0) {
1636         hQueue = xQueueCreate (msg_count, msg_size);
1637       }
1638     }
1639
1640     #if (configQUEUE_REGISTRY_SIZE > 0)
1641     if (hQueue != NULL) {
1642       if (attr != NULL) {
1643         name = attr->name;
1644       } else {
1645         name = NULL;
1646       }
1647       vQueueAddToRegistry (hQueue, name);
1648     }
1649     #endif
1650
1651   }
1652
1653   return ((osMessageQueueId_t)hQueue);
1654 }
1655
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;
1658   osStatus_t stat;
1659   BaseType_t yield;
1660
1661   (void)msg_prio; /* Message priority is ignored */
1662
1663   stat = osOK;
1664
1665   if (IS_IRQ()) {
1666     if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
1667       stat = osErrorParameter;
1668     }
1669     else {
1670       yield = pdFALSE;
1671
1672       if (xQueueSendToBackFromISR (hQueue, msg_ptr, &yield) != pdTRUE) {
1673         stat = osErrorResource;
1674       } else {
1675         portYIELD_FROM_ISR (yield);
1676       }
1677     }
1678   }
1679   else {
1680     if ((hQueue == NULL) || (msg_ptr == NULL)) {
1681       stat = osErrorParameter;
1682     }
1683     else {
1684       if (xQueueSendToBack (hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) {
1685         if (timeout != 0U) {
1686           stat = osErrorTimeout;
1687         } else {
1688           stat = osErrorResource;
1689         }
1690       }
1691     }
1692   }
1693
1694   return (stat);
1695 }
1696
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;
1699   osStatus_t stat;
1700   BaseType_t yield;
1701
1702   (void)msg_prio; /* Message priority is ignored */
1703
1704   stat = osOK;
1705
1706   if (IS_IRQ()) {
1707     if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
1708       stat = osErrorParameter;
1709     }
1710     else {
1711       yield = pdFALSE;
1712
1713       if (xQueueReceiveFromISR (hQueue, msg_ptr, &yield) != pdPASS) {
1714         stat = osErrorResource;
1715       } else {
1716         portYIELD_FROM_ISR (yield);
1717       }
1718     }
1719   }
1720   else {
1721     if ((hQueue == NULL) || (msg_ptr == NULL)) {
1722       stat = osErrorParameter;
1723     }
1724     else {
1725       if (xQueueReceive (hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) {
1726         if (timeout != 0U) {
1727           stat = osErrorTimeout;
1728         } else {
1729           stat = osErrorResource;
1730         }
1731       }
1732     }
1733   }
1734
1735   return (stat);
1736 }
1737
1738 uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id) {
1739   StaticQueue_t *mq = (StaticQueue_t *)mq_id;
1740   uint32_t capacity;
1741
1742   if (mq == NULL) {
1743     capacity = 0U;
1744   } else {
1745     /* capacity = pxQueue->uxLength */
1746     capacity = mq->uxDummy4[1];
1747   }
1748
1749   return (capacity);
1750 }
1751
1752 uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id) {
1753   StaticQueue_t *mq = (StaticQueue_t *)mq_id;
1754   uint32_t size;
1755
1756   if (mq == NULL) {
1757     size = 0U;
1758   } else {
1759     /* size = pxQueue->uxItemSize */
1760     size = mq->uxDummy4[2];
1761   }
1762
1763   return (size);
1764 }
1765
1766 uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) {
1767   QueueHandle_t hQueue = (QueueHandle_t)mq_id;
1768   UBaseType_t count;
1769
1770   if (hQueue == NULL) {
1771     count = 0U;
1772   }
1773   else if (IS_IRQ()) {
1774     count = uxQueueMessagesWaitingFromISR (hQueue);
1775   }
1776   else {
1777     count = uxQueueMessagesWaiting (hQueue);
1778   }
1779
1780   return ((uint32_t)count);
1781 }
1782
1783 uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) {
1784   StaticQueue_t *mq = (StaticQueue_t *)mq_id;
1785   uint32_t space;
1786   uint32_t isrm;
1787
1788   if (mq == NULL) {
1789     space = 0U;
1790   }
1791   else if (IS_IRQ()) {
1792     isrm = taskENTER_CRITICAL_FROM_ISR();
1793
1794     /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */
1795     space = mq->uxDummy4[1] - mq->uxDummy4[0];
1796
1797     taskEXIT_CRITICAL_FROM_ISR(isrm);
1798   }
1799   else {
1800     space = (uint32_t)uxQueueSpacesAvailable ((QueueHandle_t)mq);
1801   }
1802
1803   return (space);
1804 }
1805
1806 osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id) {
1807   QueueHandle_t hQueue = (QueueHandle_t)mq_id;
1808   osStatus_t stat;
1809
1810   if (IS_IRQ()) {
1811     stat = osErrorISR;
1812   }
1813   else if (hQueue == NULL) {
1814     stat = osErrorParameter;
1815   }
1816   else {
1817     stat = osOK;
1818     (void)xQueueReset (hQueue);
1819   }
1820
1821   return (stat);
1822 }
1823
1824 osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) {
1825   QueueHandle_t hQueue = (QueueHandle_t)mq_id;
1826   osStatus_t stat;
1827
1828 #ifndef RTE_RTOS_FreeRTOS_HEAP_1
1829   if (IS_IRQ()) {
1830     stat = osErrorISR;
1831   }
1832   else if (hQueue == NULL) {
1833     stat = osErrorParameter;
1834   }
1835   else {
1836     #if (configQUEUE_REGISTRY_SIZE > 0)
1837     vQueueUnregisterQueue (hQueue);
1838     #endif
1839
1840     stat = osOK;
1841     vQueueDelete (hQueue);
1842   }
1843 #else
1844   stat = osError;
1845 #endif
1846
1847   return (stat);
1848 }
1849
1850 /*---------------------------------------------------------------------------*/
1851
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);
1858
1859 /**
1860   Dummy implementation of the callback function vApplicationIdleHook().
1861 */
1862 #if (configUSE_IDLE_HOOK == 1)
1863 __WEAK void vApplicationIdleHook (void){}
1864 #endif
1865
1866 /**
1867   Dummy implementation of the callback function vApplicationTickHook().
1868 */
1869 #if (configUSE_TICK_HOOK == 1)
1870  __WEAK void vApplicationTickHook (void){}
1871 #endif
1872
1873 /**
1874   Dummy implementation of the callback function vApplicationMallocFailedHook().
1875 */
1876 #if (configUSE_MALLOC_FAILED_HOOK == 1)
1877 __WEAK void vApplicationMallocFailedHook (void){}
1878 #endif
1879
1880 /**
1881   Dummy implementation of the callback function vApplicationDaemonTaskStartupHook().
1882 */
1883 #if (configUSE_DAEMON_TASK_STARTUP_HOOK == 1)
1884 __WEAK void vApplicationDaemonTaskStartupHook (void){}
1885 #endif
1886
1887 /**
1888   Dummy implementation of the callback function vApplicationStackOverflowHook().
1889 */
1890 #if (configCHECK_FOR_STACK_OVERFLOW > 0)
1891 __WEAK void vApplicationStackOverflowHook (TaskHandle_t xTask, signed char *pcTaskName) {
1892   (void)xTask;
1893   (void)pcTaskName;
1894 }
1895 #endif
1896
1897 /*---------------------------------------------------------------------------*/
1898
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);
1902
1903 /* Idle task control block and stack */
1904 static StaticTask_t Idle_TCB;
1905 static StackType_t  Idle_Stack[configMINIMAL_STACK_SIZE];
1906
1907 /* Timer task control block and stack */
1908 static StaticTask_t Timer_TCB;
1909 static StackType_t  Timer_Stack[configTIMER_TASK_STACK_DEPTH];
1910
1911 /*
1912   vApplicationGetIdleTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
1913   equals to 1 and is required for static memory allocation support.
1914 */
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;
1919 }
1920
1921 /*
1922   vApplicationGetTimerTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
1923   equals to 1 and is required for static memory allocation support.
1924 */
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;
1929 }