STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
cmsis_os2.c
Go to the documentation of this file.
1/* --------------------------------------------------------------------------
2 * Copyright (c) 2013-2022 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#include <string.h>
23
24#include "FreeRTOS.h" // ARM.FreeRTOS::RTOS:Core
25#include "task.h" // ARM.FreeRTOS::RTOS:Core
26#include "event_groups.h" // ARM.FreeRTOS::RTOS:Event Groups
27#include "semphr.h" // ARM.FreeRTOS::RTOS:Core
28#include "timers.h" // ARM.FreeRTOS::RTOS:Timers
29
30#include "freertos_mpool.h" // osMemoryPool definitions
31#include "freertos_os2.h" // Configuration check and setup
32
33#include "cmsis_os2.h" // ::CMSIS:RTOS2
34#include "cmsis_compiler.h" // Compiler agnostic definitions
35
36/*---------------------------------------------------------------------------*/
37#ifndef __ARM_ARCH_6M__
38 #define __ARM_ARCH_6M__ 0
39#endif
40#ifndef __ARM_ARCH_7M__
41 #define __ARM_ARCH_7M__ 0
42#endif
43#ifndef __ARM_ARCH_7EM__
44 #define __ARM_ARCH_7EM__ 0
45#endif
46#ifndef __ARM_ARCH_8M_MAIN__
47 #define __ARM_ARCH_8M_MAIN__ 0
48#endif
49#ifndef __ARM_ARCH_7A__
50 #define __ARM_ARCH_7A__ 0
51#endif
52
53#if ((__ARM_ARCH_7M__ == 1U) || \
54 (__ARM_ARCH_7EM__ == 1U) || \
55 (__ARM_ARCH_8M_MAIN__ == 1U))
56#define IS_IRQ_MASKED() ((__get_PRIMASK() != 0U) || (__get_BASEPRI() != 0U))
57#elif (__ARM_ARCH_6M__ == 1U)
58#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
59#elif (__ARM_ARCH_7A__ == 1U)
60/* CPSR mask bits */
61#define CPSR_MASKBIT_I 0x80U
62
63#define IS_IRQ_MASKED() ((__get_CPSR() & CPSR_MASKBIT_I) != 0U)
64#else
65#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
66#endif
67
68#if (__ARM_ARCH_7A__ == 1U)
69/* CPSR mode bitmasks */
70#define CPSR_MODE_USER 0x10U
71#define CPSR_MODE_SYSTEM 0x1FU
72
73#define IS_IRQ_MODE() ((__get_mode() != CPSR_MODE_USER) && (__get_mode() != CPSR_MODE_SYSTEM))
74#else
75#define IS_IRQ_MODE() (__get_IPSR() != 0U)
76#endif
77
78/* Limits */
79#define MAX_BITS_TASK_NOTIFY 31U
80#define MAX_BITS_EVENT_GROUPS 24U
81
82#define THREAD_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_TASK_NOTIFY) - 1U))
83#define EVENT_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_EVENT_GROUPS) - 1U))
84
85/* Kernel version and identification string definition (major.minor.rev: mmnnnrrrr dec) */
86#define KERNEL_VERSION (((uint32_t)tskKERNEL_VERSION_MAJOR * 10000000UL) | \
87 ((uint32_t)tskKERNEL_VERSION_MINOR * 10000UL) | \
88 ((uint32_t)tskKERNEL_VERSION_BUILD * 1UL))
89
90#define KERNEL_ID ("FreeRTOS " tskKERNEL_VERSION_NUMBER)
91
92/* Timer callback information structure definition */
93typedef struct {
95 void *arg;
97
98/* Kernel initialization state */
100
101/* Get OS Tick count value */
102static uint32_t OS_Tick_GetCount (void);
103#if (configUSE_TICKLESS_IDLE == 0)
104/* Get OS Tick overflow status */
105static uint32_t OS_Tick_GetOverflow (void);
106#endif
107/* Get OS Tick interval */
108static uint32_t OS_Tick_GetInterval (void);
109
110/*
111 Heap region definition used by heap_5 variant
112
113 Define configAPPLICATION_ALLOCATED_HEAP as nonzero value in FreeRTOSConfig.h if
114 heap regions are already defined and vPortDefineHeapRegions is called in application.
115
116 Otherwise vPortDefineHeapRegions will be called by osKernelInitialize using
117 definition configHEAP_5_REGIONS as parameter. Overriding configHEAP_5_REGIONS
118 is possible by defining it globally or in FreeRTOSConfig.h.
119*/
120#if defined(USE_FreeRTOS_HEAP_5)
121#if (configAPPLICATION_ALLOCATED_HEAP == 0)
122 /*
123 FreeRTOS heap is not defined by the application.
124 Single region of size configTOTAL_HEAP_SIZE (defined in FreeRTOSConfig.h)
125 is provided by default. Define configHEAP_5_REGIONS to provide custom
126 HeapRegion_t array.
127 */
128 #define HEAP_5_REGION_SETUP 1
129
130 #ifndef configHEAP_5_REGIONS
131 #define configHEAP_5_REGIONS xHeapRegions
132
133 static uint8_t ucHeap[configTOTAL_HEAP_SIZE];
134
135 static HeapRegion_t xHeapRegions[] = {
137 { NULL, 0 }
138 };
139 #else
140 /* Global definition is provided to override default heap array */
141 extern HeapRegion_t configHEAP_5_REGIONS[];
142 #endif
143#else
144 /*
145 The application already defined the array used for the FreeRTOS heap and
146 called vPortDefineHeapRegions to initialize heap.
147 */
148 #define HEAP_5_REGION_SETUP 0
149#endif /* configAPPLICATION_ALLOCATED_HEAP */
150#endif /* USE_FreeRTOS_HEAP_5 */
151
152#if defined(SysTick)
153#undef SysTick_Handler
154
155/* CMSIS SysTick interrupt handler prototype */
156extern void SysTick_Handler (void);
157/* FreeRTOS tick timer interrupt handler prototype */
158extern void xPortSysTickHandler (void);
159
160/*
161 SysTick handler implementation that also clears overflow flag.
162*/
163#if (USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION == 0)
164void SysTick_Handler (void) {
165#if (configUSE_TICKLESS_IDLE == 0)
166 /* Clear overflow flag */
167 SysTick->CTRL;
168#endif
169
171 /* Call tick handler */
173 }
174}
175#endif
176#endif /* SysTick */
177
178/*
179 Setup SVC to reset value.
180*/
182#if (__ARM_ARCH_7A__ == 0U)
183 /* Service Call interrupt might be configured before kernel start */
184 /* and when its priority is lower or equal to BASEPRI, svc instruction */
185 /* causes a Hard Fault. */
187#endif
188}
189
190/*
191 Function macro used to retrieve semaphore count from ISR
192*/
193#ifndef uxSemaphoreGetCountFromISR
194#define uxSemaphoreGetCountFromISR( xSemaphore ) uxQueueMessagesWaitingFromISR( ( QueueHandle_t ) ( xSemaphore ) )
195#endif
196
197/*
198 Determine if CPU executes from interrupt context or if interrupts are masked.
199*/
201 uint32_t irq;
203
204 irq = 0U;
205
206 if (IS_IRQ_MODE()) {
207 /* Called from interrupt context */
208 irq = 1U;
209 }
210 else {
211 /* Get FreeRTOS scheduler state */
213
215 /* Scheduler was started */
216 if (IS_IRQ_MASKED()) {
217 /* Interrupts are masked */
218 irq = 1U;
219 }
220 }
221 }
222
223 /* Return context, 0: thread context, 1: IRQ context */
224 return (irq);
225}
226
227/* Get OS Tick count value */
228static uint32_t OS_Tick_GetCount (void) {
229#if (__ARM_ARCH_7A__ == 1U)
230 return (__get_CNTFRQ() - PL1_GetCurrentValue());
231#else
232 uint32_t load = SysTick->LOAD;
233 return (load - SysTick->VAL);
234#endif /* __ARM_ARCH_7A__ */
235}
236
237#if (configUSE_TICKLESS_IDLE == 0)
238/* Get OS Tick overflow status */
239static uint32_t OS_Tick_GetOverflow (void) {
240#if (__ARM_ARCH_7A__ == 1U)
241 CNTP_CTL_Type cntp_ctl;
242 cntp_ctl.w = PL1_GetControl();
243 return (cntp_ctl.b.ISTATUS);
244#else
245 return ((SysTick->CTRL >> 16) & 1U);
246#endif /* __ARM_ARCH_7A__ */
247}
248#endif
249
250/* Get OS Tick interval */
251static uint32_t OS_Tick_GetInterval (void) {
252#if (__ARM_ARCH_7A__ == 1U)
253 return (__get_CNTFRQ() + 1U);
254#else
255 return (SysTick->LOAD + 1U);
256#endif /* __ARM_ARCH_7A__ */
257}
258
259/* ==== Kernel Management Functions ==== */
260
261/*
262 Initialize the RTOS Kernel.
263*/
265 osStatus_t stat;
267
268 if (IRQ_Context() != 0U) {
269 stat = osErrorISR;
270 }
271 else {
273
274 /* Initialize if scheduler not started and not initialized before */
276 #if defined(USE_TRACE_EVENT_RECORDER)
277 /* Initialize the trace macro debugging output channel */
278 EvrFreeRTOSSetup(0U);
279 #endif
280 #if defined(USE_FreeRTOS_HEAP_5) && (HEAP_5_REGION_SETUP == 1)
281 /* Initialize the memory regions when using heap_5 variant */
282 vPortDefineHeapRegions (configHEAP_5_REGIONS);
283 #endif
285 stat = osOK;
286 } else {
287 stat = osError;
288 }
289 }
290
291 /* Return execution status */
292 return (stat);
293}
294
295/*
296 Get RTOS Kernel Information.
297*/
298osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) {
299
300 if (version != NULL) {
301 /* Version encoding is major.minor.rev: mmnnnrrrr dec */
302 version->api = KERNEL_VERSION;
303 version->kernel = KERNEL_VERSION;
304 }
305
306 if ((id_buf != NULL) && (id_size != 0U)) {
307 /* Buffer for retrieving identification string is provided */
308 if (id_size > sizeof(KERNEL_ID)) {
309 id_size = sizeof(KERNEL_ID);
310 }
311 /* Copy kernel identification string into provided buffer */
312 memcpy(id_buf, KERNEL_ID, id_size);
313 }
314
315 /* Return execution status */
316 return (osOK);
317}
318
319/*
320 Get the current RTOS Kernel state.
321*/
324
325 switch (xTaskGetSchedulerState()) {
328 break;
329
332 break;
333
335 default:
336 if (KernelState == osKernelReady) {
337 /* Ready, osKernelInitialize was already called */
339 } else {
340 /* Not initialized */
342 }
343 break;
344 }
345
346 /* Return current state */
347 return (state);
348}
349
350/*
351 Start the RTOS Kernel scheduler.
352*/
354 osStatus_t stat;
356
357 if (IRQ_Context() != 0U) {
358 stat = osErrorISR;
359 }
360 else {
362
363 /* Start scheduler if initialized and not started before */
365 /* Ensure SVC priority is at the reset value */
366 SVC_Setup();
367 /* Change state to ensure correct API flow */
369 /* Start the kernel scheduler */
371 stat = osOK;
372 } else {
373 stat = osError;
374 }
375 }
376
377 /* Return execution status */
378 return (stat);
379}
380
381/*
382 Lock the RTOS Kernel scheduler.
383*/
384int32_t osKernelLock (void) {
385 int32_t lock;
386
387 if (IRQ_Context() != 0U) {
388 lock = (int32_t)osErrorISR;
389 }
390 else {
391 switch (xTaskGetSchedulerState()) {
393 lock = 1;
394 break;
395
398 lock = 0;
399 break;
400
402 default:
403 lock = (int32_t)osError;
404 break;
405 }
406 }
407
408 /* Return previous lock state */
409 return (lock);
410}
411
412/*
413 Unlock the RTOS Kernel scheduler.
414*/
415int32_t osKernelUnlock (void) {
416 int32_t lock;
417
418 if (IRQ_Context() != 0U) {
419 lock = (int32_t)osErrorISR;
420 }
421 else {
422 switch (xTaskGetSchedulerState()) {
424 lock = 1;
425
426 if (xTaskResumeAll() != pdTRUE) {
428 lock = (int32_t)osError;
429 }
430 }
431 break;
432
434 lock = 0;
435 break;
436
438 default:
439 lock = (int32_t)osError;
440 break;
441 }
442 }
443
444 /* Return previous lock state */
445 return (lock);
446}
447
448/*
449 Restore the RTOS Kernel scheduler lock state.
450*/
451int32_t osKernelRestoreLock (int32_t lock) {
452
453 if (IRQ_Context() != 0U) {
454 lock = (int32_t)osErrorISR;
455 }
456 else {
457 switch (xTaskGetSchedulerState()) {
460 if (lock == 1) {
462 }
463 else {
464 if (lock != 0) {
465 lock = (int32_t)osError;
466 }
467 else {
468 if (xTaskResumeAll() != pdTRUE) {
470 lock = (int32_t)osError;
471 }
472 }
473 }
474 }
475 break;
476
478 default:
479 lock = (int32_t)osError;
480 break;
481 }
482 }
483
484 /* Return new lock state */
485 return (lock);
486}
487
488/*
489 Get the RTOS kernel tick count.
490*/
491uint32_t osKernelGetTickCount (void) {
492 TickType_t ticks;
493
494 if (IRQ_Context() != 0U) {
495 ticks = xTaskGetTickCountFromISR();
496 } else {
497 ticks = xTaskGetTickCount();
498 }
499
500 /* Return kernel tick count */
501 return (ticks);
502}
503
504/*
505 Get the RTOS kernel tick frequency.
506*/
507uint32_t osKernelGetTickFreq (void) {
508 /* Return frequency in hertz */
509 return (configTICK_RATE_HZ);
510}
511
512/*
513 Get the RTOS kernel system timer count.
514*/
516 uint32_t irqmask = IS_IRQ_MASKED();
517 TickType_t ticks;
518 uint32_t val;
519#if (configUSE_TICKLESS_IDLE != 0)
520 uint32_t val0;
521
522 /* Low Power Tickless Idle controls timer overflow flag and therefore */
523 /* OS_Tick_GetOverflow may be non-functional. As a workaround a reference */
524 /* time is measured here before disabling interrupts. Timer value overflow */
525 /* is then checked by comparing reference against latest time measurement. */
526 /* Timer count value returned by this method is less accurate but if an */
527 /* overflow is missed, an invalid timer count would be returned. */
528 val0 = OS_Tick_GetCount();
529#endif
530
532
533 ticks = xTaskGetTickCount();
534 val = OS_Tick_GetCount();
535
536 /* Update tick count and timer value when timer overflows */
537#if (configUSE_TICKLESS_IDLE != 0)
538 if (val < val0) {
539 ticks++;
540 }
541#else
542 if (OS_Tick_GetOverflow() != 0U) {
543 val = OS_Tick_GetCount();
544 ticks++;
545 }
546#endif
547
548 val += ticks * OS_Tick_GetInterval();
549
550 if (irqmask == 0U) {
551 __enable_irq();
552 }
553
554 /* Return system timer count */
555 return (val);
556}
557
558/*
559 Get the RTOS kernel system timer frequency.
560*/
561uint32_t osKernelGetSysTimerFreq (void) {
562 /* Return frequency in hertz */
563 return (configCPU_CLOCK_HZ);
564}
565
566
567/* ==== Thread Management Functions ==== */
568
569/*
570 Create a thread and add it to Active Threads.
571
572 Limitations:
573 - The memory for control block and stack must be provided in the osThreadAttr_t
574 structure in order to allocate object statically.
575 - Attribute osThreadJoinable is not supported, NULL is returned if used.
576*/
577osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) {
578 const char *name;
579 uint32_t stack;
580 TaskHandle_t hTask;
581 UBaseType_t prio;
582 int32_t mem;
583
584 hTask = NULL;
585
586 if ((IRQ_Context() == 0U) && (func != NULL)) {
589
590 name = NULL;
591 mem = -1;
592
593 if (attr != NULL) {
594 if (attr->name != NULL) {
595 name = attr->name;
596 }
597 if (attr->priority != osPriorityNone) {
598 prio = (UBaseType_t)attr->priority;
599 }
600
601 if ((prio < osPriorityIdle) || (prio > osPriorityISR) || ((attr->attr_bits & osThreadJoinable) == osThreadJoinable)) {
602 /* Invalid priority or unsupported osThreadJoinable attribute used */
603 return (NULL);
604 }
605
606 if (attr->stack_size > 0U) {
607 /* In FreeRTOS stack is not in bytes, but in sizeof(StackType_t) which is 4 on ARM ports. */
608 /* Stack size should be therefore 4 byte aligned in order to avoid division caused side effects */
609 stack = attr->stack_size / sizeof(StackType_t);
610 }
611
612 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTask_t)) &&
613 (attr->stack_mem != NULL) && (attr->stack_size > 0U)) {
614 /* The memory for control block and stack is provided, use static object */
615 mem = 1;
616 }
617 else {
618 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) && (attr->stack_mem == NULL)) {
619 /* Control block and stack memory will be allocated from the dynamic pool */
620 mem = 0;
621 }
622 }
623 }
624 else {
625 mem = 0;
626 }
627
628 if (mem == 1) {
629 #if (configSUPPORT_STATIC_ALLOCATION == 1)
630 hTask = xTaskCreateStatic ((TaskFunction_t)func, name, stack, argument, prio, (StackType_t *)attr->stack_mem,
631 (StaticTask_t *)attr->cb_mem);
632 #endif
633 }
634 else {
635 if (mem == 0) {
636 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
637 if (xTaskCreate ((TaskFunction_t)func, name, (configSTACK_DEPTH_TYPE)stack, argument, prio, &hTask) != pdPASS) {
638 hTask = NULL;
639 }
640 #endif
641 }
642 }
643 }
644
645 /* Return thread ID */
646 return ((osThreadId_t)hTask);
647}
648
649/*
650 Get name of a thread.
651*/
652const char *osThreadGetName (osThreadId_t thread_id) {
653 TaskHandle_t hTask = (TaskHandle_t)thread_id;
654 const char *name;
655
656 if ((IRQ_Context() != 0U) || (hTask == NULL)) {
657 name = NULL;
658 } else {
659 name = pcTaskGetName (hTask);
660 }
661
662 /* Return name as null-terminated string */
663 return (name);
664}
665
666/*
667 Return the thread ID of the current running thread.
668*/
670 osThreadId_t id;
671
673
674 /* Return thread ID */
675 return (id);
676}
677
678/*
679 Get current thread state of a thread.
680*/
682 TaskHandle_t hTask = (TaskHandle_t)thread_id;
684
685 if ((IRQ_Context() != 0U) || (hTask == NULL)) {
687 }
688 else {
689 switch (eTaskGetState (hTask)) {
690 case eRunning: state = osThreadRunning; break;
691 case eReady: state = osThreadReady; break;
692 case eBlocked:
693 case eSuspended: state = osThreadBlocked; break;
694 case eDeleted:
695 case eInvalid:
696 default: state = osThreadError; break;
697 }
698 }
699
700 /* Return current thread state */
701 return (state);
702}
703
704/*
705 Get available stack space of a thread based on stack watermark recording during execution.
706*/
708 TaskHandle_t hTask = (TaskHandle_t)thread_id;
709 uint32_t sz;
710
711 if ((IRQ_Context() != 0U) || (hTask == NULL)) {
712 sz = 0U;
713 } else {
714 sz = (uint32_t)(uxTaskGetStackHighWaterMark(hTask) * sizeof(StackType_t));
715 }
716
717 /* Return remaining stack space in bytes */
718 return (sz);
719}
720
721/*
722 Change priority of a thread.
723*/
725 TaskHandle_t hTask = (TaskHandle_t)thread_id;
726 osStatus_t stat;
727
728 if (IRQ_Context() != 0U) {
729 stat = osErrorISR;
730 }
731 else if ((hTask == NULL) || (priority < osPriorityIdle) || (priority > osPriorityISR)) {
732 stat = osErrorParameter;
733 }
734 else {
735 stat = osOK;
736 vTaskPrioritySet (hTask, (UBaseType_t)priority);
737 }
738
739 /* Return execution status */
740 return (stat);
741}
742
743/*
744 Get current priority of a thread.
745*/
747 TaskHandle_t hTask = (TaskHandle_t)thread_id;
748 osPriority_t prio;
749
750 if ((IRQ_Context() != 0U) || (hTask == NULL)) {
751 prio = osPriorityError;
752 } else {
753 prio = (osPriority_t)((int32_t)uxTaskPriorityGet (hTask));
754 }
755
756 /* Return current thread priority */
757 return (prio);
758}
759
760/*
761 Pass control to next thread that is in state READY.
762*/
764 osStatus_t stat;
765
766 if (IRQ_Context() != 0U) {
767 stat = osErrorISR;
768 } else {
769 stat = osOK;
770 taskYIELD();
771 }
772
773 /* Return execution status */
774 return (stat);
775}
776
777#if (configUSE_OS2_THREAD_SUSPEND_RESUME == 1)
778/*
779 Suspend execution of a thread.
780*/
782 TaskHandle_t hTask = (TaskHandle_t)thread_id;
783 osStatus_t stat;
784
785 if (IRQ_Context() != 0U) {
786 stat = osErrorISR;
787 }
788 else if (hTask == NULL) {
789 stat = osErrorParameter;
790 }
791 else {
792 stat = osOK;
793 vTaskSuspend (hTask);
794 }
795
796 /* Return execution status */
797 return (stat);
798}
799
800/*
801 Resume execution of a thread.
802*/
804 TaskHandle_t hTask = (TaskHandle_t)thread_id;
805 osStatus_t stat;
806
807 if (IRQ_Context() != 0U) {
808 stat = osErrorISR;
809 }
810 else if (hTask == NULL) {
811 stat = osErrorParameter;
812 }
813 else {
814 stat = osOK;
815 vTaskResume (hTask);
816 }
817
818 /* Return execution status */
819 return (stat);
820}
821#endif /* (configUSE_OS2_THREAD_SUSPEND_RESUME == 1) */
822
823/*
824 Terminate execution of current running thread.
825*/
827#ifndef USE_FreeRTOS_HEAP_1
829#endif
830 for (;;);
831}
832
833/*
834 Terminate execution of a thread.
835*/
837 TaskHandle_t hTask = (TaskHandle_t)thread_id;
838 osStatus_t stat;
839#ifndef USE_FreeRTOS_HEAP_1
840 eTaskState tstate;
841
842 if (IRQ_Context() != 0U) {
843 stat = osErrorISR;
844 }
845 else if (hTask == NULL) {
846 stat = osErrorParameter;
847 }
848 else {
849 tstate = eTaskGetState (hTask);
850
851 if (tstate != eDeleted) {
852 stat = osOK;
853 vTaskDelete (hTask);
854 } else {
855 stat = osErrorResource;
856 }
857 }
858#else
859 stat = osError;
860#endif
861
862 /* Return execution status */
863 return (stat);
864}
865
866/*
867 Get number of active threads.
868*/
869uint32_t osThreadGetCount (void) {
870 uint32_t count;
871
872 if (IRQ_Context() != 0U) {
873 count = 0U;
874 } else {
876 }
877
878 /* Return number of active threads */
879 return (count);
880}
881
882#if (configUSE_OS2_THREAD_ENUMERATE == 1)
883/*
884 Enumerate active threads.
885*/
886uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) {
887 uint32_t i, count;
888 TaskStatus_t *task;
889
890 if ((IRQ_Context() != 0U) || (thread_array == NULL) || (array_items == 0U)) {
891 count = 0U;
892 } else {
894
895 /* Allocate memory on heap to temporarily store TaskStatus_t information */
897 task = pvPortMalloc (count * sizeof(TaskStatus_t));
898
899 if (task != NULL) {
900 /* Retrieve task status information */
902
903 /* Copy handles from task status array into provided thread array */
904 for (i = 0U; (i < count) && (i < array_items); i++) {
905 thread_array[i] = (osThreadId_t)task[i].xHandle;
906 }
907 count = i;
908 }
909 (void)xTaskResumeAll();
910
911 vPortFree (task);
912 }
913
914 /* Return number of enumerated threads */
915 return (count);
916}
917#endif /* (configUSE_OS2_THREAD_ENUMERATE == 1) */
918
919
920/* ==== Thread Flags Functions ==== */
921
922#if (configUSE_OS2_THREAD_FLAGS == 1)
923/*
924 Set the specified Thread Flags of a thread.
925*/
926uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) {
927 TaskHandle_t hTask = (TaskHandle_t)thread_id;
928 uint32_t rflags;
929 BaseType_t yield;
930
931 if ((hTask == NULL) || ((flags & THREAD_FLAGS_INVALID_BITS) != 0U)) {
932 rflags = (uint32_t)osErrorParameter;
933 }
934 else {
935 rflags = (uint32_t)osError;
936
937 if (IRQ_Context() != 0U) {
938 yield = pdFALSE;
939
940 (void)xTaskNotifyFromISR (hTask, flags, eSetBits, &yield);
941 (void)xTaskNotifyAndQueryFromISR (hTask, 0, eNoAction, &rflags, NULL);
942
943 portYIELD_FROM_ISR (yield);
944 }
945 else {
946 (void)xTaskNotify (hTask, flags, eSetBits);
947 (void)xTaskNotifyAndQuery (hTask, 0, eNoAction, &rflags);
948 }
949 }
950 /* Return flags after setting */
951 return (rflags);
952}
953
954/*
955 Clear the specified Thread Flags of current running thread.
956*/
957uint32_t osThreadFlagsClear (uint32_t flags) {
958 TaskHandle_t hTask;
959 uint32_t rflags, cflags;
960
961 if (IRQ_Context() != 0U) {
962 rflags = (uint32_t)osErrorISR;
963 }
964 else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) {
965 rflags = (uint32_t)osErrorParameter;
966 }
967 else {
969
970 if (xTaskNotifyAndQuery (hTask, 0, eNoAction, &cflags) == pdPASS) {
971 rflags = cflags;
972 cflags &= ~flags;
973
974 if (xTaskNotify (hTask, cflags, eSetValueWithOverwrite) != pdPASS) {
975 rflags = (uint32_t)osError;
976 }
977 }
978 else {
979 rflags = (uint32_t)osError;
980 }
981 }
982
983 /* Return flags before clearing */
984 return (rflags);
985}
986
987/*
988 Get the current Thread Flags of current running thread.
989*/
990uint32_t osThreadFlagsGet (void) {
991 TaskHandle_t hTask;
992 uint32_t rflags;
993
994 if (IRQ_Context() != 0U) {
995 rflags = (uint32_t)osErrorISR;
996 }
997 else {
999
1000 if (xTaskNotifyAndQuery (hTask, 0, eNoAction, &rflags) != pdPASS) {
1001 rflags = (uint32_t)osError;
1002 }
1003 }
1004
1005 /* Return current flags */
1006 return (rflags);
1007}
1008
1009/*
1010 Wait for one or more Thread Flags of the current running thread to become signaled.
1011*/
1012uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) {
1013 uint32_t rflags, nval;
1014 uint32_t clear;
1015 TickType_t t0, td, tout;
1016 BaseType_t rval;
1017
1018 if (IRQ_Context() != 0U) {
1019 rflags = (uint32_t)osErrorISR;
1020 }
1021 else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) {
1022 rflags = (uint32_t)osErrorParameter;
1023 }
1024 else {
1025 if ((options & osFlagsNoClear) == osFlagsNoClear) {
1026 clear = 0U;
1027 } else {
1028 clear = flags;
1029 }
1030
1031 rflags = 0U;
1032 tout = timeout;
1033
1034 t0 = xTaskGetTickCount();
1035 do {
1036 rval = xTaskNotifyWait (0, clear, &nval, tout);
1037
1038 if (rval == pdPASS) {
1039 rflags &= flags;
1040 rflags |= nval;
1041
1042 if ((options & osFlagsWaitAll) == osFlagsWaitAll) {
1043 if ((flags & rflags) == flags) {
1044 break;
1045 } else {
1046 if (timeout == 0U) {
1047 rflags = (uint32_t)osErrorResource;
1048 break;
1049 }
1050 }
1051 }
1052 else {
1053 if ((flags & rflags) != 0) {
1054 break;
1055 } else {
1056 if (timeout == 0U) {
1057 rflags = (uint32_t)osErrorResource;
1058 break;
1059 }
1060 }
1061 }
1062
1063 /* Update timeout */
1064 td = xTaskGetTickCount() - t0;
1065
1066 if (td > timeout) {
1067 tout = 0;
1068 } else {
1069 tout = timeout - td;
1070 }
1071 }
1072 else {
1073 if (timeout == 0) {
1074 rflags = (uint32_t)osErrorResource;
1075 } else {
1076 rflags = (uint32_t)osErrorTimeout;
1077 }
1078 }
1079 }
1080 while (rval != pdFAIL);
1081 }
1082
1083 /* Return flags before clearing */
1084 return (rflags);
1085}
1086#endif /* (configUSE_OS2_THREAD_FLAGS == 1) */
1087
1088
1089/* ==== Generic Wait Functions ==== */
1090
1091/*
1092 Wait for Timeout (Time Delay).
1093*/
1094osStatus_t osDelay (uint32_t ticks) {
1095 osStatus_t stat;
1096
1097 if (IRQ_Context() != 0U) {
1098 stat = osErrorISR;
1099 }
1100 else {
1101 stat = osOK;
1102
1103 if (ticks != 0U) {
1104 vTaskDelay(ticks);
1105 }
1106 }
1107
1108 /* Return execution status */
1109 return (stat);
1110}
1111
1112/*
1113 Wait until specified time.
1114*/
1115osStatus_t osDelayUntil (uint32_t ticks) {
1116 TickType_t tcnt, delay;
1117 osStatus_t stat;
1118
1119 if (IRQ_Context() != 0U) {
1120 stat = osErrorISR;
1121 }
1122 else {
1123 stat = osOK;
1124 tcnt = xTaskGetTickCount();
1125
1126 /* Determine remaining number of ticks to delay */
1127 delay = (TickType_t)ticks - tcnt;
1128
1129 /* Check if target tick has not expired */
1130 if((delay != 0U) && (0 == (delay >> (8 * sizeof(TickType_t) - 1)))) {
1131 if (xTaskDelayUntil (&tcnt, delay) == pdFALSE) {
1132 /* Did not delay */
1133 stat = osError;
1134 }
1135 }
1136 else
1137 {
1138 /* No delay or already expired */
1139 stat = osErrorParameter;
1140 }
1141 }
1142
1143 /* Return execution status */
1144 return (stat);
1145}
1146
1147
1148/* ==== Timer Management Functions ==== */
1149
1150#if (configUSE_OS2_TIMER == 1)
1151
1152static void TimerCallback (TimerHandle_t hTimer) {
1153 TimerCallback_t *callb;
1154
1155 /* Retrieve pointer to callback function and argument */
1156 callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer);
1157
1158 /* Remove dynamic allocation flag */
1159 callb = (TimerCallback_t *)((uint32_t)callb & ~1U);
1160
1161 if (callb != NULL) {
1162 callb->func (callb->arg);
1163 }
1164}
1165
1166/*
1167 Create and Initialize a timer.
1168*/
1169osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) {
1170 const char *name;
1171 TimerHandle_t hTimer;
1172 TimerCallback_t *callb;
1173 UBaseType_t reload;
1174 int32_t mem;
1175 uint32_t callb_dyn;
1176
1177 hTimer = NULL;
1178
1179 if ((IRQ_Context() == 0U) && (func != NULL)) {
1180 callb = NULL;
1181 callb_dyn = 0U;
1182
1183 #if (configSUPPORT_STATIC_ALLOCATION == 1)
1184 /* Static memory allocation is available: check if memory for control block */
1185 /* is provided and if it also contains space for callback and its argument */
1186 if ((attr != NULL) && (attr->cb_mem != NULL)) {
1187 if (attr->cb_size >= (sizeof(StaticTimer_t) + sizeof(TimerCallback_t))) {
1188 callb = (TimerCallback_t *)((uint32_t)attr->cb_mem + sizeof(StaticTimer_t));
1189 }
1190 }
1191 #endif
1192
1193 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1194 /* Dynamic memory allocation is available: if memory for callback and */
1195 /* its argument is not provided, allocate it from dynamic memory pool */
1196 if (callb == NULL) {
1197 callb = (TimerCallback_t *)pvPortMalloc (sizeof(TimerCallback_t));
1198
1199 if (callb != NULL) {
1200 /* Callback memory was allocated from dynamic pool, set flag */
1201 callb_dyn = 1U;
1202 }
1203 }
1204 #endif
1205
1206 if (callb != NULL) {
1207 callb->func = func;
1208 callb->arg = argument;
1209
1210 if (type == osTimerOnce) {
1211 reload = pdFALSE;
1212 } else {
1213 reload = pdTRUE;
1214 }
1215
1216 mem = -1;
1217 name = NULL;
1218
1219 if (attr != NULL) {
1220 if (attr->name != NULL) {
1221 name = attr->name;
1222 }
1223
1224 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTimer_t))) {
1225 /* The memory for control block is provided, use static object */
1226 mem = 1;
1227 }
1228 else {
1229 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1230 /* Control block will be allocated from the dynamic pool */
1231 mem = 0;
1232 }
1233 }
1234 }
1235 else {
1236 mem = 0;
1237 }
1238 /* Store callback memory dynamic allocation flag */
1239 callb = (TimerCallback_t *)((uint32_t)callb | callb_dyn);
1240 /*
1241 TimerCallback function is always provided as a callback and is used to call application
1242 specified function with its argument both stored in structure callb.
1243 */
1244 if (mem == 1) {
1245 #if (configSUPPORT_STATIC_ALLOCATION == 1)
1246 hTimer = xTimerCreateStatic (name, 1, reload, callb, TimerCallback, (StaticTimer_t *)attr->cb_mem);
1247 #endif
1248 }
1249 else {
1250 if (mem == 0) {
1251 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1252 hTimer = xTimerCreate (name, 1, reload, callb, TimerCallback);
1253 #endif
1254 }
1255 }
1256
1257 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1258 if ((hTimer == NULL) && (callb != NULL) && (callb_dyn == 1U)) {
1259 /* Failed to create a timer, release allocated resources */
1260 callb = (TimerCallback_t *)((uint32_t)callb & ~1U);
1261
1262 vPortFree (callb);
1263 }
1264 #endif
1265 }
1266 }
1267
1268 /* Return timer ID */
1269 return ((osTimerId_t)hTimer);
1270}
1271
1272/*
1273 Get name of a timer.
1274*/
1275const char *osTimerGetName (osTimerId_t timer_id) {
1276 TimerHandle_t hTimer = (TimerHandle_t)timer_id;
1277 const char *p;
1278
1279 if ((IRQ_Context() != 0U) || (hTimer == NULL)) {
1280 p = NULL;
1281 } else {
1282 p = pcTimerGetName (hTimer);
1283 }
1284
1285 /* Return name as null-terminated string */
1286 return (p);
1287}
1288
1289/*
1290 Start or restart a timer.
1291*/
1292osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks) {
1293 TimerHandle_t hTimer = (TimerHandle_t)timer_id;
1294 osStatus_t stat;
1295
1296 if (IRQ_Context() != 0U) {
1297 stat = osErrorISR;
1298 }
1299 else if ((hTimer == NULL) || (ticks == 0U)) {
1300 stat = osErrorParameter;
1301 }
1302 else {
1303 if (xTimerChangePeriod (hTimer, ticks, 0) == pdPASS) {
1304 stat = osOK;
1305 } else {
1306 stat = osErrorResource;
1307 }
1308 }
1309
1310 /* Return execution status */
1311 return (stat);
1312}
1313
1314/*
1315 Stop a timer.
1316*/
1318 TimerHandle_t hTimer = (TimerHandle_t)timer_id;
1319 osStatus_t stat;
1320
1321 if (IRQ_Context() != 0U) {
1322 stat = osErrorISR;
1323 }
1324 else if (hTimer == NULL) {
1325 stat = osErrorParameter;
1326 }
1327 else {
1328 if (xTimerIsTimerActive (hTimer) == pdFALSE) {
1329 stat = osErrorResource;
1330 }
1331 else {
1332 if (xTimerStop (hTimer, 0) == pdPASS) {
1333 stat = osOK;
1334 } else {
1335 stat = osError;
1336 }
1337 }
1338 }
1339
1340 /* Return execution status */
1341 return (stat);
1342}
1343
1344/*
1345 Check if a timer is running.
1346*/
1347uint32_t osTimerIsRunning (osTimerId_t timer_id) {
1348 TimerHandle_t hTimer = (TimerHandle_t)timer_id;
1349 uint32_t running;
1350
1351 if ((IRQ_Context() != 0U) || (hTimer == NULL)) {
1352 running = 0U;
1353 } else {
1354 running = (uint32_t)xTimerIsTimerActive (hTimer);
1355 }
1356
1357 /* Return 0: not running, 1: running */
1358 return (running);
1359}
1360
1361/*
1362 Delete a timer.
1363*/
1365 TimerHandle_t hTimer = (TimerHandle_t)timer_id;
1366 osStatus_t stat;
1367#ifndef USE_FreeRTOS_HEAP_1
1368#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1369 TimerCallback_t *callb;
1370#endif
1371
1372 if (IRQ_Context() != 0U) {
1373 stat = osErrorISR;
1374 }
1375 else if (hTimer == NULL) {
1376 stat = osErrorParameter;
1377 }
1378 else {
1379 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1380 callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer);
1381 #endif
1382
1383 if (xTimerDelete (hTimer, 0) == pdPASS) {
1384 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1385 if ((uint32_t)callb & 1U) {
1386 /* Callback memory was allocated from dynamic pool, clear flag */
1387 callb = (TimerCallback_t *)((uint32_t)callb & ~1U);
1388
1389 /* Return allocated memory to dynamic pool */
1390 vPortFree (callb);
1391 }
1392 #endif
1393 stat = osOK;
1394 } else {
1395 stat = osErrorResource;
1396 }
1397 }
1398#else
1399 stat = osError;
1400#endif
1401
1402 /* Return execution status */
1403 return (stat);
1404}
1405#endif /* (configUSE_OS2_TIMER == 1) */
1406
1407
1408/* ==== Event Flags Management Functions ==== */
1409
1410/*
1411 Create and Initialize an Event Flags object.
1412
1413 Limitations:
1414 - Event flags are limited to 24 bits.
1415*/
1417 EventGroupHandle_t hEventGroup;
1418 int32_t mem;
1419
1420 hEventGroup = NULL;
1421
1422 if (IRQ_Context() == 0U) {
1423 mem = -1;
1424
1425 if (attr != NULL) {
1426 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticEventGroup_t))) {
1427 /* The memory for control block is provided, use static object */
1428 mem = 1;
1429 }
1430 else {
1431 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1432 /* Control block will be allocated from the dynamic pool */
1433 mem = 0;
1434 }
1435 }
1436 }
1437 else {
1438 mem = 0;
1439 }
1440
1441 if (mem == 1) {
1442 #if (configSUPPORT_STATIC_ALLOCATION == 1)
1443 hEventGroup = xEventGroupCreateStatic (attr->cb_mem);
1444 #endif
1445 }
1446 else {
1447 if (mem == 0) {
1448 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1449 hEventGroup = xEventGroupCreate();
1450 #endif
1451 }
1452 }
1453 }
1454
1455 /* Return event flags ID */
1456 return ((osEventFlagsId_t)hEventGroup);
1457}
1458
1459/*
1460 Set the specified Event Flags.
1461
1462 Limitations:
1463 - Event flags are limited to 24 bits.
1464*/
1465uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) {
1466 EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1467 uint32_t rflags;
1468 BaseType_t yield;
1469
1470 if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1471 rflags = (uint32_t)osErrorParameter;
1472 }
1473 else if (IRQ_Context() != 0U) {
1474 #if (configUSE_OS2_EVENTFLAGS_FROM_ISR == 0)
1475 (void)yield;
1476 /* Enable timers and xTimerPendFunctionCall function to support osEventFlagsSet from ISR */
1477 rflags = (uint32_t)osErrorResource;
1478 #else
1479 yield = pdFALSE;
1480
1481 if (xEventGroupSetBitsFromISR (hEventGroup, (EventBits_t)flags, &yield) == pdFAIL) {
1482 rflags = (uint32_t)osErrorResource;
1483 } else {
1484 /* Retrieve bits that are already set and add flags to be set in current call */
1485 rflags = xEventGroupGetBitsFromISR (hEventGroup);
1486 rflags |= flags;
1487 portYIELD_FROM_ISR (yield);
1488 }
1489 #endif
1490 }
1491 else {
1492 rflags = xEventGroupSetBits (hEventGroup, (EventBits_t)flags);
1493 }
1494
1495 /* Return event flags after setting */
1496 return (rflags);
1497}
1498
1499/*
1500 Clear the specified Event Flags.
1501
1502 Limitations:
1503 - Event flags are limited to 24 bits.
1504*/
1505uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) {
1506 EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1507 uint32_t rflags;
1508
1509 if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1510 rflags = (uint32_t)osErrorParameter;
1511 }
1512 else if (IRQ_Context() != 0U) {
1513 #if (configUSE_OS2_EVENTFLAGS_FROM_ISR == 0)
1514 /* Enable timers and xTimerPendFunctionCall function to support osEventFlagsSet from ISR */
1515 rflags = (uint32_t)osErrorResource;
1516 #else
1517 rflags = xEventGroupGetBitsFromISR (hEventGroup);
1518
1519 if (xEventGroupClearBitsFromISR (hEventGroup, (EventBits_t)flags) == pdFAIL) {
1520 rflags = (uint32_t)osErrorResource;
1521 }
1522 else {
1523 /* xEventGroupClearBitsFromISR only registers clear operation in the timer command queue. */
1524 /* Yield is required here otherwise clear operation might not execute in the right order. */
1525 /* See https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/93 for more info. */
1527 }
1528 #endif
1529 }
1530 else {
1531 rflags = xEventGroupClearBits (hEventGroup, (EventBits_t)flags);
1532 }
1533
1534 /* Return event flags before clearing */
1535 return (rflags);
1536}
1537
1538/*
1539 Get the current Event Flags.
1540
1541 Limitations:
1542 - Event flags are limited to 24 bits.
1543*/
1545 EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1546 uint32_t rflags;
1547
1548 if (ef_id == NULL) {
1549 rflags = 0U;
1550 }
1551 else if (IRQ_Context() != 0U) {
1552 rflags = xEventGroupGetBitsFromISR (hEventGroup);
1553 }
1554 else {
1555 rflags = xEventGroupGetBits (hEventGroup);
1556 }
1557
1558 /* Return current event flags */
1559 return (rflags);
1560}
1561
1562/*
1563 Wait for one or more Event Flags to become signaled.
1564
1565 Limitations:
1566 - Event flags are limited to 24 bits.
1567 - osEventFlagsWait cannot be called from an ISR.
1568*/
1569uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) {
1570 EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1571 BaseType_t wait_all;
1572 BaseType_t exit_clr;
1573 uint32_t rflags;
1574
1575 if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1576 rflags = (uint32_t)osErrorParameter;
1577 }
1578 else if (IRQ_Context() != 0U) {
1579 if (timeout == 0U) {
1580 /* Try semantic is not supported */
1581 rflags = (uint32_t)osErrorISR;
1582 } else {
1583 /* Calling osEventFlagsWait from ISR with non-zero timeout is invalid */
1584 rflags = (uint32_t)osFlagsErrorParameter;
1585 }
1586 }
1587 else {
1588 if (options & osFlagsWaitAll) {
1589 wait_all = pdTRUE;
1590 } else {
1591 wait_all = pdFAIL;
1592 }
1593
1594 if (options & osFlagsNoClear) {
1595 exit_clr = pdFAIL;
1596 } else {
1597 exit_clr = pdTRUE;
1598 }
1599
1600 rflags = xEventGroupWaitBits (hEventGroup, (EventBits_t)flags, exit_clr, wait_all, (TickType_t)timeout);
1601
1602 if (options & osFlagsWaitAll) {
1603 if ((flags & rflags) != flags) {
1604 if (timeout > 0U) {
1605 rflags = (uint32_t)osErrorTimeout;
1606 } else {
1607 rflags = (uint32_t)osErrorResource;
1608 }
1609 }
1610 }
1611 else {
1612 if ((flags & rflags) == 0U) {
1613 if (timeout > 0U) {
1614 rflags = (uint32_t)osErrorTimeout;
1615 } else {
1616 rflags = (uint32_t)osErrorResource;
1617 }
1618 }
1619 }
1620 }
1621
1622 /* Return event flags before clearing */
1623 return (rflags);
1624}
1625
1626/*
1627 Delete an Event Flags object.
1628*/
1630 EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1631 osStatus_t stat;
1632
1633#ifndef USE_FreeRTOS_HEAP_1
1634 if (IRQ_Context() != 0U) {
1635 stat = osErrorISR;
1636 }
1637 else if (hEventGroup == NULL) {
1638 stat = osErrorParameter;
1639 }
1640 else {
1641 stat = osOK;
1642 vEventGroupDelete (hEventGroup);
1643 }
1644#else
1645 stat = osError;
1646#endif
1647
1648 /* Return execution status */
1649 return (stat);
1650}
1651
1652
1653/* ==== Mutex Management Functions ==== */
1654
1655#if (configUSE_OS2_MUTEX == 1)
1656/*
1657 Create and Initialize a Mutex object.
1658
1659 Limitations:
1660 - Priority inherit protocol is used by default, osMutexPrioInherit attribute is ignored.
1661 - Robust mutex is not supported, NULL is returned if used.
1662*/
1663osMutexId_t osMutexNew (const osMutexAttr_t *attr) {
1664 SemaphoreHandle_t hMutex;
1665 uint32_t type;
1666 uint32_t rmtx;
1667 int32_t mem;
1668
1669 hMutex = NULL;
1670
1671 if (IRQ_Context() == 0U) {
1672 if (attr != NULL) {
1673 type = attr->attr_bits;
1674 } else {
1675 type = 0U;
1676 }
1677
1678 if ((type & osMutexRecursive) == osMutexRecursive) {
1679 rmtx = 1U;
1680 } else {
1681 rmtx = 0U;
1682 }
1683
1684 if ((type & osMutexRobust) != osMutexRobust) {
1685 mem = -1;
1686
1687 if (attr != NULL) {
1688 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
1689 /* The memory for control block is provided, use static object */
1690 mem = 1;
1691 }
1692 else {
1693 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1694 /* Control block will be allocated from the dynamic pool */
1695 mem = 0;
1696 }
1697 }
1698 }
1699 else {
1700 mem = 0;
1701 }
1702
1703 if (mem == 1) {
1704 #if (configSUPPORT_STATIC_ALLOCATION == 1)
1705 if (rmtx != 0U) {
1706 #if (configUSE_RECURSIVE_MUTEXES == 1)
1707 hMutex = xSemaphoreCreateRecursiveMutexStatic (attr->cb_mem);
1708 #endif
1709 }
1710 else {
1711 hMutex = xSemaphoreCreateMutexStatic (attr->cb_mem);
1712 }
1713 #endif
1714 }
1715 else {
1716 if (mem == 0) {
1717 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1718 if (rmtx != 0U) {
1719 #if (configUSE_RECURSIVE_MUTEXES == 1)
1720 hMutex = xSemaphoreCreateRecursiveMutex ();
1721 #endif
1722 } else {
1723 hMutex = xSemaphoreCreateMutex ();
1724 }
1725 #endif
1726 }
1727 }
1728
1729 #if (configQUEUE_REGISTRY_SIZE > 0)
1730 if (hMutex != NULL) {
1731 if ((attr != NULL) && (attr->name != NULL)) {
1732 /* Only non-NULL name objects are added to the Queue Registry */
1733 vQueueAddToRegistry (hMutex, attr->name);
1734 }
1735 }
1736 #endif
1737
1738 if ((hMutex != NULL) && (rmtx != 0U)) {
1739 /* Set LSB as 'recursive mutex flag' */
1740 hMutex = (SemaphoreHandle_t)((uint32_t)hMutex | 1U);
1741 }
1742 }
1743 }
1744
1745 /* Return mutex ID */
1746 return ((osMutexId_t)hMutex);
1747}
1748
1749/*
1750 Acquire a Mutex or timeout if it is locked.
1751*/
1752osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
1753 SemaphoreHandle_t hMutex;
1754 osStatus_t stat;
1755 uint32_t rmtx;
1756
1757 hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1758
1759 /* Extract recursive mutex flag */
1760 rmtx = (uint32_t)mutex_id & 1U;
1761
1762 stat = osOK;
1763
1764 if (IRQ_Context() != 0U) {
1765 stat = osErrorISR;
1766 }
1767 else if (hMutex == NULL) {
1768 stat = osErrorParameter;
1769 }
1770 else {
1771 if (rmtx != 0U) {
1772 #if (configUSE_RECURSIVE_MUTEXES == 1)
1773 if (xSemaphoreTakeRecursive (hMutex, timeout) != pdPASS) {
1774 if (timeout != 0U) {
1775 stat = osErrorTimeout;
1776 } else {
1777 stat = osErrorResource;
1778 }
1779 }
1780 #endif
1781 }
1782 else {
1783 if (xSemaphoreTake (hMutex, timeout) != pdPASS) {
1784 if (timeout != 0U) {
1785 stat = osErrorTimeout;
1786 } else {
1787 stat = osErrorResource;
1788 }
1789 }
1790 }
1791 }
1792
1793 /* Return execution status */
1794 return (stat);
1795}
1796
1797/*
1798 Release a Mutex that was acquired by osMutexAcquire.
1799*/
1801 SemaphoreHandle_t hMutex;
1802 osStatus_t stat;
1803 uint32_t rmtx;
1804
1805 hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1806
1807 /* Extract recursive mutex flag */
1808 rmtx = (uint32_t)mutex_id & 1U;
1809
1810 stat = osOK;
1811
1812 if (IRQ_Context() != 0U) {
1813 stat = osErrorISR;
1814 }
1815 else if (hMutex == NULL) {
1816 stat = osErrorParameter;
1817 }
1818 else {
1819 if (rmtx != 0U) {
1820 #if (configUSE_RECURSIVE_MUTEXES == 1)
1821 if (xSemaphoreGiveRecursive (hMutex) != pdPASS) {
1822 stat = osErrorResource;
1823 }
1824 #endif
1825 }
1826 else {
1827 if (xSemaphoreGive (hMutex) != pdPASS) {
1828 stat = osErrorResource;
1829 }
1830 }
1831 }
1832
1833 /* Return execution status */
1834 return (stat);
1835}
1836
1837/*
1838 Get Thread which owns a Mutex object.
1839*/
1841 SemaphoreHandle_t hMutex;
1843
1844 hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1845
1846 if ((IRQ_Context() != 0U) || (hMutex == NULL)) {
1847 owner = NULL;
1848 } else {
1849 owner = (osThreadId_t)xSemaphoreGetMutexHolder (hMutex);
1850 }
1851
1852 /* Return owner thread ID */
1853 return (owner);
1854}
1855
1856/*
1857 Delete a Mutex object.
1858*/
1860 osStatus_t stat;
1861#ifndef USE_FreeRTOS_HEAP_1
1862 SemaphoreHandle_t hMutex;
1863
1864 hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1865
1866 if (IRQ_Context() != 0U) {
1867 stat = osErrorISR;
1868 }
1869 else if (hMutex == NULL) {
1870 stat = osErrorParameter;
1871 }
1872 else {
1873 #if (configQUEUE_REGISTRY_SIZE > 0)
1874 vQueueUnregisterQueue (hMutex);
1875 #endif
1876 stat = osOK;
1877 vSemaphoreDelete (hMutex);
1878 }
1879#else
1880 stat = osError;
1881#endif
1882
1883 /* Return execution status */
1884 return (stat);
1885}
1886#endif /* (configUSE_OS2_MUTEX == 1) */
1887
1888
1889/* ==== Semaphore Management Functions ==== */
1890
1891/*
1892 Create and Initialize a Semaphore object.
1893*/
1894osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) {
1895 SemaphoreHandle_t hSemaphore;
1896 int32_t mem;
1897
1898 hSemaphore = NULL;
1899
1900 if ((IRQ_Context() == 0U) && (max_count > 0U) && (initial_count <= max_count)) {
1901 mem = -1;
1902
1903 if (attr != NULL) {
1904 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
1905 /* The memory for control block is provided, use static object */
1906 mem = 1;
1907 }
1908 else {
1909 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1910 /* Control block will be allocated from the dynamic pool */
1911 mem = 0;
1912 }
1913 }
1914 }
1915 else {
1916 mem = 0;
1917 }
1918
1919 if (mem != -1) {
1920 if (max_count == 1U) {
1921 if (mem == 1) {
1922 #if (configSUPPORT_STATIC_ALLOCATION == 1)
1923 hSemaphore = xSemaphoreCreateBinaryStatic ((StaticSemaphore_t *)attr->cb_mem);
1924 #endif
1925 }
1926 else {
1927 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1928 hSemaphore = xSemaphoreCreateBinary();
1929 #endif
1930 }
1931
1932 if ((hSemaphore != NULL) && (initial_count != 0U)) {
1933 if (xSemaphoreGive (hSemaphore) != pdPASS) {
1934 vSemaphoreDelete (hSemaphore);
1935 hSemaphore = NULL;
1936 }
1937 }
1938 }
1939 else {
1940 if (mem == 1) {
1941 #if (configSUPPORT_STATIC_ALLOCATION == 1)
1942 hSemaphore = xSemaphoreCreateCountingStatic (max_count, initial_count, (StaticSemaphore_t *)attr->cb_mem);
1943 #endif
1944 }
1945 else {
1946 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1947 hSemaphore = xSemaphoreCreateCounting (max_count, initial_count);
1948 #endif
1949 }
1950 }
1951
1952 #if (configQUEUE_REGISTRY_SIZE > 0)
1953 if (hSemaphore != NULL) {
1954 if ((attr != NULL) && (attr->name != NULL)) {
1955 /* Only non-NULL name objects are added to the Queue Registry */
1956 vQueueAddToRegistry (hSemaphore, attr->name);
1957 }
1958 }
1959 #endif
1960 }
1961 }
1962
1963 /* Return semaphore ID */
1964 return ((osSemaphoreId_t)hSemaphore);
1965}
1966
1967/*
1968 Acquire a Semaphore token or timeout if no tokens are available.
1969*/
1970osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) {
1971 SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
1972 osStatus_t stat;
1973 BaseType_t yield;
1974
1975 stat = osOK;
1976
1977 if (hSemaphore == NULL) {
1978 stat = osErrorParameter;
1979 }
1980 else if (IRQ_Context() != 0U) {
1981 if (timeout != 0U) {
1982 stat = osErrorParameter;
1983 }
1984 else {
1985 yield = pdFALSE;
1986
1987 if (xSemaphoreTakeFromISR (hSemaphore, &yield) != pdPASS) {
1988 stat = osErrorResource;
1989 } else {
1990 portYIELD_FROM_ISR (yield);
1991 }
1992 }
1993 }
1994 else {
1995 if (xSemaphoreTake (hSemaphore, (TickType_t)timeout) != pdPASS) {
1996 if (timeout != 0U) {
1997 stat = osErrorTimeout;
1998 } else {
1999 stat = osErrorResource;
2000 }
2001 }
2002 }
2003
2004 /* Return execution status */
2005 return (stat);
2006}
2007
2008/*
2009 Release a Semaphore token up to the initial maximum count.
2010*/
2012 SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
2013 osStatus_t stat;
2014 BaseType_t yield;
2015
2016 stat = osOK;
2017
2018 if (hSemaphore == NULL) {
2019 stat = osErrorParameter;
2020 }
2021 else if (IRQ_Context() != 0U) {
2022 yield = pdFALSE;
2023
2024 if (xSemaphoreGiveFromISR (hSemaphore, &yield) != pdTRUE) {
2025 stat = osErrorResource;
2026 } else {
2027 portYIELD_FROM_ISR (yield);
2028 }
2029 }
2030 else {
2031 if (xSemaphoreGive (hSemaphore) != pdPASS) {
2032 stat = osErrorResource;
2033 }
2034 }
2035
2036 /* Return execution status */
2037 return (stat);
2038}
2039
2040/*
2041 Get current Semaphore token count.
2042*/
2043uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id) {
2044 SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
2045 uint32_t count;
2046
2047 if (hSemaphore == NULL) {
2048 count = 0U;
2049 }
2050 else if (IRQ_Context() != 0U) {
2051 count = (uint32_t)uxSemaphoreGetCountFromISR (hSemaphore);
2052 } else {
2053 count = (uint32_t)uxSemaphoreGetCount (hSemaphore);
2054 }
2055
2056 /* Return number of tokens */
2057 return (count);
2058}
2059
2060/*
2061 Delete a Semaphore object.
2062*/
2064 SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
2065 osStatus_t stat;
2066
2067#ifndef USE_FreeRTOS_HEAP_1
2068 if (IRQ_Context() != 0U) {
2069 stat = osErrorISR;
2070 }
2071 else if (hSemaphore == NULL) {
2072 stat = osErrorParameter;
2073 }
2074 else {
2075 #if (configQUEUE_REGISTRY_SIZE > 0)
2076 vQueueUnregisterQueue (hSemaphore);
2077 #endif
2078
2079 stat = osOK;
2080 vSemaphoreDelete (hSemaphore);
2081 }
2082#else
2083 stat = osError;
2084#endif
2085
2086 /* Return execution status */
2087 return (stat);
2088}
2089
2090
2091/* ==== Message Queue Management Functions ==== */
2092
2093/*
2094 Create and Initialize a Message Queue object.
2095
2096 Limitations:
2097 - The memory for control block and and message data must be provided in the
2098 osThreadAttr_t structure in order to allocate object statically.
2099*/
2100osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) {
2101 QueueHandle_t hQueue;
2102 int32_t mem;
2103
2104 hQueue = NULL;
2105
2106 if ((IRQ_Context() == 0U) && (msg_count > 0U) && (msg_size > 0U)) {
2107 mem = -1;
2108
2109 if (attr != NULL) {
2110 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticQueue_t)) &&
2111 (attr->mq_mem != NULL) && (attr->mq_size >= (msg_count * msg_size))) {
2112 /* The memory for control block and message data is provided, use static object */
2113 mem = 1;
2114 }
2115 else {
2116 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) &&
2117 (attr->mq_mem == NULL) && (attr->mq_size == 0U)) {
2118 /* Control block will be allocated from the dynamic pool */
2119 mem = 0;
2120 }
2121 }
2122 }
2123 else {
2124 mem = 0;
2125 }
2126
2127 if (mem == 1) {
2128 #if (configSUPPORT_STATIC_ALLOCATION == 1)
2129 hQueue = xQueueCreateStatic (msg_count, msg_size, attr->mq_mem, attr->cb_mem);
2130 #endif
2131 }
2132 else {
2133 if (mem == 0) {
2134 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
2135 hQueue = xQueueCreate (msg_count, msg_size);
2136 #endif
2137 }
2138 }
2139
2140 #if (configQUEUE_REGISTRY_SIZE > 0)
2141 if (hQueue != NULL) {
2142 if ((attr != NULL) && (attr->name != NULL)) {
2143 /* Only non-NULL name objects are added to the Queue Registry */
2144 vQueueAddToRegistry (hQueue, attr->name);
2145 }
2146 }
2147 #endif
2148
2149 }
2150
2151 /* Return message queue ID */
2152 return ((osMessageQueueId_t)hQueue);
2153}
2154
2155/*
2156 Put a Message into a Queue or timeout if Queue is full.
2157
2158 Limitations:
2159 - Message priority is ignored
2160*/
2161osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) {
2162 QueueHandle_t hQueue = (QueueHandle_t)mq_id;
2163 osStatus_t stat;
2164 BaseType_t yield;
2165
2166 (void)msg_prio; /* Message priority is ignored */
2167
2168 stat = osOK;
2169
2170 if (IRQ_Context() != 0U) {
2171 if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
2172 stat = osErrorParameter;
2173 }
2174 else {
2175 yield = pdFALSE;
2176
2177 if (xQueueSendToBackFromISR (hQueue, msg_ptr, &yield) != pdTRUE) {
2178 stat = osErrorResource;
2179 } else {
2180 portYIELD_FROM_ISR (yield);
2181 }
2182 }
2183 }
2184 else {
2185 if ((hQueue == NULL) || (msg_ptr == NULL)) {
2186 stat = osErrorParameter;
2187 }
2188 else {
2189 if (xQueueSendToBack (hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) {
2190 if (timeout != 0U) {
2191 stat = osErrorTimeout;
2192 } else {
2193 stat = osErrorResource;
2194 }
2195 }
2196 }
2197 }
2198
2199 /* Return execution status */
2200 return (stat);
2201}
2202
2203/*
2204 Get a Message from a Queue or timeout if Queue is empty.
2205
2206 Limitations:
2207 - Message priority is ignored
2208*/
2209osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) {
2210 QueueHandle_t hQueue = (QueueHandle_t)mq_id;
2211 osStatus_t stat;
2212 BaseType_t yield;
2213
2214 (void)msg_prio; /* Message priority is ignored */
2215
2216 stat = osOK;
2217
2218 if (IRQ_Context() != 0U) {
2219 if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
2220 stat = osErrorParameter;
2221 }
2222 else {
2223 yield = pdFALSE;
2224
2225 if (xQueueReceiveFromISR (hQueue, msg_ptr, &yield) != pdPASS) {
2226 stat = osErrorResource;
2227 } else {
2228 portYIELD_FROM_ISR (yield);
2229 }
2230 }
2231 }
2232 else {
2233 if ((hQueue == NULL) || (msg_ptr == NULL)) {
2234 stat = osErrorParameter;
2235 }
2236 else {
2237 if (xQueueReceive (hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) {
2238 if (timeout != 0U) {
2239 stat = osErrorTimeout;
2240 } else {
2241 stat = osErrorResource;
2242 }
2243 }
2244 }
2245 }
2246
2247 /* Return execution status */
2248 return (stat);
2249}
2250
2251/*
2252 Get maximum number of messages in a Message Queue.
2253*/
2255 StaticQueue_t *mq = (StaticQueue_t *)mq_id;
2256 uint32_t capacity;
2257
2258 if (mq == NULL) {
2259 capacity = 0U;
2260 } else {
2261 /* capacity = pxQueue->uxLength */
2262 capacity = mq->uxDummy4[1];
2263 }
2264
2265 /* Return maximum number of messages */
2266 return (capacity);
2267}
2268
2269/*
2270 Get maximum message size in a Message Queue.
2271*/
2273 StaticQueue_t *mq = (StaticQueue_t *)mq_id;
2274 uint32_t size;
2275
2276 if (mq == NULL) {
2277 size = 0U;
2278 } else {
2279 /* size = pxQueue->uxItemSize */
2280 size = mq->uxDummy4[2];
2281 }
2282
2283 /* Return maximum message size */
2284 return (size);
2285}
2286
2287/*
2288 Get number of queued messages in a Message Queue.
2289*/
2291 QueueHandle_t hQueue = (QueueHandle_t)mq_id;
2293
2294 if (hQueue == NULL) {
2295 count = 0U;
2296 }
2297 else if (IRQ_Context() != 0U) {
2299 }
2300 else {
2301 count = uxQueueMessagesWaiting (hQueue);
2302 }
2303
2304 /* Return number of queued messages */
2305 return ((uint32_t)count);
2306}
2307
2308/*
2309 Get number of available slots for messages in a Message Queue.
2310*/
2312 StaticQueue_t *mq = (StaticQueue_t *)mq_id;
2313 uint32_t space;
2314 uint32_t isrm;
2315
2316 if (mq == NULL) {
2317 space = 0U;
2318 }
2319 else if (IRQ_Context() != 0U) {
2321
2322 /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */
2323 space = mq->uxDummy4[1] - mq->uxDummy4[0];
2324
2326 }
2327 else {
2328 space = (uint32_t)uxQueueSpacesAvailable ((QueueHandle_t)mq);
2329 }
2330
2331 /* Return number of available slots */
2332 return (space);
2333}
2334
2335/*
2336 Reset a Message Queue to initial empty state.
2337*/
2339 QueueHandle_t hQueue = (QueueHandle_t)mq_id;
2340 osStatus_t stat;
2341
2342 if (IRQ_Context() != 0U) {
2343 stat = osErrorISR;
2344 }
2345 else if (hQueue == NULL) {
2346 stat = osErrorParameter;
2347 }
2348 else {
2349 stat = osOK;
2350 (void)xQueueReset (hQueue);
2351 }
2352
2353 /* Return execution status */
2354 return (stat);
2355}
2356
2357/*
2358 Delete a Message Queue object.
2359*/
2361 QueueHandle_t hQueue = (QueueHandle_t)mq_id;
2362 osStatus_t stat;
2363
2364#ifndef USE_FreeRTOS_HEAP_1
2365 if (IRQ_Context() != 0U) {
2366 stat = osErrorISR;
2367 }
2368 else if (hQueue == NULL) {
2369 stat = osErrorParameter;
2370 }
2371 else {
2372 #if (configQUEUE_REGISTRY_SIZE > 0)
2373 vQueueUnregisterQueue (hQueue);
2374 #endif
2375
2376 stat = osOK;
2377 vQueueDelete (hQueue);
2378 }
2379#else
2380 stat = osError;
2381#endif
2382
2383 /* Return execution status */
2384 return (stat);
2385}
2386
2387
2388/* ==== Memory Pool Management Functions ==== */
2389
2390#ifdef FREERTOS_MPOOL_H_
2391/* Static memory pool functions */
2392static void FreeBlock (MemPool_t *mp, void *block);
2393static void *AllocBlock (MemPool_t *mp);
2394static void *CreateBlock (MemPool_t *mp);
2395
2396/*
2397 Create and Initialize a Memory Pool object.
2398*/
2399osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) {
2400 MemPool_t *mp;
2401 const char *name;
2402 int32_t mem_cb, mem_mp;
2403 uint32_t sz;
2404
2405 if (IRQ_Context() != 0U) {
2406 mp = NULL;
2407 }
2408 else if ((block_count == 0U) || (block_size == 0U)) {
2409 mp = NULL;
2410 }
2411 else {
2412 mp = NULL;
2413 sz = MEMPOOL_ARR_SIZE (block_count, block_size);
2414
2415 name = NULL;
2416 mem_cb = -1;
2417 mem_mp = -1;
2418
2419 if (attr != NULL) {
2420 if (attr->name != NULL) {
2421 name = attr->name;
2422 }
2423
2424 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(MemPool_t))) {
2425 /* Static control block is provided */
2426 mem_cb = 1;
2427 }
2428 else if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
2429 /* Allocate control block memory on heap */
2430 mem_cb = 0;
2431 }
2432
2433 if ((attr->mp_mem == NULL) && (attr->mp_size == 0U)) {
2434 /* Allocate memory array on heap */
2435 mem_mp = 0;
2436 }
2437 else {
2438 if (attr->mp_mem != NULL) {
2439 /* Check if array is 4-byte aligned */
2440 if (((uint32_t)attr->mp_mem & 3U) == 0U) {
2441 /* Check if array big enough */
2442 if (attr->mp_size >= sz) {
2443 /* Static memory pool array is provided */
2444 mem_mp = 1;
2445 }
2446 }
2447 }
2448 }
2449 }
2450 else {
2451 /* Attributes not provided, allocate memory on heap */
2452 mem_cb = 0;
2453 mem_mp = 0;
2454 }
2455
2456 if (mem_cb == 0) {
2457 mp = pvPortMalloc (sizeof(MemPool_t));
2458 } else {
2459 mp = attr->cb_mem;
2460 }
2461
2462 if (mp != NULL) {
2463 /* Create a semaphore (max count == initial count == block_count) */
2464 #if (configSUPPORT_STATIC_ALLOCATION == 1)
2465 mp->sem = xSemaphoreCreateCountingStatic (block_count, block_count, &mp->mem_sem);
2466 #elif (configSUPPORT_DYNAMIC_ALLOCATION == 1)
2467 mp->sem = xSemaphoreCreateCounting (block_count, block_count);
2468 #else
2469 mp->sem = NULL;
2470 #endif
2471
2472 if (mp->sem != NULL) {
2473 /* Setup memory array */
2474 if (mem_mp == 0) {
2475 mp->mem_arr = pvPortMalloc (sz);
2476 } else {
2477 mp->mem_arr = attr->mp_mem;
2478 }
2479 }
2480 }
2481
2482 if ((mp != NULL) && (mp->mem_arr != NULL)) {
2483 /* Memory pool can be created */
2484 mp->head = NULL;
2485 mp->mem_sz = sz;
2486 mp->name = name;
2487 mp->bl_sz = block_size;
2488 mp->bl_cnt = block_count;
2489 mp->n = 0U;
2490
2491 /* Set heap allocated memory flags */
2492 mp->status = MPOOL_STATUS;
2493
2494 if (mem_cb == 0) {
2495 /* Control block on heap */
2496 mp->status |= 1U;
2497 }
2498 if (mem_mp == 0) {
2499 /* Memory array on heap */
2500 mp->status |= 2U;
2501 }
2502 }
2503 else {
2504 /* Memory pool cannot be created, release allocated resources */
2505 if ((mem_cb == 0) && (mp != NULL)) {
2506 /* Free control block memory */
2507 vPortFree (mp);
2508 }
2509 mp = NULL;
2510 }
2511 }
2512
2513 /* Return memory pool ID */
2514 return (mp);
2515}
2516
2517/*
2518 Get name of a Memory Pool object.
2519*/
2520const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id) {
2521 MemPool_t *mp = (osMemoryPoolId_t)mp_id;
2522 const char *p;
2523
2524 if (IRQ_Context() != 0U) {
2525 p = NULL;
2526 }
2527 else if (mp_id == NULL) {
2528 p = NULL;
2529 }
2530 else {
2531 p = mp->name;
2532 }
2533
2534 /* Return name as null-terminated string */
2535 return (p);
2536}
2537
2538/*
2539 Allocate a memory block from a Memory Pool.
2540*/
2541void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) {
2542 MemPool_t *mp;
2543 void *block;
2544 uint32_t isrm;
2545
2546 if (mp_id == NULL) {
2547 /* Invalid input parameters */
2548 block = NULL;
2549 }
2550 else {
2551 block = NULL;
2552
2553 mp = (MemPool_t *)mp_id;
2554
2555 if ((mp->status & MPOOL_STATUS) == MPOOL_STATUS) {
2556 if (IRQ_Context() != 0U) {
2557 if (timeout == 0U) {
2558 if (xSemaphoreTakeFromISR (mp->sem, NULL) == pdTRUE) {
2559 if ((mp->status & MPOOL_STATUS) == MPOOL_STATUS) {
2561
2562 /* Get a block from the free-list */
2563 block = AllocBlock(mp);
2564
2565 if (block == NULL) {
2566 /* List of free blocks is empty, 'create' new block */
2567 block = CreateBlock(mp);
2568 }
2569
2571 }
2572 }
2573 }
2574 }
2575 else {
2576 if (xSemaphoreTake (mp->sem, (TickType_t)timeout) == pdTRUE) {
2577 if ((mp->status & MPOOL_STATUS) == MPOOL_STATUS) {
2579
2580 /* Get a block from the free-list */
2581 block = AllocBlock(mp);
2582
2583 if (block == NULL) {
2584 /* List of free blocks is empty, 'create' new block */
2585 block = CreateBlock(mp);
2586 }
2587
2589 }
2590 }
2591 }
2592 }
2593 }
2594
2595 /* Return memory block address */
2596 return (block);
2597}
2598
2599/*
2600 Return an allocated memory block back to a Memory Pool.
2601*/
2602osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) {
2603 MemPool_t *mp;
2604 osStatus_t stat;
2605 uint32_t isrm;
2606 BaseType_t yield;
2607
2608 if ((mp_id == NULL) || (block == NULL)) {
2609 /* Invalid input parameters */
2610 stat = osErrorParameter;
2611 }
2612 else {
2613 mp = (MemPool_t *)mp_id;
2614
2615 if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
2616 /* Invalid object status */
2617 stat = osErrorResource;
2618 }
2619 else if ((block < (void *)&mp->mem_arr[0]) || (block > (void*)&mp->mem_arr[mp->mem_sz-1])) {
2620 /* Block pointer outside of memory array area */
2621 stat = osErrorParameter;
2622 }
2623 else {
2624 stat = osOK;
2625
2626 if (IRQ_Context() != 0U) {
2627 if (uxSemaphoreGetCountFromISR (mp->sem) == mp->bl_cnt) {
2628 stat = osErrorResource;
2629 }
2630 else {
2632
2633 /* Add block to the list of free blocks */
2634 FreeBlock(mp, block);
2635
2637
2638 yield = pdFALSE;
2639 xSemaphoreGiveFromISR (mp->sem, &yield);
2640 portYIELD_FROM_ISR (yield);
2641 }
2642 }
2643 else {
2644 if (uxSemaphoreGetCount (mp->sem) == mp->bl_cnt) {
2645 stat = osErrorResource;
2646 }
2647 else {
2649
2650 /* Add block to the list of free blocks */
2651 FreeBlock(mp, block);
2652
2654
2655 xSemaphoreGive (mp->sem);
2656 }
2657 }
2658 }
2659 }
2660
2661 /* Return execution status */
2662 return (stat);
2663}
2664
2665/*
2666 Get maximum number of memory blocks in a Memory Pool.
2667*/
2669 MemPool_t *mp;
2670 uint32_t n;
2671
2672 if (mp_id == NULL) {
2673 /* Invalid input parameters */
2674 n = 0U;
2675 }
2676 else {
2677 mp = (MemPool_t *)mp_id;
2678
2679 if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
2680 /* Invalid object status */
2681 n = 0U;
2682 }
2683 else {
2684 n = mp->bl_cnt;
2685 }
2686 }
2687
2688 /* Return maximum number of memory blocks */
2689 return (n);
2690}
2691
2692/*
2693 Get memory block size in a Memory Pool.
2694*/
2696 MemPool_t *mp;
2697 uint32_t sz;
2698
2699 if (mp_id == NULL) {
2700 /* Invalid input parameters */
2701 sz = 0U;
2702 }
2703 else {
2704 mp = (MemPool_t *)mp_id;
2705
2706 if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
2707 /* Invalid object status */
2708 sz = 0U;
2709 }
2710 else {
2711 sz = mp->bl_sz;
2712 }
2713 }
2714
2715 /* Return memory block size in bytes */
2716 return (sz);
2717}
2718
2719/*
2720 Get number of memory blocks used in a Memory Pool.
2721*/
2722uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id) {
2723 MemPool_t *mp;
2724 uint32_t n;
2725
2726 if (mp_id == NULL) {
2727 /* Invalid input parameters */
2728 n = 0U;
2729 }
2730 else {
2731 mp = (MemPool_t *)mp_id;
2732
2733 if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
2734 /* Invalid object status */
2735 n = 0U;
2736 }
2737 else {
2738 if (IRQ_Context() != 0U) {
2740 } else {
2741 n = uxSemaphoreGetCount (mp->sem);
2742 }
2743
2744 n = mp->bl_cnt - n;
2745 }
2746 }
2747
2748 /* Return number of memory blocks used */
2749 return (n);
2750}
2751
2752/*
2753 Get number of memory blocks available in a Memory Pool.
2754*/
2755uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id) {
2756 MemPool_t *mp;
2757 uint32_t n;
2758
2759 if (mp_id == NULL) {
2760 /* Invalid input parameters */
2761 n = 0U;
2762 }
2763 else {
2764 mp = (MemPool_t *)mp_id;
2765
2766 if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
2767 /* Invalid object status */
2768 n = 0U;
2769 }
2770 else {
2771 if (IRQ_Context() != 0U) {
2773 } else {
2774 n = uxSemaphoreGetCount (mp->sem);
2775 }
2776 }
2777 }
2778
2779 /* Return number of memory blocks available */
2780 return (n);
2781}
2782
2783/*
2784 Delete a Memory Pool object.
2785*/
2787 MemPool_t *mp;
2788 osStatus_t stat;
2789
2790 if (mp_id == NULL) {
2791 /* Invalid input parameters */
2792 stat = osErrorParameter;
2793 }
2794 else if (IRQ_Context() != 0U) {
2795 stat = osErrorISR;
2796 }
2797 else {
2798 mp = (MemPool_t *)mp_id;
2799
2801
2802 /* Invalidate control block status */
2803 mp->status = mp->status & 3U;
2804
2805 /* Wake-up tasks waiting for pool semaphore */
2806 while (xSemaphoreGive (mp->sem) == pdTRUE);
2807
2808 mp->head = NULL;
2809 mp->bl_sz = 0U;
2810 mp->bl_cnt = 0U;
2811
2812 if ((mp->status & 2U) != 0U) {
2813 /* Memory pool array allocated on heap */
2814 vPortFree (mp->mem_arr);
2815 }
2816 if ((mp->status & 1U) != 0U) {
2817 /* Memory pool control block allocated on heap */
2818 vPortFree (mp);
2819 }
2820
2822
2823 stat = osOK;
2824 }
2825
2826 /* Return execution status */
2827 return (stat);
2828}
2829
2830/*
2831 Create new block given according to the current block index.
2832*/
2833static void *CreateBlock (MemPool_t *mp) {
2835
2836 if (mp->n < mp->bl_cnt) {
2837 /* Unallocated blocks exist, set pointer to new block */
2838 p = (void *)(mp->mem_arr + (mp->bl_sz * mp->n));
2839
2840 /* Increment block index */
2841 mp->n += 1U;
2842 }
2843
2844 return (p);
2845}
2846
2847/*
2848 Allocate a block by reading the list of free blocks.
2849*/
2850static void *AllocBlock (MemPool_t *mp) {
2852
2853 if (mp->head != NULL) {
2854 /* List of free block exists, get head block */
2855 p = mp->head;
2856
2857 /* Head block is now next on the list */
2858 mp->head = p->next;
2859 }
2860
2861 return (p);
2862}
2863
2864/*
2865 Free block by putting it to the list of free blocks.
2866*/
2867static void FreeBlock (MemPool_t *mp, void *block) {
2868 MemPoolBlock_t *p = block;
2869
2870 /* Store current head into block memory space */
2871 p->next = mp->head;
2872
2873 /* Store current block as new head */
2874 mp->head = p;
2875}
2876#endif /* FREERTOS_MPOOL_H_ */
2877/*---------------------------------------------------------------------------*/
2878
2879/* Callback function prototypes */
2880extern void vApplicationIdleHook (void);
2881extern void vApplicationMallocFailedHook (void);
2883
2884/**
2885 Dummy implementation of the callback function vApplicationIdleHook().
2886*/
2887#if (configUSE_IDLE_HOOK == 1)
2888__WEAK void vApplicationIdleHook (void){}
2889#endif
2890
2891/**
2892 Dummy implementation of the callback function vApplicationTickHook().
2893*/
2894#if (configUSE_TICK_HOOK == 1)
2895 __WEAK void vApplicationTickHook (void){}
2896#endif
2897
2898/**
2899 Dummy implementation of the callback function vApplicationMallocFailedHook().
2900*/
2901#if (configUSE_MALLOC_FAILED_HOOK == 1)
2903 /* Assert when malloc failed hook is enabled but no application defined function exists */
2904 configASSERT(0);
2905}
2906#endif
2907
2908/**
2909 Dummy implementation of the callback function vApplicationDaemonTaskStartupHook().
2910*/
2911#if (configUSE_DAEMON_TASK_STARTUP_HOOK == 1)
2913#endif
2914
2915/**
2916 Dummy implementation of the callback function vApplicationStackOverflowHook().
2917*/
2918#if (configCHECK_FOR_STACK_OVERFLOW > 0)
2919__WEAK void vApplicationStackOverflowHook (TaskHandle_t xTask, char *pcTaskName) {
2920 (void)xTask;
2921 (void)pcTaskName;
2922
2923 /* Assert when stack overflow is enabled but no application defined function exists */
2924 configASSERT(0);
2925}
2926#endif
2927
2928/*---------------------------------------------------------------------------*/
2929#if (configSUPPORT_STATIC_ALLOCATION == 1)
2930/*
2931 vApplicationGetIdleTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
2932 equals to 1 and is required for static memory allocation support.
2933*/
2934__WEAK void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {
2935 /* Idle task control block and stack */
2936 static StaticTask_t Idle_TCB;
2937 static StackType_t Idle_Stack[configMINIMAL_STACK_SIZE];
2938
2939 *ppxIdleTaskTCBBuffer = &Idle_TCB;
2940 *ppxIdleTaskStackBuffer = &Idle_Stack[0];
2941 *pulIdleTaskStackSize = (uint32_t)configMINIMAL_STACK_SIZE;
2942}
2943
2944/*
2945 vApplicationGetTimerTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
2946 equals to 1 and is required for static memory allocation support.
2947*/
2948__WEAK void vApplicationGetTimerTaskMemory (StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) {
2949 /* Timer task control block and stack */
2950 static StaticTask_t Timer_TCB;
2951 static StackType_t Timer_Stack[configTIMER_TASK_STACK_DEPTH];
2952
2953 *ppxTimerTaskTCBBuffer = &Timer_TCB;
2954 *ppxTimerTaskStackBuffer = &Timer_Stack[0];
2955 *pulTimerTaskStackSize = (uint32_t)configTIMER_TASK_STACK_DEPTH;
2956}
2957#endif
#define configASSERT(x)
#define configTICK_RATE_HZ
#define configMINIMAL_STACK_SIZE
#define configTOTAL_HEAP_SIZE
#define configCPU_CLOCK_HZ
#define configTIMER_TASK_STACK_DEPTH
struct xSTATIC_QUEUE StaticQueue_t
#define vQueueAddToRegistry(xQueue, pcName)
Definition FreeRTOS.h:403
StaticQueue_t StaticSemaphore_t
Definition FreeRTOS.h:1367
struct xSTATIC_TIMER StaticTimer_t
#define configSTACK_DEPTH_TYPE
Definition FreeRTOS.h:998
struct xSTATIC_TCB StaticTask_t
#define vQueueUnregisterQueue(xQueue)
Definition FreeRTOS.h:404
struct xSTATIC_EVENT_GROUP StaticEventGroup_t
void delay(int ms)
static osThreadId_t volatile owner
Definition board_uart9.c:14
static std::atomic< bool > running
#define __NO_RETURN
Definition cmsis_armcc.h:70
#define __STATIC_INLINE
Definition cmsis_armcc.h:64
#define __WEAK
Definition cmsis_armcc.h:76
CMSIS compiler generic header file.
#define KERNEL_VERSION
Definition cmsis_os2.c:86
osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id)
Release a Semaphore token up to the initial maximum count.
Definition cmsis_os2.c:2011
osPriority_t osThreadGetPriority(osThreadId_t thread_id)
Get current priority of a thread.
Definition cmsis_os2.c:746
osMessageQueueId_t osMessageQueueNew(uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr)
Create and Initialize a Message Queue object.
Definition cmsis_os2.c:2100
osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr)
Create and Initialize a Semaphore object.
Definition cmsis_os2.c:1894
#define EVENT_FLAGS_INVALID_BITS
Definition cmsis_os2.c:83
osStatus_t osThreadTerminate(osThreadId_t thread_id)
Terminate execution of a thread.
Definition cmsis_os2.c:836
uint32_t osEventFlagsSet(osEventFlagsId_t ef_id, uint32_t flags)
Set the specified Event Flags.
Definition cmsis_os2.c:1465
static osKernelState_t KernelState
Definition cmsis_os2.c:99
__STATIC_INLINE void SVC_Setup(void)
Definition cmsis_os2.c:181
osStatus_t osDelayUntil(uint32_t ticks)
Wait until specified time.
Definition cmsis_os2.c:1115
osStatus_t osThreadResume(osThreadId_t thread_id)
Resume execution of a thread.
Definition cmsis_os2.c:803
static uint32_t OS_Tick_GetOverflow(void)
Definition cmsis_os2.c:239
osKernelState_t osKernelGetState(void)
Get the current RTOS Kernel state.
Definition cmsis_os2.c:322
osThreadId_t osThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr)
Create a thread and add it to Active Threads.
Definition cmsis_os2.c:577
uint32_t osThreadGetCount(void)
Get number of active threads.
Definition cmsis_os2.c:869
uint32_t osKernelGetSysTimerFreq(void)
Get the RTOS kernel system timer frequency.
Definition cmsis_os2.c:561
uint32_t osEventFlagsWait(osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout)
Wait for one or more Event Flags to become signaled.
Definition cmsis_os2.c:1569
static uint32_t OS_Tick_GetCount(void)
Definition cmsis_os2.c:228
uint32_t osThreadEnumerate(osThreadId_t *thread_array, uint32_t array_items)
Enumerate active threads.
Definition cmsis_os2.c:886
#define IS_IRQ_MASKED()
Definition cmsis_os2.c:65
uint32_t osMessageQueueGetCount(osMessageQueueId_t mq_id)
Get number of queued messages in a Message Queue.
Definition cmsis_os2.c:2290
osStatus_t osKernelGetInfo(osVersion_t *version, char *id_buf, uint32_t id_size)
Get RTOS Kernel Information.
Definition cmsis_os2.c:298
uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id)
Get current Semaphore token count.
Definition cmsis_os2.c:2043
uint32_t osKernelGetTickFreq(void)
Get the RTOS kernel tick frequency.
Definition cmsis_os2.c:507
osStatus_t osEventFlagsDelete(osEventFlagsId_t ef_id)
Delete an Event Flags object.
Definition cmsis_os2.c:1629
osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout)
Acquire a Semaphore token or timeout if no tokens are available.
Definition cmsis_os2.c:1970
osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id)
Delete a Semaphore object.
Definition cmsis_os2.c:2063
uint32_t osKernelGetTickCount(void)
Get the RTOS kernel tick count.
Definition cmsis_os2.c:491
osStatus_t osThreadSetPriority(osThreadId_t thread_id, osPriority_t priority)
Change priority of a thread.
Definition cmsis_os2.c:724
uint32_t osEventFlagsGet(osEventFlagsId_t ef_id)
Get the current Event Flags.
Definition cmsis_os2.c:1544
osThreadId_t osThreadGetId(void)
Return the thread ID of the current running thread.
Definition cmsis_os2.c:669
uint32_t osEventFlagsClear(osEventFlagsId_t ef_id, uint32_t flags)
Clear the specified Event Flags.
Definition cmsis_os2.c:1505
int32_t osKernelLock(void)
Lock the RTOS Kernel scheduler.
Definition cmsis_os2.c:384
uint32_t osMessageQueueGetMsgSize(osMessageQueueId_t mq_id)
Get maximum message size in a Message Queue.
Definition cmsis_os2.c:2272
void vApplicationIdleHook(void)
osStatus_t osKernelStart(void)
Start the RTOS Kernel scheduler.
Definition cmsis_os2.c:353
uint32_t osThreadGetStackSpace(osThreadId_t thread_id)
Get available stack space of a thread based on stack watermark recording during execution.
Definition cmsis_os2.c:707
osStatus_t osMessageQueuePut(osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout)
Put a Message into a Queue or timeout if Queue is full.
Definition cmsis_os2.c:2161
osStatus_t osThreadSuspend(osThreadId_t thread_id)
Suspend execution of a thread.
Definition cmsis_os2.c:781
osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t *attr)
Create and Initialize an Event Flags object.
Definition cmsis_os2.c:1416
#define THREAD_FLAGS_INVALID_BITS
Definition cmsis_os2.c:82
#define KERNEL_ID
Definition cmsis_os2.c:90
void vApplicationMallocFailedHook(void)
Definition freertos.c:69
#define IS_IRQ_MODE()
Definition cmsis_os2.c:75
void vApplicationDaemonTaskStartupHook(void)
osStatus_t osMessageQueueDelete(osMessageQueueId_t mq_id)
Delete a Message Queue object.
Definition cmsis_os2.c:2360
uint32_t osMessageQueueGetCapacity(osMessageQueueId_t mq_id)
Get maximum number of messages in a Message Queue.
Definition cmsis_os2.c:2254
const char * osThreadGetName(osThreadId_t thread_id)
Get name of a thread.
Definition cmsis_os2.c:652
osStatus_t osMessageQueueReset(osMessageQueueId_t mq_id)
Reset a Message Queue to initial empty state.
Definition cmsis_os2.c:2338
osThreadState_t osThreadGetState(osThreadId_t thread_id)
Get current thread state of a thread.
Definition cmsis_os2.c:681
__STATIC_INLINE uint32_t IRQ_Context(void)
Definition cmsis_os2.c:200
osStatus_t osThreadYield(void)
Pass control to next thread that is in state READY.
Definition cmsis_os2.c:763
static uint32_t OS_Tick_GetInterval(void)
Definition cmsis_os2.c:251
osStatus_t osMessageQueueGet(osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout)
Get a Message from a Queue or timeout if Queue is empty.
Definition cmsis_os2.c:2209
__NO_RETURN void osThreadExit(void)
Terminate execution of current running thread.
Definition cmsis_os2.c:826
uint32_t osMessageQueueGetSpace(osMessageQueueId_t mq_id)
Get number of available slots for messages in a Message Queue.
Definition cmsis_os2.c:2311
uint32_t osKernelGetSysTimerCount(void)
Get the RTOS kernel system timer count.
Definition cmsis_os2.c:515
int32_t osKernelRestoreLock(int32_t lock)
Restore the RTOS Kernel scheduler lock state.
Definition cmsis_os2.c:451
osStatus_t osKernelInitialize(void)
Initialize the RTOS Kernel.
Definition cmsis_os2.c:264
int32_t osKernelUnlock(void)
Unlock the RTOS Kernel scheduler.
Definition cmsis_os2.c:415
osStatus_t osDelay(uint32_t ticks)
Wait for Timeout (Time Delay).
Definition cmsis_os2.c:1094
uint32_t osMemoryPoolGetSpace(osMemoryPoolId_t mp_id)
Get number of memory blocks available in a Memory Pool.
osKernelState_t
Kernel state.
Definition cmsis_os2.h:82
@ osKernelLocked
Locked.
Definition cmsis_os2.h:86
@ osKernelReady
Ready.
Definition cmsis_os2.h:84
@ osKernelRunning
Running.
Definition cmsis_os2.h:85
@ osKernelInactive
Inactive.
Definition cmsis_os2.h:83
void * osMessageQueueId_t
Definition cmsis_os2.h:229
#define osThreadJoinable
Thread created in joinable mode.
Definition cmsis_os2.h:190
void * osMutexId_t
Definition cmsis_os2.h:220
osMemoryPoolId_t osMemoryPoolNew(uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr)
Create and Initialize a Memory Pool object.
void * osSemaphoreId_t
Definition cmsis_os2.h:223
void * osThreadId_t
Definition cmsis_os2.h:211
uint32_t osThreadFlagsClear(uint32_t flags)
Clear the specified Thread Flags of current running thread.
#define osMutexRecursive
Recursive mutex.
Definition cmsis_os2.h:193
uint32_t osTimerIsRunning(osTimerId_t timer_id)
Check if a timer is running.
osStatus_t
Status code values returned by CMSIS-RTOS functions.
Definition cmsis_os2.h:198
@ osErrorISR
Not allowed in ISR context: the function cannot be called from interrupt service routines.
Definition cmsis_os2.h:205
@ osErrorResource
Resource not available.
Definition cmsis_os2.h:202
@ osErrorTimeout
Operation not completed within the timeout period.
Definition cmsis_os2.h:201
@ osOK
Operation completed successfully.
Definition cmsis_os2.h:199
@ osError
Unspecified RTOS error: run-time error but no other error message fits.
Definition cmsis_os2.h:200
@ osErrorParameter
Parameter error.
Definition cmsis_os2.h:203
uint32_t osThreadFlagsSet(osThreadId_t thread_id, uint32_t flags)
Set the specified Thread Flags of a thread.
void(* osTimerFunc_t)(void *argument)
Timer callback function.
Definition cmsis_os2.h:164
const char * osTimerGetName(osTimerId_t timer_id)
Get name of a timer.
osTimerType_t
Timer type.
Definition cmsis_os2.h:167
@ osTimerOnce
One-shot timer.
Definition cmsis_os2.h:168
osThreadId_t osMutexGetOwner(osMutexId_t mutex_id)
Get Thread which owns a Mutex object.
uint32_t osThreadFlagsGet(void)
Get the current Thread Flags of current running thread.
#define osFlagsWaitAll
Wait for all flags.
Definition cmsis_os2.h:177
osStatus_t osMemoryPoolDelete(osMemoryPoolId_t mp_id)
Delete a Memory Pool object.
void * osMemoryPoolAlloc(osMemoryPoolId_t mp_id, uint32_t timeout)
Allocate a memory block from a Memory Pool.
void(* osThreadFunc_t)(void *argument)
Entry point of a thread.
Definition cmsis_os2.h:161
uint32_t osMemoryPoolGetCount(osMemoryPoolId_t mp_id)
Get number of memory blocks used in a Memory Pool.
#define osFlagsErrorParameter
osErrorParameter (-4).
Definition cmsis_os2.h:185
#define osFlagsNoClear
Do not clear flags which have been specified to wait for.
Definition cmsis_os2.h:178
uint32_t osMemoryPoolGetBlockSize(osMemoryPoolId_t mp_id)
Get memory block size in a Memory Pool.
const char * osMemoryPoolGetName(osMemoryPoolId_t mp_id)
Get name of a Memory Pool object.
osStatus_t osTimerStart(osTimerId_t timer_id, uint32_t ticks)
Start or restart a timer.
osMutexId_t osMutexNew(const osMutexAttr_t *attr)
Create and Initialize a Mutex object.
osStatus_t osMemoryPoolFree(osMemoryPoolId_t mp_id, void *block)
Return an allocated memory block back to a Memory Pool.
osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout)
Acquire a Mutex or timeout if it is locked.
osStatus_t osTimerStop(osTimerId_t timer_id)
Stop a timer.
void * osMemoryPoolId_t
Definition cmsis_os2.h:226
osStatus_t osMutexDelete(osMutexId_t mutex_id)
Delete a Mutex object.
uint32_t osThreadFlagsWait(uint32_t flags, uint32_t options, uint32_t timeout)
Wait for one or more Thread Flags of the current running thread to become signaled.
void * osTimerId_t
Definition cmsis_os2.h:214
osStatus_t osTimerDelete(osTimerId_t timer_id)
Delete a timer.
osThreadState_t
Thread state.
Definition cmsis_os2.h:93
@ osThreadBlocked
Blocked.
Definition cmsis_os2.h:97
@ osThreadRunning
Running.
Definition cmsis_os2.h:96
@ osThreadError
Error.
Definition cmsis_os2.h:99
@ osThreadReady
Ready.
Definition cmsis_os2.h:95
osPriority_t
Priority values.
Definition cmsis_os2.h:104
@ osPriorityISR
Reserved for ISR deferred thread.
Definition cmsis_os2.h:155
@ osPriorityNormal
Priority: normal.
Definition cmsis_os2.h:123
@ osPriorityIdle
Reserved for Idle thread.
Definition cmsis_os2.h:106
@ osPriorityNone
No priority (not initialized).
Definition cmsis_os2.h:105
@ osPriorityError
System cannot determine priority or illegal priority.
Definition cmsis_os2.h:156
osTimerId_t osTimerNew(osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr)
Create and Initialize a timer.
uint32_t osMemoryPoolGetCapacity(osMemoryPoolId_t mp_id)
Get maximum number of memory blocks in a Memory Pool.
osStatus_t osMutexRelease(osMutexId_t mutex_id)
Release a Mutex that was acquired by osMutexAcquire.
void * osEventFlagsId_t
Definition cmsis_os2.h:217
#define osMutexRobust
Robust mutex.
Definition cmsis_os2.h:195
EventBits_t xEventGroupWaitBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait)
void vEventGroupDelete(EventGroupHandle_t xEventGroup)
event_groups.h
EventBits_t xEventGroupClearBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear)
EventBits_t xEventGroupSetBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet)
EventBits_t xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup)
#define xEventGroupGetBits(xEventGroup)
#define xEventGroupClearBitsFromISR(xEventGroup, uxBitsToClear)
#define xEventGroupSetBitsFromISR(xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken)
TickType_t EventBits_t
struct EventGroupDef_t * EventGroupHandle_t
static ActuatorControllerState state
Definition main.cpp:57
int32_t p
Definition flight_e2e.c:78
void vApplicationStackOverflowHook(xTaskHandle xTask, char *pcTaskName)
File Name : freertos.c Description : Code for freertos applications.
Definition freertos.c:60
#define MEMPOOL_ARR_SIZE(bl_count, bl_size)
struct MemPoolDef_t MemPool_t
#define MPOOL_STATUS
#define SysTick
SysTick configuration struct.
#define NVIC_SetPriority
#define __enable_irq
Enable IRQ Interrupts.
#define __disable_irq
Disable IRQ Interrupts.
@ SVCall_IRQn
11 Cortex-M SV Call Interrupt
Definition stm32h723xx.h:56
#define NULL
Definition usbd_def.h:44
static PRIVILEGED_DATA uint8_t ucHeap[configTOTAL_HEAP_SIZE]
Definition heap_4.c:92
size_type count(const key_type &key) const
Definition json.hpp:19264
static osMutexId_t lock
Definition mode.c:11
*brief user defined string literal for JSON values *sa std::size_t n
Definition json.hpp:24474
void xPortSysTickHandler(void)
Definition port.c:517
void vPortDefineHeapRegions(const HeapRegion_t *const pxHeapRegions) PRIVILEGED_FUNCTION
void vPortFree(void *pv) PRIVILEGED_FUNCTION
Definition heap_4.c:307
void * pvPortMalloc(size_t xSize) PRIVILEGED_FUNCTION
struct HeapRegion HeapRegion_t
long BaseType_t
Definition portmacro.h:59
unsigned long UBaseType_t
Definition portmacro.h:60
uint16_t TickType_t
Definition portmacro.h:63
portSTACK_TYPE StackType_t
Definition portmacro.h:58
#define portYIELD_FROM_ISR(x)
Definition portmacro.h:101
#define pdPASS
Definition projdefs.h:52
#define pdFAIL
Definition projdefs.h:53
void(* TaskFunction_t)(void *)
Definition projdefs.h:36
#define pdFALSE
Definition projdefs.h:45
#define pdTRUE
Definition projdefs.h:46
UBaseType_t uxQueueMessagesWaitingFromISR(const QueueHandle_t xQueue) PRIVILEGED_FUNCTION
Definition queue.c:2112
#define xQueueSendToBackFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken)
Definition queue.h:1109
struct QueueDefinition * QueueHandle_t
Definition queue.h:51
void vQueueDelete(QueueHandle_t xQueue) PRIVILEGED_FUNCTION
Definition queue.c:2124
#define xQueueSendToBack(xQueue, pvItemToQueue, xTicksToWait)
Definition queue.h:428
#define xQueueReset(xQueue)
Definition queue.h:1510
UBaseType_t uxQueueSpacesAvailable(const QueueHandle_t xQueue) PRIVILEGED_FUNCTION
Definition queue.c:2095
BaseType_t xQueueReceiveFromISR(QueueHandle_t xQueue, void *const pvBuffer, BaseType_t *const pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION
Definition queue.c:1931
UBaseType_t uxQueueMessagesWaiting(const QueueHandle_t xQueue) PRIVILEGED_FUNCTION
Definition queue.c:2079
BaseType_t xQueueReceive(QueueHandle_t xQueue, void *const pvBuffer, TickType_t xTicksToWait) PRIVILEGED_FUNCTION
Definition queue.c:1427
#define uxSemaphoreGetCountFromISR(xSemaphore)
semphr.h
Definition semphr.h:1191
#define xSemaphoreTakeFromISR(xSemaphore, pxHigherPriorityTaskWoken)
semphr.
Definition semphr.h:675
#define xSemaphoreGiveFromISR(xSemaphore, pxHigherPriorityTaskWoken)
Definition semphr.h:640
#define uxSemaphoreGetCount(xSemaphore)
semphr.h
Definition semphr.h:1177
#define xSemaphoreGive(xSemaphore)
Definition semphr.h:460
#define vSemaphoreDelete(xSemaphore)
Definition semphr.h:1129
QueueHandle_t SemaphoreHandle_t
Definition semphr.h:38
#define xSemaphoreTake(xSemaphore, xBlockTime)
Definition semphr.h:298
uint8_t * mem_arr
SemaphoreHandle_t sem
uint32_t bl_cnt
uint32_t mem_sz
MemPoolBlock_t * head
volatile uint32_t status
const char * name
osTimerFunc_t func
Definition cmsis_os2.c:94
Attributes structure for event flags.
Definition cmsis_os2.h:261
uint32_t cb_size
size of provided memory for control block
Definition cmsis_os2.h:265
void * cb_mem
memory for control block
Definition cmsis_os2.h:264
Attributes structure for memory pool.
Definition cmsis_os2.h:285
uint32_t mp_size
size of provided memory for data storage
Definition cmsis_os2.h:291
const char * name
name of the memory pool
Definition cmsis_os2.h:286
void * cb_mem
memory for control block
Definition cmsis_os2.h:288
uint32_t cb_size
size of provided memory for control block
Definition cmsis_os2.h:289
void * mp_mem
memory for data storage
Definition cmsis_os2.h:290
Attributes structure for message queue.
Definition cmsis_os2.h:295
const char * name
name of the message queue
Definition cmsis_os2.h:296
void * cb_mem
memory for control block
Definition cmsis_os2.h:298
uint32_t mq_size
size of provided memory for data storage
Definition cmsis_os2.h:301
uint32_t cb_size
size of provided memory for control block
Definition cmsis_os2.h:299
void * mq_mem
memory for data storage
Definition cmsis_os2.h:300
Attributes structure for mutex.
Definition cmsis_os2.h:269
uint32_t cb_size
size of provided memory for control block
Definition cmsis_os2.h:273
uint32_t attr_bits
attribute bits
Definition cmsis_os2.h:271
const char * name
name of the mutex
Definition cmsis_os2.h:270
void * cb_mem
memory for control block
Definition cmsis_os2.h:272
Attributes structure for semaphore.
Definition cmsis_os2.h:277
const char * name
name of the semaphore
Definition cmsis_os2.h:278
uint32_t cb_size
size of provided memory for control block
Definition cmsis_os2.h:281
void * cb_mem
memory for control block
Definition cmsis_os2.h:280
Attributes structure for thread.
Definition cmsis_os2.h:240
void * cb_mem
memory for control block
Definition cmsis_os2.h:243
uint32_t attr_bits
attribute bits
Definition cmsis_os2.h:242
uint32_t cb_size
size of provided memory for control block
Definition cmsis_os2.h:244
void * stack_mem
memory for stack
Definition cmsis_os2.h:245
osPriority_t priority
initial thread priority (default: osPriorityNormal)
Definition cmsis_os2.h:247
uint32_t stack_size
size of stack
Definition cmsis_os2.h:246
const char * name
name of the thread
Definition cmsis_os2.h:241
Attributes structure for timer.
Definition cmsis_os2.h:253
void * cb_mem
memory for control block
Definition cmsis_os2.h:256
const char * name
name of the timer
Definition cmsis_os2.h:254
uint32_t cb_size
size of provided memory for control block
Definition cmsis_os2.h:257
Version information.
Definition cmsis_os2.h:76
uint32_t api
API version (major.minor.rev: mmnnnrrrr dec).
Definition cmsis_os2.h:77
uint32_t kernel
Kernel version (major.minor.rev: mmnnnrrrr dec).
Definition cmsis_os2.h:78
UBaseType_t uxDummy4[3]
Definition FreeRTOS.h:1351
BaseType_t xTaskResumeAll(void) PRIVILEGED_FUNCTION
Definition tasks.c:2187
BaseType_t xTaskGetSchedulerState(void) PRIVILEGED_FUNCTION
#define taskSCHEDULER_NOT_STARTED
Definition task.h:257
TickType_t xTaskGetTickCountFromISR(void) PRIVILEGED_FUNCTION
Definition tasks.c:2314
#define taskSCHEDULER_SUSPENDED
Definition task.h:256
#define xTaskNotify(xTaskToNotify, ulValue, eAction)
Definition task.h:2161
eTaskState
Definition task.h:102
@ eRunning
Definition task.h:103
@ eReady
Definition task.h:104
@ eInvalid
Definition task.h:108
@ eDeleted
Definition task.h:107
@ eBlocked
Definition task.h:105
@ eSuspended
Definition task.h:106
UBaseType_t uxTaskPriorityGet(const TaskHandle_t xTask) PRIVILEGED_FUNCTION
#define xTaskNotifyFromISR(xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken)
Definition task.h:2314
void vTaskPrioritySet(TaskHandle_t xTask, UBaseType_t uxNewPriority) PRIVILEGED_FUNCTION
#define xTaskNotifyWait(ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait)
Definition task.h:2457
struct tskTaskControlBlock * TaskHandle_t
Definition task.h:92
void vTaskDelete(TaskHandle_t xTaskToDelete) PRIVILEGED_FUNCTION
void vTaskSuspendAll(void) PRIVILEGED_FUNCTION
Definition tasks.c:2103
#define xTaskNotifyAndQueryFromISR(xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken)
Definition task.h:2345
UBaseType_t uxTaskGetNumberOfTasks(void) PRIVILEGED_FUNCTION
Definition tasks.c:2345
TickType_t xTaskGetTickCount(void) PRIVILEGED_FUNCTION
Definition tasks.c:2299
#define taskYIELD()
Definition task.h:201
UBaseType_t uxTaskGetStackHighWaterMark(TaskHandle_t xTask) PRIVILEGED_FUNCTION
task.h
void vTaskResume(TaskHandle_t xTaskToResume) PRIVILEGED_FUNCTION
void vTaskSuspend(TaskHandle_t xTaskToSuspend) PRIVILEGED_FUNCTION
TaskHandle_t xTaskGetCurrentTaskHandle(void) PRIVILEGED_FUNCTION
UBaseType_t uxTaskGetSystemState(TaskStatus_t *const pxTaskStatusArray, const UBaseType_t uxArraySize, configRUN_TIME_COUNTER_TYPE *const pulTotalRunTime) PRIVILEGED_FUNCTION
configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for uxTaskGetSystemState() to be av...
eTaskState eTaskGetState(TaskHandle_t xTask) PRIVILEGED_FUNCTION
task.
void vTaskDelay(const TickType_t xTicksToDelay) PRIVILEGED_FUNCTION
#define xTaskNotifyAndQuery(xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue)
Definition task.h:2190
#define taskEXIT_CRITICAL()
Definition task.h:230
void vTaskStartScheduler(void) PRIVILEGED_FUNCTION
Definition tasks.c:1967
#define taskENTER_CRITICAL()
Definition task.h:215
#define taskENTER_CRITICAL_FROM_ISR()
Definition task.h:216
#define taskSCHEDULER_RUNNING
Definition task.h:258
struct xTASK_STATUS TaskStatus_t
@ eSetValueWithOverwrite
Definition task.h:117
@ eSetBits
Definition task.h:115
@ eNoAction
Definition task.h:114
char * pcTaskGetName(TaskHandle_t xTaskToQuery) PRIVILEGED_FUNCTION
Definition tasks.c:2353
BaseType_t xTaskDelayUntil(TickType_t *const pxPreviousWakeTime, const TickType_t xTimeIncrement) PRIVILEGED_FUNCTION
#define taskEXIT_CRITICAL_FROM_ISR(x)
Definition task.h:231
void * pvTimerGetTimerID(const TimerHandle_t xTimer) PRIVILEGED_FUNCTION
TimerHandle_t xTimerCreate( const char * const pcTimerName, TickType_t...
BaseType_t xTimerIsTimerActive(TimerHandle_t xTimer) PRIVILEGED_FUNCTION
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );.
const char * pcTimerGetName(TimerHandle_t xTimer) PRIVILEGED_FUNCTION
const char * const pcTimerGetName( TimerHandle_t xTimer );
#define xTimerStop(xTimer, xTicksToWait)
BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait );.
Definition timers.h:552
#define xTimerDelete(xTimer, xTicksToWait)
BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait );.
Definition timers.h:672
#define xTimerChangePeriod(xTimer, xNewPeriod, xTicksToWait)
BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, TickType_t x...
Definition timers.h:633
struct tmrTimerControl * TimerHandle_t
Definition timers.h:80