source: S-port/trunk/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c@ 1

Last change on this file since 1 was 1, checked in by AlexLir, 2 years ago
File size: 59.0 KB
Line 
1/* --------------------------------------------------------------------------
2 * Copyright (c) 2013-2020 Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Name: cmsis_os2.c
19 * Purpose: CMSIS RTOS2 wrapper for FreeRTOS
20 *
21 *---------------------------------------------------------------------------*/
22
23#include <string.h>
24
25#include "cmsis_os2.h" // ::CMSIS:RTOS2
26#include "cmsis_compiler.h" // Compiler agnostic definitions
27
28#include "FreeRTOS.h" // ARM.FreeRTOS::RTOS:Core
29#include "task.h" // ARM.FreeRTOS::RTOS:Core
30#include "event_groups.h" // ARM.FreeRTOS::RTOS:Event Groups
31#include "semphr.h" // ARM.FreeRTOS::RTOS:Core
32
33#include "freertos_mpool.h" // osMemoryPool definitions
34#include "freertos_os2.h" // Configuration check and setup
35
36/*---------------------------------------------------------------------------*/
37#ifndef __ARM_ARCH_6M__
38 #define __ARM_ARCH_6M__ 0
39#endif
40#ifndef __ARM_ARCH_7M__
41 #define __ARM_ARCH_7M__ 0
42#endif
43#ifndef __ARM_ARCH_7EM__
44 #define __ARM_ARCH_7EM__ 0
45#endif
46#ifndef __ARM_ARCH_8M_MAIN__
47 #define __ARM_ARCH_8M_MAIN__ 0
48#endif
49#ifndef __ARM_ARCH_7A__
50 #define __ARM_ARCH_7A__ 0
51#endif
52
53#if ((__ARM_ARCH_7M__ == 1U) || \
54 (__ARM_ARCH_7EM__ == 1U) || \
55 (__ARM_ARCH_8M_MAIN__ == 1U))
56#define IS_IRQ_MASKED() ((__get_PRIMASK() != 0U) || (__get_BASEPRI() != 0U))
57#elif (__ARM_ARCH_6M__ == 1U)
58#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
59#elif (__ARM_ARCH_7A__ == 1U)
60/* CPSR mask bits */
61#define CPSR_MASKBIT_I 0x80U
62
63#define IS_IRQ_MASKED() ((__get_CPSR() & CPSR_MASKBIT_I) != 0U)
64#else
65#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
66#endif
67
68#if (__ARM_ARCH_7A__ == 1U)
69/* CPSR mode bitmasks */
70#define CPSR_MODE_USER 0x10U
71#define CPSR_MODE_SYSTEM 0x1FU
72
73#define IS_IRQ_MODE() ((__get_mode() != CPSR_MODE_USER) && (__get_mode() != CPSR_MODE_SYSTEM))
74#else
75#define IS_IRQ_MODE() (__get_IPSR() != 0U)
76#endif
77
78#define IS_IRQ() IS_IRQ_MODE()
79
80#define SVCall_IRQ_NBR (IRQn_Type) -5 /* SVCall_IRQ_NBR added as SV_Call handler name is not the same for CM0 and for all other CMx */
81
82/* Limits */
83#define MAX_BITS_TASK_NOTIFY 31U
84#define MAX_BITS_EVENT_GROUPS 24U
85
86#define THREAD_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_TASK_NOTIFY) - 1U))
87#define EVENT_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_EVENT_GROUPS) - 1U))
88
89/* Kernel version and identification string definition (major.minor.rev: mmnnnrrrr dec) */
90#define KERNEL_VERSION (((uint32_t)tskKERNEL_VERSION_MAJOR * 10000000UL) | \
91 ((uint32_t)tskKERNEL_VERSION_MINOR * 10000UL) | \
92 ((uint32_t)tskKERNEL_VERSION_BUILD * 1UL))
93
94#define KERNEL_ID ("FreeRTOS " tskKERNEL_VERSION_NUMBER)
95
96/* Timer callback information structure definition */
97typedef struct {
98 osTimerFunc_t func;
99 void *arg;
100} TimerCallback_t;
101
102/* Kernel initialization state */
103static osKernelState_t KernelState = osKernelInactive;
104
105/*
106 Heap region definition used by heap_5 variant
107
108 Define configAPPLICATION_ALLOCATED_HEAP as nonzero value in FreeRTOSConfig.h if
109 heap regions are already defined and vPortDefineHeapRegions is called in application.
110
111 Otherwise vPortDefineHeapRegions will be called by osKernelInitialize using
112 definition configHEAP_5_REGIONS as parameter. Overriding configHEAP_5_REGIONS
113 is possible by defining it globally or in FreeRTOSConfig.h.
114*/
115#if defined(USE_FreeRTOS_HEAP_5)
116#if (configAPPLICATION_ALLOCATED_HEAP == 0)
117 /*
118 FreeRTOS heap is not defined by the application.
119 Single region of size configTOTAL_HEAP_SIZE (defined in FreeRTOSConfig.h)
120 is provided by default. Define configHEAP_5_REGIONS to provide custom
121 HeapRegion_t array.
122 */
123 #define HEAP_5_REGION_SETUP 1
124
125 #ifndef configHEAP_5_REGIONS
126 #define configHEAP_5_REGIONS xHeapRegions
127
128 static uint8_t ucHeap[configTOTAL_HEAP_SIZE];
129
130 static HeapRegion_t xHeapRegions[] = {
131 { ucHeap, configTOTAL_HEAP_SIZE },
132 { NULL, 0 }
133 };
134 #else
135 /* Global definition is provided to override default heap array */
136 extern HeapRegion_t configHEAP_5_REGIONS[];
137 #endif
138#else
139 /*
140 The application already defined the array used for the FreeRTOS heap and
141 called vPortDefineHeapRegions to initialize heap.
142 */
143 #define HEAP_5_REGION_SETUP 0
144#endif /* configAPPLICATION_ALLOCATED_HEAP */
145#endif /* USE_FreeRTOS_HEAP_5 */
146
147#if defined(SysTick)
148#undef SysTick_Handler
149
150/* CMSIS SysTick interrupt handler prototype */
151extern void SysTick_Handler (void);
152/* FreeRTOS tick timer interrupt handler prototype */
153extern void xPortSysTickHandler (void);
154
155/*
156 SysTick handler implementation that also clears overflow flag.
157*/
158#if (USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION == 0)
159void SysTick_Handler (void) {
160 /* Clear overflow flag */
161 SysTick->CTRL;
162
163 if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
164 /* Call tick handler */
165 xPortSysTickHandler();
166 }
167}
168#endif
169#endif /* SysTick */
170
171/*
172 Setup SVC to reset value.
173*/
174__STATIC_INLINE void SVC_Setup (void) {
175#if (__ARM_ARCH_7A__ == 0U)
176 /* Service Call interrupt might be configured before kernel start */
177 /* and when its priority is lower or equal to BASEPRI, svc intruction */
178 /* causes a Hard Fault. */
179 NVIC_SetPriority (SVCall_IRQ_NBR, 0U);
180#endif
181}
182
183/*
184 Function macro used to retrieve semaphore count from ISR
185*/
186#ifndef uxSemaphoreGetCountFromISR
187#define uxSemaphoreGetCountFromISR( xSemaphore ) uxQueueMessagesWaitingFromISR( ( QueueHandle_t ) ( xSemaphore ) )
188#endif
189
190/* Get OS Tick count value */
191static uint32_t OS_Tick_GetCount (void);
192/* Get OS Tick overflow status */
193static uint32_t OS_Tick_GetOverflow (void);
194/* Get OS Tick interval */
195static uint32_t OS_Tick_GetInterval (void);
196/*---------------------------------------------------------------------------*/
197
198osStatus_t osKernelInitialize (void) {
199 osStatus_t stat;
200
201 if (IS_IRQ()) {
202 stat = osErrorISR;
203 }
204 else {
205 if (KernelState == osKernelInactive) {
206 #if defined(USE_TRACE_EVENT_RECORDER)
207 EvrFreeRTOSSetup(0U);
208 #endif
209 #if defined(USE_FreeRTOS_HEAP_5) && (HEAP_5_REGION_SETUP == 1)
210 vPortDefineHeapRegions (configHEAP_5_REGIONS);
211 #endif
212 KernelState = osKernelReady;
213 stat = osOK;
214 } else {
215 stat = osError;
216 }
217 }
218
219 return (stat);
220}
221
222osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) {
223
224 if (version != NULL) {
225 /* Version encoding is major.minor.rev: mmnnnrrrr dec */
226 version->api = KERNEL_VERSION;
227 version->kernel = KERNEL_VERSION;
228 }
229
230 if ((id_buf != NULL) && (id_size != 0U)) {
231 if (id_size > sizeof(KERNEL_ID)) {
232 id_size = sizeof(KERNEL_ID);
233 }
234 memcpy(id_buf, KERNEL_ID, id_size);
235 }
236
237 return (osOK);
238}
239
240osKernelState_t osKernelGetState (void) {
241 osKernelState_t state;
242
243 switch (xTaskGetSchedulerState()) {
244 case taskSCHEDULER_RUNNING:
245 state = osKernelRunning;
246 break;
247
248 case taskSCHEDULER_SUSPENDED:
249 state = osKernelLocked;
250 break;
251
252 case taskSCHEDULER_NOT_STARTED:
253 default:
254 if (KernelState == osKernelReady) {
255 state = osKernelReady;
256 } else {
257 state = osKernelInactive;
258 }
259 break;
260 }
261
262 return (state);
263}
264
265osStatus_t osKernelStart (void) {
266 osStatus_t stat;
267
268 if (IS_IRQ()) {
269 stat = osErrorISR;
270 }
271 else {
272 if (KernelState == osKernelReady) {
273 /* Ensure SVC priority is at the reset value */
274 SVC_Setup();
275 /* Change state to enable IRQ masking check */
276 KernelState = osKernelRunning;
277 /* Start the kernel scheduler */
278 vTaskStartScheduler();
279 stat = osOK;
280 } else {
281 stat = osError;
282 }
283 }
284
285 return (stat);
286}
287
288int32_t osKernelLock (void) {
289 int32_t lock;
290
291 if (IS_IRQ()) {
292 lock = (int32_t)osErrorISR;
293 }
294 else {
295 switch (xTaskGetSchedulerState()) {
296 case taskSCHEDULER_SUSPENDED:
297 lock = 1;
298 break;
299
300 case taskSCHEDULER_RUNNING:
301 vTaskSuspendAll();
302 lock = 0;
303 break;
304
305 case taskSCHEDULER_NOT_STARTED:
306 default:
307 lock = (int32_t)osError;
308 break;
309 }
310 }
311
312 return (lock);
313}
314
315int32_t osKernelUnlock (void) {
316 int32_t lock;
317
318 if (IS_IRQ()) {
319 lock = (int32_t)osErrorISR;
320 }
321 else {
322 switch (xTaskGetSchedulerState()) {
323 case taskSCHEDULER_SUSPENDED:
324 lock = 1;
325
326 if (xTaskResumeAll() != pdTRUE) {
327 if (xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED) {
328 lock = (int32_t)osError;
329 }
330 }
331 break;
332
333 case taskSCHEDULER_RUNNING:
334 lock = 0;
335 break;
336
337 case taskSCHEDULER_NOT_STARTED:
338 default:
339 lock = (int32_t)osError;
340 break;
341 }
342 }
343
344 return (lock);
345}
346
347int32_t osKernelRestoreLock (int32_t lock) {
348
349 if (IS_IRQ()) {
350 lock = (int32_t)osErrorISR;
351 }
352 else {
353 switch (xTaskGetSchedulerState()) {
354 case taskSCHEDULER_SUSPENDED:
355 case taskSCHEDULER_RUNNING:
356 if (lock == 1) {
357 vTaskSuspendAll();
358 }
359 else {
360 if (lock != 0) {
361 lock = (int32_t)osError;
362 }
363 else {
364 if (xTaskResumeAll() != pdTRUE) {
365 if (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) {
366 lock = (int32_t)osError;
367 }
368 }
369 }
370 }
371 break;
372
373 case taskSCHEDULER_NOT_STARTED:
374 default:
375 lock = (int32_t)osError;
376 break;
377 }
378 }
379
380 return (lock);
381}
382
383uint32_t osKernelGetTickCount (void) {
384 TickType_t ticks;
385
386 if (IS_IRQ()) {
387 ticks = xTaskGetTickCountFromISR();
388 } else {
389 ticks = xTaskGetTickCount();
390 }
391
392 return (ticks);
393}
394
395uint32_t osKernelGetTickFreq (void) {
396 return (configTICK_RATE_HZ);
397}
398
399/* Get OS Tick count value */
400static uint32_t OS_Tick_GetCount (void) {
401 uint32_t load = SysTick->LOAD;
402 return (load - SysTick->VAL);
403}
404
405/* Get OS Tick overflow status */
406static uint32_t OS_Tick_GetOverflow (void) {
407 return ((SysTick->CTRL >> 16) & 1U);
408}
409
410/* Get OS Tick interval */
411static uint32_t OS_Tick_GetInterval (void) {
412 return (SysTick->LOAD + 1U);
413}
414
415uint32_t osKernelGetSysTimerCount (void) {
416 uint32_t irqmask = IS_IRQ_MASKED();
417 TickType_t ticks;
418 uint32_t val;
419
420 __disable_irq();
421
422 ticks = xTaskGetTickCount();
423 val = OS_Tick_GetCount();
424
425 if (OS_Tick_GetOverflow() != 0U) {
426 val = OS_Tick_GetCount();
427 ticks++;
428 }
429 val += ticks * OS_Tick_GetInterval();
430
431 if (irqmask == 0U) {
432 __enable_irq();
433 }
434
435 return (val);
436}
437
438uint32_t osKernelGetSysTimerFreq (void) {
439 return (configCPU_CLOCK_HZ);
440}
441
442/*---------------------------------------------------------------------------*/
443
444osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) {
445 const char *name;
446 uint32_t stack;
447 TaskHandle_t hTask;
448 UBaseType_t prio;
449 int32_t mem;
450
451 hTask = NULL;
452
453 if (!IS_IRQ() && (func != NULL)) {
454 stack = configMINIMAL_STACK_SIZE;
455 prio = (UBaseType_t)osPriorityNormal;
456
457 name = NULL;
458 mem = -1;
459
460 if (attr != NULL) {
461 if (attr->name != NULL) {
462 name = attr->name;
463 }
464 if (attr->priority != osPriorityNone) {
465 prio = (UBaseType_t)attr->priority;
466 }
467
468 if ((prio < osPriorityIdle) || (prio > osPriorityISR) || ((attr->attr_bits & osThreadJoinable) == osThreadJoinable)) {
469 return (NULL);
470 }
471
472 if (attr->stack_size > 0U) {
473 /* In FreeRTOS stack is not in bytes, but in sizeof(StackType_t) which is 4 on ARM ports. */
474 /* Stack size should be therefore 4 byte aligned in order to avoid division caused side effects */
475 stack = attr->stack_size / sizeof(StackType_t);
476 }
477
478 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTask_t)) &&
479 (attr->stack_mem != NULL) && (attr->stack_size > 0U)) {
480 mem = 1;
481 }
482 else {
483 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) && (attr->stack_mem == NULL)) {
484 mem = 0;
485 }
486 }
487 }
488 else {
489 mem = 0;
490 }
491
492 if (mem == 1) {
493 #if (configSUPPORT_STATIC_ALLOCATION == 1)
494 hTask = xTaskCreateStatic ((TaskFunction_t)func, name, stack, argument, prio, (StackType_t *)attr->stack_mem,
495 (StaticTask_t *)attr->cb_mem);
496 #endif
497 }
498 else {
499 if (mem == 0) {
500 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
501 if (xTaskCreate ((TaskFunction_t)func, name, (uint16_t)stack, argument, prio, &hTask) != pdPASS) {
502 hTask = NULL;
503 }
504 #endif
505 }
506 }
507 }
508
509 return ((osThreadId_t)hTask);
510}
511
512const char *osThreadGetName (osThreadId_t thread_id) {
513 TaskHandle_t hTask = (TaskHandle_t)thread_id;
514 const char *name;
515
516 if (IS_IRQ() || (hTask == NULL)) {
517 name = NULL;
518 } else {
519 name = pcTaskGetName (hTask);
520 }
521
522 return (name);
523}
524
525osThreadId_t osThreadGetId (void) {
526 osThreadId_t id;
527
528 id = (osThreadId_t)xTaskGetCurrentTaskHandle();
529
530 return (id);
531}
532
533osThreadState_t osThreadGetState (osThreadId_t thread_id) {
534 TaskHandle_t hTask = (TaskHandle_t)thread_id;
535 osThreadState_t state;
536
537 if (IS_IRQ() || (hTask == NULL)) {
538 state = osThreadError;
539 }
540 else {
541 switch (eTaskGetState (hTask)) {
542 case eRunning: state = osThreadRunning; break;
543 case eReady: state = osThreadReady; break;
544 case eBlocked:
545 case eSuspended: state = osThreadBlocked; break;
546 case eDeleted: state = osThreadTerminated; break;
547 case eInvalid:
548 default: state = osThreadError; break;
549 }
550 }
551
552 return (state);
553}
554
555uint32_t osThreadGetStackSpace (osThreadId_t thread_id) {
556 TaskHandle_t hTask = (TaskHandle_t)thread_id;
557 uint32_t sz;
558
559 if (IS_IRQ() || (hTask == NULL)) {
560 sz = 0U;
561 } else {
562 sz = (uint32_t)(uxTaskGetStackHighWaterMark(hTask) * sizeof(StackType_t));
563 }
564
565 return (sz);
566}
567
568osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) {
569 TaskHandle_t hTask = (TaskHandle_t)thread_id;
570 osStatus_t stat;
571
572 if (IS_IRQ()) {
573 stat = osErrorISR;
574 }
575 else if ((hTask == NULL) || (priority < osPriorityIdle) || (priority > osPriorityISR)) {
576 stat = osErrorParameter;
577 }
578 else {
579 stat = osOK;
580 vTaskPrioritySet (hTask, (UBaseType_t)priority);
581 }
582
583 return (stat);
584}
585
586osPriority_t osThreadGetPriority (osThreadId_t thread_id) {
587 TaskHandle_t hTask = (TaskHandle_t)thread_id;
588 osPriority_t prio;
589
590 if (IS_IRQ() || (hTask == NULL)) {
591 prio = osPriorityError;
592 } else {
593 prio = (osPriority_t)((int32_t)uxTaskPriorityGet (hTask));
594 }
595
596 return (prio);
597}
598
599osStatus_t osThreadYield (void) {
600 osStatus_t stat;
601
602 if (IS_IRQ()) {
603 stat = osErrorISR;
604 } else {
605 stat = osOK;
606 taskYIELD();
607 }
608
609 return (stat);
610}
611
612#if (configUSE_OS2_THREAD_SUSPEND_RESUME == 1)
613osStatus_t osThreadSuspend (osThreadId_t thread_id) {
614 TaskHandle_t hTask = (TaskHandle_t)thread_id;
615 osStatus_t stat;
616
617 if (IS_IRQ()) {
618 stat = osErrorISR;
619 }
620 else if (hTask == NULL) {
621 stat = osErrorParameter;
622 }
623 else {
624 stat = osOK;
625 vTaskSuspend (hTask);
626 }
627
628 return (stat);
629}
630
631osStatus_t osThreadResume (osThreadId_t thread_id) {
632 TaskHandle_t hTask = (TaskHandle_t)thread_id;
633 osStatus_t stat;
634
635 if (IS_IRQ()) {
636 stat = osErrorISR;
637 }
638 else if (hTask == NULL) {
639 stat = osErrorParameter;
640 }
641 else {
642 stat = osOK;
643 vTaskResume (hTask);
644 }
645
646 return (stat);
647}
648#endif /* (configUSE_OS2_THREAD_SUSPEND_RESUME == 1) */
649
650__NO_RETURN void osThreadExit (void) {
651#ifndef USE_FreeRTOS_HEAP_1
652 vTaskDelete (NULL);
653#endif
654 for (;;);
655}
656
657osStatus_t osThreadTerminate (osThreadId_t thread_id) {
658 TaskHandle_t hTask = (TaskHandle_t)thread_id;
659 osStatus_t stat;
660#ifndef USE_FreeRTOS_HEAP_1
661 eTaskState tstate;
662
663 if (IS_IRQ()) {
664 stat = osErrorISR;
665 }
666 else if (hTask == NULL) {
667 stat = osErrorParameter;
668 }
669 else {
670 tstate = eTaskGetState (hTask);
671
672 if (tstate != eDeleted) {
673 stat = osOK;
674 vTaskDelete (hTask);
675 } else {
676 stat = osErrorResource;
677 }
678 }
679#else
680 stat = osError;
681#endif
682
683 return (stat);
684}
685
686uint32_t osThreadGetCount (void) {
687 uint32_t count;
688
689 if (IS_IRQ()) {
690 count = 0U;
691 } else {
692 count = uxTaskGetNumberOfTasks();
693 }
694
695 return (count);
696}
697
698#if (configUSE_OS2_THREAD_ENUMERATE == 1)
699uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) {
700 uint32_t i, count;
701 TaskStatus_t *task;
702
703 if (IS_IRQ() || (thread_array == NULL) || (array_items == 0U)) {
704 count = 0U;
705 } else {
706 vTaskSuspendAll();
707
708 count = uxTaskGetNumberOfTasks();
709 task = pvPortMalloc (count * sizeof(TaskStatus_t));
710
711 if (task != NULL) {
712 count = uxTaskGetSystemState (task, count, NULL);
713
714 for (i = 0U; (i < count) && (i < array_items); i++) {
715 thread_array[i] = (osThreadId_t)task[i].xHandle;
716 }
717 count = i;
718 }
719 (void)xTaskResumeAll();
720
721 vPortFree (task);
722 }
723
724 return (count);
725}
726#endif /* (configUSE_OS2_THREAD_ENUMERATE == 1) */
727
728#if (configUSE_OS2_THREAD_FLAGS == 1)
729uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) {
730 TaskHandle_t hTask = (TaskHandle_t)thread_id;
731 uint32_t rflags;
732 BaseType_t yield;
733
734 if ((hTask == NULL) || ((flags & THREAD_FLAGS_INVALID_BITS) != 0U)) {
735 rflags = (uint32_t)osErrorParameter;
736 }
737 else {
738 rflags = (uint32_t)osError;
739
740 if (IS_IRQ()) {
741 yield = pdFALSE;
742
743 (void)xTaskNotifyFromISR (hTask, flags, eSetBits, &yield);
744 (void)xTaskNotifyAndQueryFromISR (hTask, 0, eNoAction, &rflags, NULL);
745
746 portYIELD_FROM_ISR (yield);
747 }
748 else {
749 (void)xTaskNotify (hTask, flags, eSetBits);
750 (void)xTaskNotifyAndQuery (hTask, 0, eNoAction, &rflags);
751 }
752 }
753 /* Return flags after setting */
754 return (rflags);
755}
756
757uint32_t osThreadFlagsClear (uint32_t flags) {
758 TaskHandle_t hTask;
759 uint32_t rflags, cflags;
760
761 if (IS_IRQ()) {
762 rflags = (uint32_t)osErrorISR;
763 }
764 else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) {
765 rflags = (uint32_t)osErrorParameter;
766 }
767 else {
768 hTask = xTaskGetCurrentTaskHandle();
769
770 if (xTaskNotifyAndQuery (hTask, 0, eNoAction, &cflags) == pdPASS) {
771 rflags = cflags;
772 cflags &= ~flags;
773
774 if (xTaskNotify (hTask, cflags, eSetValueWithOverwrite) != pdPASS) {
775 rflags = (uint32_t)osError;
776 }
777 }
778 else {
779 rflags = (uint32_t)osError;
780 }
781 }
782
783 /* Return flags before clearing */
784 return (rflags);
785}
786
787uint32_t osThreadFlagsGet (void) {
788 TaskHandle_t hTask;
789 uint32_t rflags;
790
791 if (IS_IRQ()) {
792 rflags = (uint32_t)osErrorISR;
793 }
794 else {
795 hTask = xTaskGetCurrentTaskHandle();
796
797 if (xTaskNotifyAndQuery (hTask, 0, eNoAction, &rflags) != pdPASS) {
798 rflags = (uint32_t)osError;
799 }
800 }
801
802 return (rflags);
803}
804
805uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) {
806 uint32_t rflags, nval;
807 uint32_t clear;
808 TickType_t t0, td, tout;
809 BaseType_t rval;
810
811 if (IS_IRQ()) {
812 rflags = (uint32_t)osErrorISR;
813 }
814 else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) {
815 rflags = (uint32_t)osErrorParameter;
816 }
817 else {
818 if ((options & osFlagsNoClear) == osFlagsNoClear) {
819 clear = 0U;
820 } else {
821 clear = flags;
822 }
823
824 rflags = 0U;
825 tout = timeout;
826
827 t0 = xTaskGetTickCount();
828 do {
829 rval = xTaskNotifyWait (0, clear, &nval, tout);
830
831 if (rval == pdPASS) {
832 rflags &= flags;
833 rflags |= nval;
834
835 if ((options & osFlagsWaitAll) == osFlagsWaitAll) {
836 if ((flags & rflags) == flags) {
837 break;
838 } else {
839 if (timeout == 0U) {
840 rflags = (uint32_t)osErrorResource;
841 break;
842 }
843 }
844 }
845 else {
846 if ((flags & rflags) != 0) {
847 break;
848 } else {
849 if (timeout == 0U) {
850 rflags = (uint32_t)osErrorResource;
851 break;
852 }
853 }
854 }
855
856 /* Update timeout */
857 td = xTaskGetTickCount() - t0;
858
859 if (td > tout) {
860 tout = 0;
861 } else {
862 tout -= td;
863 }
864 }
865 else {
866 if (timeout == 0) {
867 rflags = (uint32_t)osErrorResource;
868 } else {
869 rflags = (uint32_t)osErrorTimeout;
870 }
871 }
872 }
873 while (rval != pdFAIL);
874 }
875
876 /* Return flags before clearing */
877 return (rflags);
878}
879#endif /* (configUSE_OS2_THREAD_FLAGS == 1) */
880
881osStatus_t osDelay (uint32_t ticks) {
882 osStatus_t stat;
883
884 if (IS_IRQ()) {
885 stat = osErrorISR;
886 }
887 else {
888 stat = osOK;
889
890 if (ticks != 0U) {
891 vTaskDelay(ticks);
892 }
893 }
894
895 return (stat);
896}
897
898osStatus_t osDelayUntil (uint32_t ticks) {
899 TickType_t tcnt, delay;
900 osStatus_t stat;
901
902 if (IS_IRQ()) {
903 stat = osErrorISR;
904 }
905 else {
906 stat = osOK;
907 tcnt = xTaskGetTickCount();
908
909 /* Determine remaining number of ticks to delay */
910 delay = (TickType_t)ticks - tcnt;
911
912 /* Check if target tick has not expired */
913 if((delay != 0U) && (0 == (delay >> (8 * sizeof(TickType_t) - 1)))) {
914 vTaskDelayUntil (&tcnt, delay);
915 }
916 else
917 {
918 /* No delay or already expired */
919 stat = osErrorParameter;
920 }
921 }
922
923 return (stat);
924}
925
926/*---------------------------------------------------------------------------*/
927#if (configUSE_OS2_TIMER == 1)
928
929static void TimerCallback (TimerHandle_t hTimer) {
930 TimerCallback_t *callb;
931
932 callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer);
933
934 if (callb != NULL) {
935 callb->func (callb->arg);
936 }
937}
938
939osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) {
940 const char *name;
941 TimerHandle_t hTimer;
942 TimerCallback_t *callb;
943 UBaseType_t reload;
944 int32_t mem;
945
946 hTimer = NULL;
947
948 if (!IS_IRQ() && (func != NULL)) {
949 /* Allocate memory to store callback function and argument */
950 callb = pvPortMalloc (sizeof(TimerCallback_t));
951
952 if (callb != NULL) {
953 callb->func = func;
954 callb->arg = argument;
955
956 if (type == osTimerOnce) {
957 reload = pdFALSE;
958 } else {
959 reload = pdTRUE;
960 }
961
962 mem = -1;
963 name = NULL;
964
965 if (attr != NULL) {
966 if (attr->name != NULL) {
967 name = attr->name;
968 }
969
970 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTimer_t))) {
971 mem = 1;
972 }
973 else {
974 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
975 mem = 0;
976 }
977 }
978 }
979 else {
980 mem = 0;
981 }
982
983 if (mem == 1) {
984 #if (configSUPPORT_STATIC_ALLOCATION == 1)
985 hTimer = xTimerCreateStatic (name, 1, reload, callb, TimerCallback, (StaticTimer_t *)attr->cb_mem);
986 #endif
987 }
988 else {
989 if (mem == 0) {
990 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
991 hTimer = xTimerCreate (name, 1, reload, callb, TimerCallback);
992 #endif
993 }
994 }
995
996 if ((hTimer == NULL) && (callb != NULL)) {
997 vPortFree (callb);
998 }
999 }
1000 }
1001
1002 return ((osTimerId_t)hTimer);
1003}
1004
1005const char *osTimerGetName (osTimerId_t timer_id) {
1006 TimerHandle_t hTimer = (TimerHandle_t)timer_id;
1007 const char *p;
1008
1009 if (IS_IRQ() || (hTimer == NULL)) {
1010 p = NULL;
1011 } else {
1012 p = pcTimerGetName (hTimer);
1013 }
1014
1015 return (p);
1016}
1017
1018osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks) {
1019 TimerHandle_t hTimer = (TimerHandle_t)timer_id;
1020 osStatus_t stat;
1021
1022 if (IS_IRQ()) {
1023 stat = osErrorISR;
1024 }
1025 else if (hTimer == NULL) {
1026 stat = osErrorParameter;
1027 }
1028 else {
1029 if (xTimerChangePeriod (hTimer, ticks, 0) == pdPASS) {
1030 stat = osOK;
1031 } else {
1032 stat = osErrorResource;
1033 }
1034 }
1035
1036 return (stat);
1037}
1038
1039osStatus_t osTimerStop (osTimerId_t timer_id) {
1040 TimerHandle_t hTimer = (TimerHandle_t)timer_id;
1041 osStatus_t stat;
1042
1043 if (IS_IRQ()) {
1044 stat = osErrorISR;
1045 }
1046 else if (hTimer == NULL) {
1047 stat = osErrorParameter;
1048 }
1049 else {
1050 if (xTimerIsTimerActive (hTimer) == pdFALSE) {
1051 stat = osErrorResource;
1052 }
1053 else {
1054 if (xTimerStop (hTimer, 0) == pdPASS) {
1055 stat = osOK;
1056 } else {
1057 stat = osError;
1058 }
1059 }
1060 }
1061
1062 return (stat);
1063}
1064
1065uint32_t osTimerIsRunning (osTimerId_t timer_id) {
1066 TimerHandle_t hTimer = (TimerHandle_t)timer_id;
1067 uint32_t running;
1068
1069 if (IS_IRQ() || (hTimer == NULL)) {
1070 running = 0U;
1071 } else {
1072 running = (uint32_t)xTimerIsTimerActive (hTimer);
1073 }
1074
1075 return (running);
1076}
1077
1078osStatus_t osTimerDelete (osTimerId_t timer_id) {
1079 TimerHandle_t hTimer = (TimerHandle_t)timer_id;
1080 osStatus_t stat;
1081#ifndef USE_FreeRTOS_HEAP_1
1082 TimerCallback_t *callb;
1083
1084 if (IS_IRQ()) {
1085 stat = osErrorISR;
1086 }
1087 else if (hTimer == NULL) {
1088 stat = osErrorParameter;
1089 }
1090 else {
1091 callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer);
1092
1093 if (xTimerDelete (hTimer, 0) == pdPASS) {
1094 vPortFree (callb);
1095 stat = osOK;
1096 } else {
1097 stat = osErrorResource;
1098 }
1099 }
1100#else
1101 stat = osError;
1102#endif
1103
1104 return (stat);
1105}
1106#endif /* (configUSE_OS2_TIMER == 1) */
1107
1108/*---------------------------------------------------------------------------*/
1109
1110osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr) {
1111 EventGroupHandle_t hEventGroup;
1112 int32_t mem;
1113
1114 hEventGroup = NULL;
1115
1116 if (!IS_IRQ()) {
1117 mem = -1;
1118
1119 if (attr != NULL) {
1120 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticEventGroup_t))) {
1121 mem = 1;
1122 }
1123 else {
1124 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1125 mem = 0;
1126 }
1127 }
1128 }
1129 else {
1130 mem = 0;
1131 }
1132
1133 if (mem == 1) {
1134 #if (configSUPPORT_STATIC_ALLOCATION == 1)
1135 hEventGroup = xEventGroupCreateStatic (attr->cb_mem);
1136 #endif
1137 }
1138 else {
1139 if (mem == 0) {
1140 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1141 hEventGroup = xEventGroupCreate();
1142 #endif
1143 }
1144 }
1145 }
1146
1147 return ((osEventFlagsId_t)hEventGroup);
1148}
1149
1150uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) {
1151 EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1152 uint32_t rflags;
1153 BaseType_t yield;
1154
1155 if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1156 rflags = (uint32_t)osErrorParameter;
1157 }
1158 else if (IS_IRQ()) {
1159 #if (configUSE_OS2_EVENTFLAGS_FROM_ISR == 0)
1160 (void)yield;
1161 /* Enable timers and xTimerPendFunctionCall function to support osEventFlagsSet from ISR */
1162 rflags = (uint32_t)osErrorResource;
1163 #else
1164 yield = pdFALSE;
1165
1166 if (xEventGroupSetBitsFromISR (hEventGroup, (EventBits_t)flags, &yield) == pdFAIL) {
1167 rflags = (uint32_t)osErrorResource;
1168 } else {
1169 rflags = flags;
1170 portYIELD_FROM_ISR (yield);
1171 }
1172 #endif
1173 }
1174 else {
1175 rflags = xEventGroupSetBits (hEventGroup, (EventBits_t)flags);
1176 }
1177
1178 return (rflags);
1179}
1180
1181uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) {
1182 EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1183 uint32_t rflags;
1184
1185 if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1186 rflags = (uint32_t)osErrorParameter;
1187 }
1188 else if (IS_IRQ()) {
1189 #if (configUSE_OS2_EVENTFLAGS_FROM_ISR == 0)
1190 /* Enable timers and xTimerPendFunctionCall function to support osEventFlagsSet from ISR */
1191 rflags = (uint32_t)osErrorResource;
1192 #else
1193 rflags = xEventGroupGetBitsFromISR (hEventGroup);
1194
1195 if (xEventGroupClearBitsFromISR (hEventGroup, (EventBits_t)flags) == pdFAIL) {
1196 rflags = (uint32_t)osErrorResource;
1197 }
1198 #endif
1199 }
1200 else {
1201 rflags = xEventGroupClearBits (hEventGroup, (EventBits_t)flags);
1202 }
1203
1204 return (rflags);
1205}
1206
1207uint32_t osEventFlagsGet (osEventFlagsId_t ef_id) {
1208 EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1209 uint32_t rflags;
1210
1211 if (ef_id == NULL) {
1212 rflags = 0U;
1213 }
1214 else if (IS_IRQ()) {
1215 rflags = xEventGroupGetBitsFromISR (hEventGroup);
1216 }
1217 else {
1218 rflags = xEventGroupGetBits (hEventGroup);
1219 }
1220
1221 return (rflags);
1222}
1223
1224uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) {
1225 EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1226 BaseType_t wait_all;
1227 BaseType_t exit_clr;
1228 uint32_t rflags;
1229
1230 if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
1231 rflags = (uint32_t)osErrorParameter;
1232 }
1233 else if (IS_IRQ()) {
1234 rflags = (uint32_t)osErrorISR;
1235 }
1236 else {
1237 if (options & osFlagsWaitAll) {
1238 wait_all = pdTRUE;
1239 } else {
1240 wait_all = pdFAIL;
1241 }
1242
1243 if (options & osFlagsNoClear) {
1244 exit_clr = pdFAIL;
1245 } else {
1246 exit_clr = pdTRUE;
1247 }
1248
1249 rflags = xEventGroupWaitBits (hEventGroup, (EventBits_t)flags, exit_clr, wait_all, (TickType_t)timeout);
1250
1251 if (options & osFlagsWaitAll) {
1252 if ((flags & rflags) != flags) {
1253 if (timeout > 0U) {
1254 rflags = (uint32_t)osErrorTimeout;
1255 } else {
1256 rflags = (uint32_t)osErrorResource;
1257 }
1258 }
1259 }
1260 else {
1261 if ((flags & rflags) == 0U) {
1262 if (timeout > 0U) {
1263 rflags = (uint32_t)osErrorTimeout;
1264 } else {
1265 rflags = (uint32_t)osErrorResource;
1266 }
1267 }
1268 }
1269 }
1270
1271 return (rflags);
1272}
1273
1274osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id) {
1275 EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
1276 osStatus_t stat;
1277
1278#ifndef USE_FreeRTOS_HEAP_1
1279 if (IS_IRQ()) {
1280 stat = osErrorISR;
1281 }
1282 else if (hEventGroup == NULL) {
1283 stat = osErrorParameter;
1284 }
1285 else {
1286 stat = osOK;
1287 vEventGroupDelete (hEventGroup);
1288 }
1289#else
1290 stat = osError;
1291#endif
1292
1293 return (stat);
1294}
1295
1296/*---------------------------------------------------------------------------*/
1297#if (configUSE_OS2_MUTEX == 1)
1298
1299osMutexId_t osMutexNew (const osMutexAttr_t *attr) {
1300 SemaphoreHandle_t hMutex;
1301 uint32_t type;
1302 uint32_t rmtx;
1303 int32_t mem;
1304 #if (configQUEUE_REGISTRY_SIZE > 0)
1305 const char *name;
1306 #endif
1307
1308 hMutex = NULL;
1309
1310 if (!IS_IRQ()) {
1311 if (attr != NULL) {
1312 type = attr->attr_bits;
1313 } else {
1314 type = 0U;
1315 }
1316
1317 if ((type & osMutexRecursive) == osMutexRecursive) {
1318 rmtx = 1U;
1319 } else {
1320 rmtx = 0U;
1321 }
1322
1323 if ((type & osMutexRobust) != osMutexRobust) {
1324 mem = -1;
1325
1326 if (attr != NULL) {
1327 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
1328 mem = 1;
1329 }
1330 else {
1331 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1332 mem = 0;
1333 }
1334 }
1335 }
1336 else {
1337 mem = 0;
1338 }
1339
1340 if (mem == 1) {
1341 #if (configSUPPORT_STATIC_ALLOCATION == 1)
1342 if (rmtx != 0U) {
1343 #if (configUSE_RECURSIVE_MUTEXES == 1)
1344 hMutex = xSemaphoreCreateRecursiveMutexStatic (attr->cb_mem);
1345 #endif
1346 }
1347 else {
1348 hMutex = xSemaphoreCreateMutexStatic (attr->cb_mem);
1349 }
1350 #endif
1351 }
1352 else {
1353 if (mem == 0) {
1354 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1355 if (rmtx != 0U) {
1356 #if (configUSE_RECURSIVE_MUTEXES == 1)
1357 hMutex = xSemaphoreCreateRecursiveMutex ();
1358 #endif
1359 } else {
1360 hMutex = xSemaphoreCreateMutex ();
1361 }
1362 #endif
1363 }
1364 }
1365
1366 #if (configQUEUE_REGISTRY_SIZE > 0)
1367 if (hMutex != NULL) {
1368 if (attr != NULL) {
1369 name = attr->name;
1370 } else {
1371 name = NULL;
1372 }
1373 vQueueAddToRegistry (hMutex, name);
1374 }
1375 #endif
1376
1377 if ((hMutex != NULL) && (rmtx != 0U)) {
1378 hMutex = (SemaphoreHandle_t)((uint32_t)hMutex | 1U);
1379 }
1380 }
1381 }
1382
1383 return ((osMutexId_t)hMutex);
1384}
1385
1386osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
1387 SemaphoreHandle_t hMutex;
1388 osStatus_t stat;
1389 uint32_t rmtx;
1390
1391 hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1392
1393 rmtx = (uint32_t)mutex_id & 1U;
1394
1395 stat = osOK;
1396
1397 if (IS_IRQ()) {
1398 stat = osErrorISR;
1399 }
1400 else if (hMutex == NULL) {
1401 stat = osErrorParameter;
1402 }
1403 else {
1404 if (rmtx != 0U) {
1405 #if (configUSE_RECURSIVE_MUTEXES == 1)
1406 if (xSemaphoreTakeRecursive (hMutex, timeout) != pdPASS) {
1407 if (timeout != 0U) {
1408 stat = osErrorTimeout;
1409 } else {
1410 stat = osErrorResource;
1411 }
1412 }
1413 #endif
1414 }
1415 else {
1416 if (xSemaphoreTake (hMutex, timeout) != pdPASS) {
1417 if (timeout != 0U) {
1418 stat = osErrorTimeout;
1419 } else {
1420 stat = osErrorResource;
1421 }
1422 }
1423 }
1424 }
1425
1426 return (stat);
1427}
1428
1429osStatus_t osMutexRelease (osMutexId_t mutex_id) {
1430 SemaphoreHandle_t hMutex;
1431 osStatus_t stat;
1432 uint32_t rmtx;
1433
1434 hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1435
1436 rmtx = (uint32_t)mutex_id & 1U;
1437
1438 stat = osOK;
1439
1440 if (IS_IRQ()) {
1441 stat = osErrorISR;
1442 }
1443 else if (hMutex == NULL) {
1444 stat = osErrorParameter;
1445 }
1446 else {
1447 if (rmtx != 0U) {
1448 #if (configUSE_RECURSIVE_MUTEXES == 1)
1449 if (xSemaphoreGiveRecursive (hMutex) != pdPASS) {
1450 stat = osErrorResource;
1451 }
1452 #endif
1453 }
1454 else {
1455 if (xSemaphoreGive (hMutex) != pdPASS) {
1456 stat = osErrorResource;
1457 }
1458 }
1459 }
1460
1461 return (stat);
1462}
1463
1464osThreadId_t osMutexGetOwner (osMutexId_t mutex_id) {
1465 SemaphoreHandle_t hMutex;
1466 osThreadId_t owner;
1467
1468 hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1469
1470 if (IS_IRQ() || (hMutex == NULL)) {
1471 owner = NULL;
1472 } else {
1473 owner = (osThreadId_t)xSemaphoreGetMutexHolder (hMutex);
1474 }
1475
1476 return (owner);
1477}
1478
1479osStatus_t osMutexDelete (osMutexId_t mutex_id) {
1480 osStatus_t stat;
1481#ifndef USE_FreeRTOS_HEAP_1
1482 SemaphoreHandle_t hMutex;
1483
1484 hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
1485
1486 if (IS_IRQ()) {
1487 stat = osErrorISR;
1488 }
1489 else if (hMutex == NULL) {
1490 stat = osErrorParameter;
1491 }
1492 else {
1493 #if (configQUEUE_REGISTRY_SIZE > 0)
1494 vQueueUnregisterQueue (hMutex);
1495 #endif
1496 stat = osOK;
1497 vSemaphoreDelete (hMutex);
1498 }
1499#else
1500 stat = osError;
1501#endif
1502
1503 return (stat);
1504}
1505#endif /* (configUSE_OS2_MUTEX == 1) */
1506
1507/*---------------------------------------------------------------------------*/
1508
1509osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) {
1510 SemaphoreHandle_t hSemaphore;
1511 int32_t mem;
1512 #if (configQUEUE_REGISTRY_SIZE > 0)
1513 const char *name;
1514 #endif
1515
1516 hSemaphore = NULL;
1517
1518 if (!IS_IRQ() && (max_count > 0U) && (initial_count <= max_count)) {
1519 mem = -1;
1520
1521 if (attr != NULL) {
1522 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
1523 mem = 1;
1524 }
1525 else {
1526 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1527 mem = 0;
1528 }
1529 }
1530 }
1531 else {
1532 mem = 0;
1533 }
1534
1535 if (mem != -1) {
1536 if (max_count == 1U) {
1537 if (mem == 1) {
1538 #if (configSUPPORT_STATIC_ALLOCATION == 1)
1539 hSemaphore = xSemaphoreCreateBinaryStatic ((StaticSemaphore_t *)attr->cb_mem);
1540 #endif
1541 }
1542 else {
1543 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1544 hSemaphore = xSemaphoreCreateBinary();
1545 #endif
1546 }
1547
1548 if ((hSemaphore != NULL) && (initial_count != 0U)) {
1549 if (xSemaphoreGive (hSemaphore) != pdPASS) {
1550 vSemaphoreDelete (hSemaphore);
1551 hSemaphore = NULL;
1552 }
1553 }
1554 }
1555 else {
1556 if (mem == 1) {
1557 #if (configSUPPORT_STATIC_ALLOCATION == 1)
1558 hSemaphore = xSemaphoreCreateCountingStatic (max_count, initial_count, (StaticSemaphore_t *)attr->cb_mem);
1559 #endif
1560 }
1561 else {
1562 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1563 hSemaphore = xSemaphoreCreateCounting (max_count, initial_count);
1564 #endif
1565 }
1566 }
1567
1568 #if (configQUEUE_REGISTRY_SIZE > 0)
1569 if (hSemaphore != NULL) {
1570 if (attr != NULL) {
1571 name = attr->name;
1572 } else {
1573 name = NULL;
1574 }
1575 vQueueAddToRegistry (hSemaphore, name);
1576 }
1577 #endif
1578 }
1579 }
1580
1581 return ((osSemaphoreId_t)hSemaphore);
1582}
1583
1584osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) {
1585 SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
1586 osStatus_t stat;
1587 BaseType_t yield;
1588
1589 stat = osOK;
1590
1591 if (hSemaphore == NULL) {
1592 stat = osErrorParameter;
1593 }
1594 else if (IS_IRQ()) {
1595 if (timeout != 0U) {
1596 stat = osErrorParameter;
1597 }
1598 else {
1599 yield = pdFALSE;
1600
1601 if (xSemaphoreTakeFromISR (hSemaphore, &yield) != pdPASS) {
1602 stat = osErrorResource;
1603 } else {
1604 portYIELD_FROM_ISR (yield);
1605 }
1606 }
1607 }
1608 else {
1609 if (xSemaphoreTake (hSemaphore, (TickType_t)timeout) != pdPASS) {
1610 if (timeout != 0U) {
1611 stat = osErrorTimeout;
1612 } else {
1613 stat = osErrorResource;
1614 }
1615 }
1616 }
1617
1618 return (stat);
1619}
1620
1621osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id) {
1622 SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
1623 osStatus_t stat;
1624 BaseType_t yield;
1625
1626 stat = osOK;
1627
1628 if (hSemaphore == NULL) {
1629 stat = osErrorParameter;
1630 }
1631 else if (IS_IRQ()) {
1632 yield = pdFALSE;
1633
1634 if (xSemaphoreGiveFromISR (hSemaphore, &yield) != pdTRUE) {
1635 stat = osErrorResource;
1636 } else {
1637 portYIELD_FROM_ISR (yield);
1638 }
1639 }
1640 else {
1641 if (xSemaphoreGive (hSemaphore) != pdPASS) {
1642 stat = osErrorResource;
1643 }
1644 }
1645
1646 return (stat);
1647}
1648
1649uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id) {
1650 SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
1651 uint32_t count;
1652
1653 if (hSemaphore == NULL) {
1654 count = 0U;
1655 }
1656 else if (IS_IRQ()) {
1657 count = uxQueueMessagesWaitingFromISR (hSemaphore);
1658 } else {
1659 count = (uint32_t)uxSemaphoreGetCount (hSemaphore);
1660 }
1661
1662 return (count);
1663}
1664
1665osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id) {
1666 SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
1667 osStatus_t stat;
1668
1669#ifndef USE_FreeRTOS_HEAP_1
1670 if (IS_IRQ()) {
1671 stat = osErrorISR;
1672 }
1673 else if (hSemaphore == NULL) {
1674 stat = osErrorParameter;
1675 }
1676 else {
1677 #if (configQUEUE_REGISTRY_SIZE > 0)
1678 vQueueUnregisterQueue (hSemaphore);
1679 #endif
1680
1681 stat = osOK;
1682 vSemaphoreDelete (hSemaphore);
1683 }
1684#else
1685 stat = osError;
1686#endif
1687
1688 return (stat);
1689}
1690
1691/*---------------------------------------------------------------------------*/
1692
1693osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) {
1694 QueueHandle_t hQueue;
1695 int32_t mem;
1696 #if (configQUEUE_REGISTRY_SIZE > 0)
1697 const char *name;
1698 #endif
1699
1700 hQueue = NULL;
1701
1702 if (!IS_IRQ() && (msg_count > 0U) && (msg_size > 0U)) {
1703 mem = -1;
1704
1705 if (attr != NULL) {
1706 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticQueue_t)) &&
1707 (attr->mq_mem != NULL) && (attr->mq_size >= (msg_count * msg_size))) {
1708 mem = 1;
1709 }
1710 else {
1711 if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) &&
1712 (attr->mq_mem == NULL) && (attr->mq_size == 0U)) {
1713 mem = 0;
1714 }
1715 }
1716 }
1717 else {
1718 mem = 0;
1719 }
1720
1721 if (mem == 1) {
1722 #if (configSUPPORT_STATIC_ALLOCATION == 1)
1723 hQueue = xQueueCreateStatic (msg_count, msg_size, attr->mq_mem, attr->cb_mem);
1724 #endif
1725 }
1726 else {
1727 if (mem == 0) {
1728 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1729 hQueue = xQueueCreate (msg_count, msg_size);
1730 #endif
1731 }
1732 }
1733
1734 #if (configQUEUE_REGISTRY_SIZE > 0)
1735 if (hQueue != NULL) {
1736 if (attr != NULL) {
1737 name = attr->name;
1738 } else {
1739 name = NULL;
1740 }
1741 vQueueAddToRegistry (hQueue, name);
1742 }
1743 #endif
1744
1745 }
1746
1747 return ((osMessageQueueId_t)hQueue);
1748}
1749
1750osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) {
1751 QueueHandle_t hQueue = (QueueHandle_t)mq_id;
1752 osStatus_t stat;
1753 BaseType_t yield;
1754
1755 (void)msg_prio; /* Message priority is ignored */
1756
1757 stat = osOK;
1758
1759 if (IS_IRQ()) {
1760 if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
1761 stat = osErrorParameter;
1762 }
1763 else {
1764 yield = pdFALSE;
1765
1766 if (xQueueSendToBackFromISR (hQueue, msg_ptr, &yield) != pdTRUE) {
1767 stat = osErrorResource;
1768 } else {
1769 portYIELD_FROM_ISR (yield);
1770 }
1771 }
1772 }
1773 else {
1774 if ((hQueue == NULL) || (msg_ptr == NULL)) {
1775 stat = osErrorParameter;
1776 }
1777 else {
1778 if (xQueueSendToBack (hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) {
1779 if (timeout != 0U) {
1780 stat = osErrorTimeout;
1781 } else {
1782 stat = osErrorResource;
1783 }
1784 }
1785 }
1786 }
1787
1788 return (stat);
1789}
1790
1791osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) {
1792 QueueHandle_t hQueue = (QueueHandle_t)mq_id;
1793 osStatus_t stat;
1794 BaseType_t yield;
1795
1796 (void)msg_prio; /* Message priority is ignored */
1797
1798 stat = osOK;
1799
1800 if (IS_IRQ()) {
1801 if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
1802 stat = osErrorParameter;
1803 }
1804 else {
1805 yield = pdFALSE;
1806
1807 if (xQueueReceiveFromISR (hQueue, msg_ptr, &yield) != pdPASS) {
1808 stat = osErrorResource;
1809 } else {
1810 portYIELD_FROM_ISR (yield);
1811 }
1812 }
1813 }
1814 else {
1815 if ((hQueue == NULL) || (msg_ptr == NULL)) {
1816 stat = osErrorParameter;
1817 }
1818 else {
1819 if (xQueueReceive (hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) {
1820 if (timeout != 0U) {
1821 stat = osErrorTimeout;
1822 } else {
1823 stat = osErrorResource;
1824 }
1825 }
1826 }
1827 }
1828
1829 return (stat);
1830}
1831
1832uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id) {
1833 StaticQueue_t *mq = (StaticQueue_t *)mq_id;
1834 uint32_t capacity;
1835
1836 if (mq == NULL) {
1837 capacity = 0U;
1838 } else {
1839 /* capacity = pxQueue->uxLength */
1840 capacity = mq->uxDummy4[1];
1841 }
1842
1843 return (capacity);
1844}
1845
1846uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id) {
1847 StaticQueue_t *mq = (StaticQueue_t *)mq_id;
1848 uint32_t size;
1849
1850 if (mq == NULL) {
1851 size = 0U;
1852 } else {
1853 /* size = pxQueue->uxItemSize */
1854 size = mq->uxDummy4[2];
1855 }
1856
1857 return (size);
1858}
1859
1860uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) {
1861 QueueHandle_t hQueue = (QueueHandle_t)mq_id;
1862 UBaseType_t count;
1863
1864 if (hQueue == NULL) {
1865 count = 0U;
1866 }
1867 else if (IS_IRQ()) {
1868 count = uxQueueMessagesWaitingFromISR (hQueue);
1869 }
1870 else {
1871 count = uxQueueMessagesWaiting (hQueue);
1872 }
1873
1874 return ((uint32_t)count);
1875}
1876
1877uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) {
1878 StaticQueue_t *mq = (StaticQueue_t *)mq_id;
1879 uint32_t space;
1880 uint32_t isrm;
1881
1882 if (mq == NULL) {
1883 space = 0U;
1884 }
1885 else if (IS_IRQ()) {
1886 isrm = taskENTER_CRITICAL_FROM_ISR();
1887
1888 /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */
1889 space = mq->uxDummy4[1] - mq->uxDummy4[0];
1890
1891 taskEXIT_CRITICAL_FROM_ISR(isrm);
1892 }
1893 else {
1894 space = (uint32_t)uxQueueSpacesAvailable ((QueueHandle_t)mq);
1895 }
1896
1897 return (space);
1898}
1899
1900osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id) {
1901 QueueHandle_t hQueue = (QueueHandle_t)mq_id;
1902 osStatus_t stat;
1903
1904 if (IS_IRQ()) {
1905 stat = osErrorISR;
1906 }
1907 else if (hQueue == NULL) {
1908 stat = osErrorParameter;
1909 }
1910 else {
1911 stat = osOK;
1912 (void)xQueueReset (hQueue);
1913 }
1914
1915 return (stat);
1916}
1917
1918osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) {
1919 QueueHandle_t hQueue = (QueueHandle_t)mq_id;
1920 osStatus_t stat;
1921
1922#ifndef USE_FreeRTOS_HEAP_1
1923 if (IS_IRQ()) {
1924 stat = osErrorISR;
1925 }
1926 else if (hQueue == NULL) {
1927 stat = osErrorParameter;
1928 }
1929 else {
1930 #if (configQUEUE_REGISTRY_SIZE > 0)
1931 vQueueUnregisterQueue (hQueue);
1932 #endif
1933
1934 stat = osOK;
1935 vQueueDelete (hQueue);
1936 }
1937#else
1938 stat = osError;
1939#endif
1940
1941 return (stat);
1942}
1943
1944/*---------------------------------------------------------------------------*/
1945#ifdef FREERTOS_MPOOL_H_
1946
1947/* Static memory pool functions */
1948static void FreeBlock (MemPool_t *mp, void *block);
1949static void *AllocBlock (MemPool_t *mp);
1950static void *CreateBlock (MemPool_t *mp);
1951
1952osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) {
1953 MemPool_t *mp;
1954 const char *name;
1955 int32_t mem_cb, mem_mp;
1956 uint32_t sz;
1957
1958 if (IS_IRQ()) {
1959 mp = NULL;
1960 }
1961 else if ((block_count == 0U) || (block_size == 0U)) {
1962 mp = NULL;
1963 }
1964 else {
1965 mp = NULL;
1966 sz = MEMPOOL_ARR_SIZE (block_count, block_size);
1967
1968 name = NULL;
1969 mem_cb = -1;
1970 mem_mp = -1;
1971
1972 if (attr != NULL) {
1973 if (attr->name != NULL) {
1974 name = attr->name;
1975 }
1976
1977 if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(MemPool_t))) {
1978 /* Static control block is provided */
1979 mem_cb = 1;
1980 }
1981 else if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
1982 /* Allocate control block memory on heap */
1983 mem_cb = 0;
1984 }
1985
1986 if ((attr->mp_mem == NULL) && (attr->mp_size == 0U)) {
1987 /* Allocate memory array on heap */
1988 mem_mp = 0;
1989 }
1990 else {
1991 if (attr->mp_mem != NULL) {
1992 /* Check if array is 4-byte aligned */
1993 if (((uint32_t)attr->mp_mem & 3U) == 0U) {
1994 /* Check if array big enough */
1995 if (attr->mp_size >= sz) {
1996 /* Static memory pool array is provided */
1997 mem_mp = 1;
1998 }
1999 }
2000 }
2001 }
2002 }
2003 else {
2004 /* Attributes not provided, allocate memory on heap */
2005 mem_cb = 0;
2006 mem_mp = 0;
2007 }
2008
2009 if (mem_cb == 0) {
2010 mp = pvPortMalloc (sizeof(MemPool_t));
2011 } else {
2012 mp = attr->cb_mem;
2013 }
2014
2015 if (mp != NULL) {
2016 /* Create a semaphore (max count == initial count == block_count) */
2017 #if (configSUPPORT_STATIC_ALLOCATION == 1)
2018 mp->sem = xSemaphoreCreateCountingStatic (block_count, block_count, &mp->mem_sem);
2019 #elif (configSUPPORT_DYNAMIC_ALLOCATION == 1)
2020 mp->sem = xSemaphoreCreateCounting (block_count, block_count);
2021 #else
2022 mp->sem == NULL;
2023 #endif
2024
2025 if (mp->sem != NULL) {
2026 /* Setup memory array */
2027 if (mem_mp == 0) {
2028 mp->mem_arr = pvPortMalloc (sz);
2029 } else {
2030 mp->mem_arr = attr->mp_mem;
2031 }
2032 }
2033 }
2034
2035 if ((mp != NULL) && (mp->mem_arr != NULL)) {
2036 /* Memory pool can be created */
2037 mp->head = NULL;
2038 mp->mem_sz = sz;
2039 mp->name = name;
2040 mp->bl_sz = block_size;
2041 mp->bl_cnt = block_count;
2042 mp->n = 0U;
2043
2044 /* Set heap allocated memory flags */
2045 mp->status = MPOOL_STATUS;
2046
2047 if (mem_cb == 0) {
2048 /* Control block on heap */
2049 mp->status |= 1U;
2050 }
2051 if (mem_mp == 0) {
2052 /* Memory array on heap */
2053 mp->status |= 2U;
2054 }
2055 }
2056 else {
2057 /* Memory pool cannot be created, release allocated resources */
2058 if ((mem_cb == 0) && (mp != NULL)) {
2059 /* Free control block memory */
2060 vPortFree (mp);
2061 }
2062 mp = NULL;
2063 }
2064 }
2065
2066 return (mp);
2067}
2068
2069const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id) {
2070 MemPool_t *mp = (osMemoryPoolId_t)mp_id;
2071 const char *p;
2072
2073 if (IS_IRQ()) {
2074 p = NULL;
2075 }
2076 else if (mp_id == NULL) {
2077 p = NULL;
2078 }
2079 else {
2080 p = mp->name;
2081 }
2082
2083 return (p);
2084}
2085
2086void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) {
2087 MemPool_t *mp;
2088 void *block;
2089 uint32_t isrm;
2090
2091 if (mp_id == NULL) {
2092 /* Invalid input parameters */
2093 block = NULL;
2094 }
2095 else {
2096 block = NULL;
2097
2098 mp = (MemPool_t *)mp_id;
2099
2100 if ((mp->status & MPOOL_STATUS) == MPOOL_STATUS) {
2101 if (IS_IRQ()) {
2102 if (timeout == 0U) {
2103 if (xSemaphoreTakeFromISR (mp->sem, NULL) == pdTRUE) {
2104 if ((mp->status & MPOOL_STATUS) == MPOOL_STATUS) {
2105 isrm = taskENTER_CRITICAL_FROM_ISR();
2106
2107 /* Get a block from the free-list */
2108 block = AllocBlock(mp);
2109
2110 if (block == NULL) {
2111 /* List of free blocks is empty, 'create' new block */
2112 block = CreateBlock(mp);
2113 }
2114
2115 taskEXIT_CRITICAL_FROM_ISR(isrm);
2116 }
2117 }
2118 }
2119 }
2120 else {
2121 if (xSemaphoreTake (mp->sem, (TickType_t)timeout) == pdTRUE) {
2122 if ((mp->status & MPOOL_STATUS) == MPOOL_STATUS) {
2123 taskENTER_CRITICAL();
2124
2125 /* Get a block from the free-list */
2126 block = AllocBlock(mp);
2127
2128 if (block == NULL) {
2129 /* List of free blocks is empty, 'create' new block */
2130 block = CreateBlock(mp);
2131 }
2132
2133 taskEXIT_CRITICAL();
2134 }
2135 }
2136 }
2137 }
2138 }
2139
2140 return (block);
2141}
2142
2143osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) {
2144 MemPool_t *mp;
2145 osStatus_t stat;
2146 uint32_t isrm;
2147 BaseType_t yield;
2148
2149 if ((mp_id == NULL) || (block == NULL)) {
2150 /* Invalid input parameters */
2151 stat = osErrorParameter;
2152 }
2153 else {
2154 mp = (MemPool_t *)mp_id;
2155
2156 if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
2157 /* Invalid object status */
2158 stat = osErrorResource;
2159 }
2160 else if ((block < (void *)&mp->mem_arr[0]) || (block > (void*)&mp->mem_arr[mp->mem_sz-1])) {
2161 /* Block pointer outside of memory array area */
2162 stat = osErrorParameter;
2163 }
2164 else {
2165 stat = osOK;
2166
2167 if (IS_IRQ()) {
2168 if (uxSemaphoreGetCountFromISR (mp->sem) == mp->bl_cnt) {
2169 stat = osErrorResource;
2170 }
2171 else {
2172 isrm = taskENTER_CRITICAL_FROM_ISR();
2173
2174 /* Add block to the list of free blocks */
2175 FreeBlock(mp, block);
2176
2177 taskEXIT_CRITICAL_FROM_ISR(isrm);
2178
2179 yield = pdFALSE;
2180 xSemaphoreGiveFromISR (mp->sem, &yield);
2181 portYIELD_FROM_ISR (yield);
2182 }
2183 }
2184 else {
2185 if (uxSemaphoreGetCount (mp->sem) == mp->bl_cnt) {
2186 stat = osErrorResource;
2187 }
2188 else {
2189 taskENTER_CRITICAL();
2190
2191 /* Add block to the list of free blocks */
2192 FreeBlock(mp, block);
2193
2194 taskEXIT_CRITICAL();
2195
2196 xSemaphoreGive (mp->sem);
2197 }
2198 }
2199 }
2200 }
2201
2202 return (stat);
2203}
2204
2205uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) {
2206 MemPool_t *mp;
2207 uint32_t n;
2208
2209 if (mp_id == NULL) {
2210 /* Invalid input parameters */
2211 n = 0U;
2212 }
2213 else {
2214 mp = (MemPool_t *)mp_id;
2215
2216 if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
2217 /* Invalid object status */
2218 n = 0U;
2219 }
2220 else {
2221 n = mp->bl_cnt;
2222 }
2223 }
2224
2225 /* Return maximum number of memory blocks */
2226 return (n);
2227}
2228
2229uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) {
2230 MemPool_t *mp;
2231 uint32_t sz;
2232
2233 if (mp_id == NULL) {
2234 /* Invalid input parameters */
2235 sz = 0U;
2236 }
2237 else {
2238 mp = (MemPool_t *)mp_id;
2239
2240 if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
2241 /* Invalid object status */
2242 sz = 0U;
2243 }
2244 else {
2245 sz = mp->bl_sz;
2246 }
2247 }
2248
2249 /* Return memory block size in bytes */
2250 return (sz);
2251}
2252
2253uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id) {
2254 MemPool_t *mp;
2255 uint32_t n;
2256
2257 if (mp_id == NULL) {
2258 /* Invalid input parameters */
2259 n = 0U;
2260 }
2261 else {
2262 mp = (MemPool_t *)mp_id;
2263
2264 if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
2265 /* Invalid object status */
2266 n = 0U;
2267 }
2268 else {
2269 if (IS_IRQ()) {
2270 n = uxSemaphoreGetCountFromISR (mp->sem);
2271 } else {
2272 n = uxSemaphoreGetCount (mp->sem);
2273 }
2274
2275 n = mp->bl_cnt - n;
2276 }
2277 }
2278
2279 /* Return number of memory blocks used */
2280 return (n);
2281}
2282
2283uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id) {
2284 MemPool_t *mp;
2285 uint32_t n;
2286
2287 if (mp_id == NULL) {
2288 /* Invalid input parameters */
2289 n = 0U;
2290 }
2291 else {
2292 mp = (MemPool_t *)mp_id;
2293
2294 if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
2295 /* Invalid object status */
2296 n = 0U;
2297 }
2298 else {
2299 if (IS_IRQ()) {
2300 n = uxSemaphoreGetCountFromISR (mp->sem);
2301 } else {
2302 n = uxSemaphoreGetCount (mp->sem);
2303 }
2304 }
2305 }
2306
2307 /* Return number of memory blocks available */
2308 return (n);
2309}
2310
2311osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id) {
2312 MemPool_t *mp;
2313 osStatus_t stat;
2314
2315 if (mp_id == NULL) {
2316 /* Invalid input parameters */
2317 stat = osErrorParameter;
2318 }
2319 else if (IS_IRQ()) {
2320 stat = osErrorISR;
2321 }
2322 else {
2323 mp = (MemPool_t *)mp_id;
2324
2325 taskENTER_CRITICAL();
2326
2327 /* Invalidate control block status */
2328 mp->status = mp->status & 3U;
2329
2330 /* Wake-up tasks waiting for pool semaphore */
2331 while (xSemaphoreGive (mp->sem) == pdTRUE);
2332
2333 mp->head = NULL;
2334 mp->bl_sz = 0U;
2335 mp->bl_cnt = 0U;
2336
2337 if ((mp->status & 2U) != 0U) {
2338 /* Memory pool array allocated on heap */
2339 vPortFree (mp->mem_arr);
2340 }
2341 if ((mp->status & 1U) != 0U) {
2342 /* Memory pool control block allocated on heap */
2343 vPortFree (mp);
2344 }
2345
2346 taskEXIT_CRITICAL();
2347
2348 stat = osOK;
2349 }
2350
2351 return (stat);
2352}
2353
2354/*
2355 Create new block given according to the current block index.
2356*/
2357static void *CreateBlock (MemPool_t *mp) {
2358 MemPoolBlock_t *p = NULL;
2359
2360 if (mp->n < mp->bl_cnt) {
2361 /* Unallocated blocks exist, set pointer to new block */
2362 p = (void *)(mp->mem_arr + (mp->bl_sz * mp->n));
2363
2364 /* Increment block index */
2365 mp->n += 1U;
2366 }
2367
2368 return (p);
2369}
2370
2371/*
2372 Allocate a block by reading the list of free blocks.
2373*/
2374static void *AllocBlock (MemPool_t *mp) {
2375 MemPoolBlock_t *p = NULL;
2376
2377 if (mp->head != NULL) {
2378 /* List of free block exists, get head block */
2379 p = mp->head;
2380
2381 /* Head block is now next on the list */
2382 mp->head = p->next;
2383 }
2384
2385 return (p);
2386}
2387
2388/*
2389 Free block by putting it to the list of free blocks.
2390*/
2391static void FreeBlock (MemPool_t *mp, void *block) {
2392 MemPoolBlock_t *p = block;
2393
2394 /* Store current head into block memory space */
2395 p->next = mp->head;
2396
2397 /* Store current block as new head */
2398 mp->head = p;
2399}
2400#endif /* FREERTOS_MPOOL_H_ */
2401/*---------------------------------------------------------------------------*/
2402
2403/* Callback function prototypes */
2404extern void vApplicationIdleHook (void);
2405extern void vApplicationTickHook (void);
2406extern void vApplicationMallocFailedHook (void);
2407extern void vApplicationDaemonTaskStartupHook (void);
2408extern void vApplicationStackOverflowHook (TaskHandle_t xTask, signed char *pcTaskName);
2409
2410/**
2411 Dummy implementation of the callback function vApplicationIdleHook().
2412*/
2413#if (configUSE_IDLE_HOOK == 1)
2414__WEAK void vApplicationIdleHook (void){}
2415#endif
2416
2417/**
2418 Dummy implementation of the callback function vApplicationTickHook().
2419*/
2420#if (configUSE_TICK_HOOK == 1)
2421 __WEAK void vApplicationTickHook (void){}
2422#endif
2423
2424/**
2425 Dummy implementation of the callback function vApplicationMallocFailedHook().
2426*/
2427#if (configUSE_MALLOC_FAILED_HOOK == 1)
2428__WEAK void vApplicationMallocFailedHook (void){}
2429#endif
2430
2431/**
2432 Dummy implementation of the callback function vApplicationDaemonTaskStartupHook().
2433*/
2434#if (configUSE_DAEMON_TASK_STARTUP_HOOK == 1)
2435__WEAK void vApplicationDaemonTaskStartupHook (void){}
2436#endif
2437
2438/**
2439 Dummy implementation of the callback function vApplicationStackOverflowHook().
2440*/
2441#if (configCHECK_FOR_STACK_OVERFLOW > 0)
2442__WEAK void vApplicationStackOverflowHook (TaskHandle_t xTask, signed char *pcTaskName) {
2443 (void)xTask;
2444 (void)pcTaskName;
2445 configASSERT(0);
2446}
2447#endif
2448
2449/*---------------------------------------------------------------------------*/
2450#if (configSUPPORT_STATIC_ALLOCATION == 1)
2451/* External Idle and Timer task static memory allocation functions */
2452extern void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize);
2453extern void vApplicationGetTimerTaskMemory (StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize);
2454
2455/*
2456 vApplicationGetIdleTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
2457 equals to 1 and is required for static memory allocation support.
2458*/
2459__WEAK void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {
2460 /* Idle task control block and stack */
2461 static StaticTask_t Idle_TCB;
2462 static StackType_t Idle_Stack[configMINIMAL_STACK_SIZE];
2463
2464 *ppxIdleTaskTCBBuffer = &Idle_TCB;
2465 *ppxIdleTaskStackBuffer = &Idle_Stack[0];
2466 *pulIdleTaskStackSize = (uint32_t)configMINIMAL_STACK_SIZE;
2467}
2468
2469/*
2470 vApplicationGetTimerTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
2471 equals to 1 and is required for static memory allocation support.
2472*/
2473__WEAK void vApplicationGetTimerTaskMemory (StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) {
2474 /* Timer task control block and stack */
2475 static StaticTask_t Timer_TCB;
2476 static StackType_t Timer_Stack[configTIMER_TASK_STACK_DEPTH];
2477
2478 *ppxTimerTaskTCBBuffer = &Timer_TCB;
2479 *ppxTimerTaskStackBuffer = &Timer_Stack[0];
2480 *pulTimerTaskStackSize = (uint32_t)configTIMER_TASK_STACK_DEPTH;
2481}
2482#endif
Note: See TracBrowser for help on using the repository browser.