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