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