1 /*! *********************************************************************************
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017, 2019 NXP
4  * All rights reserved.
5  *
6  *
7  * This is the source file for the OS Abstraction layer for freertos.
8  *
9  * SPDX-License-Identifier: BSD-3-Clause
10  ********************************************************************************** */
11 
12 /*! *********************************************************************************
13 *************************************************************************************
14 * Include
15 *************************************************************************************
16 ********************************************************************************** */
17 #include "fsl_common.h"
18 #include "fsl_os_abstraction.h"
19 #include "fsl_os_abstraction_free_rtos.h"
20 #include <string.h>
21 #include "fsl_component_generic_list.h"
22 
23 /*! *********************************************************************************
24 *************************************************************************************
25 * Private macros
26 *************************************************************************************
27 ********************************************************************************** */
28 
29 /* Weak function. */
30 #if defined(__GNUC__)
31 #define __WEAK_FUNC __attribute__((weak))
32 #elif defined(__ICCARM__)
33 #define __WEAK_FUNC __weak
34 #elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
35 #define __WEAK_FUNC __attribute__((weak))
36 #endif
37 
38 #define millisecToTicks(millisec) (((millisec)*configTICK_RATE_HZ + 999U) / 1000U)
39 
40 #ifdef DEBUG_ASSERT
41 #define OS_ASSERT(condition) \
42     if (!(condition))        \
43         while (1)            \
44             ;
45 #else
46 #define OS_ASSERT(condition) (void)(condition);
47 #endif
48 
49 /*! @brief Converts milliseconds to ticks*/
50 #define MSEC_TO_TICK(msec) \
51     (((uint32_t)(msec) + 500uL / (uint32_t)configTICK_RATE_HZ) * (uint32_t)configTICK_RATE_HZ / 1000uL)
52 #define TICKS_TO_MSEC(tick) ((uint32_t)((uint64_t)(tick)*1000uL / (uint64_t)configTICK_RATE_HZ))
53 
54 #define OSA_MEM_MAGIC_NUMBER (12345U)
55 #define OSA_MEM_SIZE_ALIGN(var, alignbytes) \
56     ((unsigned int)((var) + ((alignbytes)-1U)) & (unsigned int)(~(unsigned int)((alignbytes)-1U)))
57 
58 /************************************************************************************
59 *************************************************************************************
60 * Private type definitions
61 *************************************************************************************
62 ************************************************************************************/
63 typedef struct osa_freertos_task
64 {
65     list_element_t link;
66     TaskHandle_t taskHandle;
67 } osa_freertos_task_t;
68 
69 typedef struct _osa_event_struct
70 {
71     EventGroupHandle_t eventHandle; /* The event handle */
72     uint8_t autoClear;         /*!< Auto clear or manual clear   */
73 } osa_event_struct_t;
74 
75 /*! @brief State structure for bm osa manager. */
76 typedef struct _osa_state
77 {
78 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
79     list_label_t taskList;
80 #if (defined(FSL_OSA_MAIN_FUNC_ENABLE) && (FSL_OSA_MAIN_FUNC_ENABLE > 0U))
81     OSA_TASK_HANDLE_DEFINE(mainTaskHandle);
82 #endif
83 #endif
84     uint32_t basePriority;
85     int32_t basePriorityNesting;
86     uint32_t interruptDisableCount;
87 } osa_state_t;
88 
89 /*! @brief Definition structure contains allocated memory information.*/
90 typedef struct _osa_mem_align_control_block
91 {
92     uint16_t identifier; /*!< Identifier for the memory control block. */
93     uint16_t offset;     /*!< offset from aligned address to real address */
94 } osa_mem_align_cb_t;
95 
96 /*! *********************************************************************************
97 *************************************************************************************
98 * Private prototypes
99 *************************************************************************************
100 ********************************************************************************** */
101 __WEAK_FUNC void main_task(void const *argument);
main_task(void const * argument)102 __WEAK_FUNC void main_task(void const *argument)
103 {
104 }
105 
106 void startup_task(void *argument);
107 
108 /*! *********************************************************************************
109 *************************************************************************************
110 * Public memory declarations
111 *************************************************************************************
112 ********************************************************************************** */
113 const uint8_t gUseRtos_c = USE_RTOS; /* USE_RTOS = 0 for BareMetal and 1 for OS */
114 
115 static osa_state_t s_osaState = {0};
116 
117 /* Allocate the memory for the heap. */
118 #if (defined(FSL_OSA_ALLOCATED_HEAP) && (FSL_OSA_ALLOCATED_HEAP > 0U))
119 #if defined(configAPPLICATION_ALLOCATED_HEAP) && (configAPPLICATION_ALLOCATED_HEAP)
120 #if defined(DATA_SECTION_IS_CACHEABLE) && (DATA_SECTION_IS_CACHEABLE)
121 extern uint8_t ucHeap[configTOTAL_HEAP_SIZE];
122 AT_NONCACHEABLE_SECTION_ALIGN(uint8_t ucHeap[configTOTAL_HEAP_SIZE], 4);
123 #else
124 extern uint8_t ucHeap[configTOTAL_HEAP_SIZE];
125 SDK_ALIGN(uint8_t ucHeap[configTOTAL_HEAP_SIZE], 4);
126 #endif /* DATA_SECTION_IS_CACHEABLE */
127 #endif /* configAPPLICATION_ALLOCATED_HEAP */
128 #endif /* FSL_OSA_ALLOCATED_HEAP */
129 
130 /*! *********************************************************************************
131 *************************************************************************************
132 * Private memory declarations
133 *************************************************************************************
134 ********************************************************************************** */
135 
136 /*! *********************************************************************************
137 *************************************************************************************
138 * Public functions
139 *************************************************************************************
140 ********************************************************************************** */
141 /*FUNCTION**********************************************************************
142  *
143  * Function Name : OSA_MemoryAllocate
144  * Description   : Reserves the requested amount of memory in bytes.
145  *
146  *END**************************************************************************/
OSA_MemoryAllocate(uint32_t memLength)147 void *OSA_MemoryAllocate(uint32_t memLength)
148 {
149 #if defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0)
150 
151     void *p = (void *)pvPortMalloc(memLength);
152 
153     if (NULL != p)
154     {
155         (void)memset(p, 0, memLength);
156     }
157 
158     return p;
159 #else
160     return NULL;
161 #endif
162 }
163 
164 /*FUNCTION**********************************************************************
165  *
166  * Function Name : OSA_MemoryFree
167  * Description   : Frees the memory previously reserved.
168  *
169  *END**************************************************************************/
OSA_MemoryFree(void * p)170 void OSA_MemoryFree(void *p)
171 {
172 #if defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0)
173     vPortFree(p);
174 #endif
175 }
176 
OSA_MemoryAllocateAlign(uint32_t memLength,uint32_t alignbytes)177 void *OSA_MemoryAllocateAlign(uint32_t memLength, uint32_t alignbytes)
178 {
179     osa_mem_align_cb_t *p_cb = NULL;
180     uint32_t alignedsize;
181 
182     /* Check overflow. */
183     alignedsize = (uint32_t)(unsigned int)OSA_MEM_SIZE_ALIGN(memLength, alignbytes);
184     if (alignedsize < memLength)
185     {
186         return NULL;
187     }
188 
189     if (alignedsize > 0xFFFFFFFFU - alignbytes - sizeof(osa_mem_align_cb_t))
190     {
191         return NULL;
192     }
193 
194     alignedsize += alignbytes + (uint32_t)sizeof(osa_mem_align_cb_t);
195 
196     union
197     {
198         void *pointer_value;
199         uintptr_t unsigned_value;
200     } p_align_addr, p_addr;
201 
202     p_addr.pointer_value = OSA_MemoryAllocate(alignedsize);
203 
204     if (p_addr.pointer_value == NULL)
205     {
206         return NULL;
207     }
208 
209     p_align_addr.unsigned_value = OSA_MEM_SIZE_ALIGN(p_addr.unsigned_value + sizeof(osa_mem_align_cb_t), alignbytes);
210 
211     p_cb             = (osa_mem_align_cb_t *)(p_align_addr.unsigned_value - 4U);
212     p_cb->identifier = OSA_MEM_MAGIC_NUMBER;
213     p_cb->offset     = (uint16_t)(p_align_addr.unsigned_value - p_addr.unsigned_value);
214 
215     return p_align_addr.pointer_value;
216 }
217 
OSA_MemoryFreeAlign(void * p)218 void OSA_MemoryFreeAlign(void *p)
219 {
220     union
221     {
222         void *pointer_value;
223         uintptr_t unsigned_value;
224     } p_free;
225     p_free.pointer_value = p;
226     osa_mem_align_cb_t *p_cb = (osa_mem_align_cb_t *)(p_free.unsigned_value - 4U);
227 
228     if (p_cb->identifier != OSA_MEM_MAGIC_NUMBER)
229     {
230         return;
231     }
232 
233     p_free.unsigned_value = p_free.unsigned_value - p_cb->offset;
234 
235     OSA_MemoryFree(p_free.pointer_value);
236 }
237 
OSA_EnterCritical(uint32_t * sr)238 void OSA_EnterCritical(uint32_t *sr)
239 {
240 #if defined(__GIC_PRIO_BITS)
241     if ((__get_CPSR() & CPSR_M_Msk) == 0x13)
242 #else
243     if (0U != __get_IPSR())
244 #endif
245     {
246         *sr = portSET_INTERRUPT_MASK_FROM_ISR();
247     }
248     else
249     {
250         portENTER_CRITICAL();
251     }
252 }
253 
OSA_ExitCritical(uint32_t sr)254 void OSA_ExitCritical(uint32_t sr)
255 {
256 #if defined(__GIC_PRIO_BITS)
257     if ((__get_CPSR() & CPSR_M_Msk) == 0x13)
258 #else
259     if (0U != __get_IPSR())
260 #endif
261     {
262         portCLEAR_INTERRUPT_MASK_FROM_ISR(sr);
263     }
264     else
265     {
266         portEXIT_CRITICAL();
267     }
268 }
269 
270 /*FUNCTION**********************************************************************
271  *
272  * Function Name : startup_task
273  * Description   : Wrapper over main_task..
274  *
275  *END**************************************************************************/
startup_task(void * argument)276 void startup_task(void *argument)
277 {
278     main_task(argument);
279 }
280 
281 /*FUNCTION**********************************************************************
282  *
283  * Function Name : OSA_TaskGetCurrentHandle
284  * Description   : This function is used to get current active task's handler.
285  *
286  *END**************************************************************************/
287 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskGetCurrentHandle(void)288 osa_task_handle_t OSA_TaskGetCurrentHandle(void)
289 {
290     list_element_handle_t list_element;
291     osa_freertos_task_t *ptask;
292 
293     list_element = LIST_GetHead(&s_osaState.taskList);
294     while (NULL != list_element)
295     {
296         ptask = (osa_freertos_task_t *)(void *)list_element;
297         if (ptask->taskHandle == xTaskGetCurrentTaskHandle())
298         {
299             return (osa_task_handle_t)ptask;
300         }
301         list_element = LIST_GetNext(list_element);
302     }
303     return NULL;
304 }
305 #endif
306 
307 /*FUNCTION**********************************************************************
308  *
309  * Function Name : OSA_TaskYield
310  * Description   : When a task calls this function, it will give up CPU and put
311  * itself to the tail of ready list.
312  *
313  *END**************************************************************************/
314 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskYield(void)315 void OSA_TaskYield(void)
316 {
317     taskYIELD();
318 }
319 #endif
320 
321 /*FUNCTION**********************************************************************
322  *
323  * Function Name : OSA_TaskGetPriority
324  * Description   : This function returns task's priority by task handler.
325  *
326  *END**************************************************************************/
327 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskGetPriority(osa_task_handle_t taskHandle)328 osa_task_priority_t OSA_TaskGetPriority(osa_task_handle_t taskHandle)
329 {
330     assert(NULL != taskHandle);
331     osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
332     return (osa_task_priority_t)(PRIORITY_RTOS_TO_OSA((uxTaskPriorityGet(ptask->taskHandle))));
333 }
334 #endif
335 
336 /*FUNCTION**********************************************************************
337  *
338  * Function Name : OSA_TaskSetPriority
339  * Description   : This function sets task's priority by task handler.
340  *
341  *END**************************************************************************/
342 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskSetPriority(osa_task_handle_t taskHandle,osa_task_priority_t taskPriority)343 osa_status_t OSA_TaskSetPriority(osa_task_handle_t taskHandle, osa_task_priority_t taskPriority)
344 {
345     assert(NULL != taskHandle);
346     osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
347     vTaskPrioritySet((task_handler_t)ptask->taskHandle, PRIORITY_OSA_TO_RTOS(((uint32_t)taskPriority)));
348     return KOSA_StatusSuccess;
349 }
350 #endif
351 
352 /*FUNCTION**********************************************************************
353  *
354  * Function Name : OSA_TaskCreate
355  * Description   : This function is used to create a task and make it ready.
356  * Param[in]     :  threadDef  - Definition of the thread.
357  *                  task_param - Parameter to pass to the new thread.
358  * Return Thread handle of the new thread, or NULL if failed.
359  *
360  *END**************************************************************************/
361 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskCreate(osa_task_handle_t taskHandle,const osa_task_def_t * thread_def,osa_task_param_t task_param)362 osa_status_t OSA_TaskCreate(osa_task_handle_t taskHandle, const osa_task_def_t *thread_def, osa_task_param_t task_param)
363 {
364     osa_status_t status = KOSA_StatusError;
365 #if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
366     !((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
367     assert((sizeof(osa_freertos_task_t) + sizeof(StaticTask_t)) <= OSA_TASK_HANDLE_SIZE);
368 #else
369     assert(sizeof(osa_freertos_task_t) == OSA_TASK_HANDLE_SIZE);
370 #endif
371     assert(NULL != taskHandle);
372 #if defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0)
373     TaskHandle_t pxCreatedTask;
374 #endif
375     osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
376 #if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
377     !((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
378     TaskHandle_t xHandle = NULL;
379 #endif
380     OSA_InterruptDisable();
381 #if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
382     !((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
383     xHandle = xTaskCreateStatic(
384             (TaskFunction_t)thread_def->pthread, /* pointer to the task */
385                         (const char *)thread_def->tname,     /* task name for kernel awareness debugging */
386                         (uint32_t)((uint16_t)thread_def->stacksize / sizeof(portSTACK_TYPE)), /* task stack size */
387                         (task_param_t)task_param,                      /* optional task startup argument */
388                         PRIORITY_OSA_TO_RTOS((thread_def->tpriority)), /* initial priority */
389                         (StackType_t *) thread_def->tstack,    /*Array to use as the task's stack*/
390                         (StaticTask_t *)((uint8_t *)(taskHandle) + sizeof(osa_freertos_task_t))/*Variable to hold the task's data structure*/
391                         );
392       if(xHandle != NULL)
393       {
394           ptask->taskHandle = xHandle;
395           (void)LIST_AddTail(&s_osaState.taskList, (list_element_handle_t) & (ptask->link));
396           status = KOSA_StatusSuccess;
397       }
398 #else
399     if (xTaskCreate(
400             (TaskFunction_t)thread_def->pthread, /* pointer to the task */
401             (char const *)thread_def->tname,     /* task name for kernel awareness debugging */
402             (configSTACK_DEPTH_TYPE)((uint16_t)thread_def->stacksize / sizeof(portSTACK_TYPE)), /* task stack size */
403             (task_param_t)task_param,                      /* optional task startup argument */
404             PRIORITY_OSA_TO_RTOS((thread_def->tpriority)), /* initial priority */
405             &pxCreatedTask                                 /* optional task handle to create */
406             ) == pdPASS)
407     {
408         ptask->taskHandle = pxCreatedTask;
409 
410         (void)LIST_AddTail(&s_osaState.taskList, (list_element_handle_t) & (ptask->link));
411 
412         status = KOSA_StatusSuccess;
413     }
414 #endif
415     OSA_InterruptEnable();
416     return status;
417 }
418 #endif
419 
420 /*FUNCTION**********************************************************************
421  *
422  * Function Name : OSA_TaskDestroy
423  * Description   : This function destroy a task.
424  * Param[in]     :taskHandle - Thread handle.
425  * Return KOSA_StatusSuccess if the task is destroied, otherwise return KOSA_StatusError.
426  *
427  *END**************************************************************************/
428 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskDestroy(osa_task_handle_t taskHandle)429 osa_status_t OSA_TaskDestroy(osa_task_handle_t taskHandle)
430 {
431     assert(NULL != taskHandle);
432     osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
433     osa_status_t status;
434     UBaseType_t oldPriority;
435 
436     /*Change priority to avoid context switches*/
437     oldPriority = uxTaskPriorityGet(xTaskGetCurrentTaskHandle());
438     vTaskPrioritySet(xTaskGetCurrentTaskHandle(), (configMAX_PRIORITIES - 1));
439 #if INCLUDE_vTaskDelete /* vTaskDelete() enabled */
440     vTaskDelete((task_handler_t)ptask->taskHandle);
441     status = KOSA_StatusSuccess;
442 #else
443     status = KOSA_StatusError; /* vTaskDelete() not available */
444 #endif
445     vTaskPrioritySet(xTaskGetCurrentTaskHandle(), oldPriority);
446     OSA_InterruptDisable();
447     (void)LIST_RemoveElement(taskHandle);
448     OSA_InterruptEnable();
449     return status;
450 }
451 #endif
452 
453 /*FUNCTION**********************************************************************
454  *
455  * Function Name : OSA_TimeDelay
456  * Description   : This function is used to suspend the active thread for the given number of milliseconds.
457  *
458  *END**************************************************************************/
OSA_TimeDelay(uint32_t millisec)459 void OSA_TimeDelay(uint32_t millisec)
460 {
461     vTaskDelay(millisecToTicks(millisec));
462 }
463 /*FUNCTION**********************************************************************
464  *
465  * Function Name : OSA_TimeGetMsec
466  * Description   : This function gets current time in milliseconds.
467  *
468  *END**************************************************************************/
OSA_TimeGetMsec(void)469 uint32_t OSA_TimeGetMsec(void)
470 {
471     TickType_t ticks;
472 
473     if (0U != __get_IPSR())
474     {
475         ticks = xTaskGetTickCountFromISR();
476     }
477     else
478     {
479         ticks = xTaskGetTickCount();
480     }
481 
482     return TICKS_TO_MSEC(ticks);
483 }
484 
485 /*FUNCTION**********************************************************************
486  *
487  * Function Name : OSA_SemaphorePrecreate
488  * Description   : This function is used to pre-create a semaphore.
489  * Return         : KOSA_StatusSuccess
490  *
491  *END**************************************************************************/
492 
OSA_SemaphorePrecreate(osa_semaphore_handle_t semaphoreHandle,osa_task_ptr_t taskHandler)493 osa_status_t OSA_SemaphorePrecreate(osa_semaphore_handle_t semaphoreHandle, osa_task_ptr_t taskHandler)
494 {
495     semaphoreHandle = semaphoreHandle;
496     taskHandler     = taskHandler;
497     return KOSA_StatusSuccess;
498 }
499 
500 /*FUNCTION**********************************************************************
501  *
502  * Function Name : OSA_SemaphoreCreate
503  * Description   : This function is used to create a semaphore.
504  * Return         : Semaphore handle of the new semaphore, or NULL if failed.
505  *
506  *END**************************************************************************/
OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle,uint32_t initValue)507 osa_status_t OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle, uint32_t initValue)
508 {
509 #if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
510     !((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
511     assert((sizeof(osa_semaphore_handle_t) + sizeof(StaticQueue_t)) == OSA_SEM_HANDLE_SIZE);
512 #else
513     assert(sizeof(osa_semaphore_handle_t) == OSA_SEM_HANDLE_SIZE);
514 #endif
515     assert(NULL != semaphoreHandle);
516 
517     union
518     {
519         QueueHandle_t sem;
520         uint32_t semhandle;
521     } xSemaHandle;
522 #if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
523     !((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
524     xSemaHandle.sem = xSemaphoreCreateCountingStatic(0xFF, initValue, (StaticQueue_t *)(void *)((uint8_t *)semaphoreHandle + sizeof(osa_semaphore_handle_t)));
525 #else
526     xSemaHandle.sem = xSemaphoreCreateCounting(0xFF, initValue);
527 #endif
528     if (NULL != xSemaHandle.sem)
529     {
530         *(uint32_t *)semaphoreHandle = xSemaHandle.semhandle;
531         return KOSA_StatusSuccess;
532     }
533     return KOSA_StatusError;
534 }
535 
536 /*FUNCTION**********************************************************************
537  *
538  * Function Name : OSA_SemaphoreCreateBinary
539  * Description   : This function is used to create a binary semaphore.
540  * Return        : Semaphore handle of the new binary semaphore, or NULL if failed.
541  *
542  *END**************************************************************************/
OSA_SemaphoreCreateBinary(osa_semaphore_handle_t semaphoreHandle)543 osa_status_t OSA_SemaphoreCreateBinary(osa_semaphore_handle_t semaphoreHandle)
544 {
545 #if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
546     !((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
547     assert((sizeof(osa_semaphore_handle_t) + sizeof(StaticQueue_t)) == OSA_SEM_HANDLE_SIZE);
548 #else
549     assert(sizeof(osa_semaphore_handle_t) == OSA_SEM_HANDLE_SIZE);
550 #endif
551     assert(NULL != semaphoreHandle);
552 
553     union
554     {
555         QueueHandle_t sem;
556         uint32_t semhandle;
557     } xSemaHandle;
558 #if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
559     !((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
560     xSemaHandle.sem = xSemaphoreCreateBinaryStatic((StaticQueue_t *)(void *)((uint8_t *)semaphoreHandle + sizeof(osa_semaphore_handle_t)));
561 #else
562     xSemaHandle.sem = xSemaphoreCreateBinary();
563 #endif
564     if (NULL != xSemaHandle.sem)
565     {
566         *(uint32_t *)semaphoreHandle = xSemaHandle.semhandle;
567         return KOSA_StatusSuccess;
568     }
569     return KOSA_StatusError;
570 }
571 
572 /*FUNCTION**********************************************************************
573  *
574  * Function Name : OSA_SemaphoreDestroy
575  * Description   : This function is used to destroy a semaphore.
576  * Return        : KOSA_StatusSuccess if the semaphore is destroyed successfully, otherwise return KOSA_StatusError.
577  *
578  *END**************************************************************************/
OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle)579 osa_status_t OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle)
580 {
581     assert(NULL != semaphoreHandle);
582     QueueHandle_t sem = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)semaphoreHandle);
583 
584     vSemaphoreDelete(sem);
585     return KOSA_StatusSuccess;
586 }
587 
588 /*FUNCTION**********************************************************************
589  *
590  * Function Name : OSA_SemaphoreWait
591  * Description   : This function checks the semaphore's counting value, if it is
592  * positive, decreases it and returns KOSA_StatusSuccess, otherwise, timeout
593  * will be used for wait. The parameter timeout indicates how long should wait
594  * in milliseconds. Pass osaWaitForever_c to wait indefinitely, pass 0 will
595  * return KOSA_StatusTimeout immediately if semaphore is not positive.
596  * This function returns KOSA_StatusSuccess if the semaphore is received, returns
597  * KOSA_StatusTimeout if the semaphore is not received within the specified
598  * 'timeout', returns KOSA_StatusError if any errors occur during waiting.
599  *
600  *END**************************************************************************/
OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle,uint32_t millisec)601 osa_status_t OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle, uint32_t millisec)
602 {
603     uint32_t timeoutTicks;
604     assert(NULL != semaphoreHandle);
605     QueueHandle_t sem = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)semaphoreHandle);
606 
607     /* Convert timeout from millisecond to tick. */
608     if (millisec == osaWaitForever_c)
609     {
610         timeoutTicks = portMAX_DELAY;
611     }
612     else
613     {
614         timeoutTicks = MSEC_TO_TICK(millisec);
615     }
616 
617     if (((BaseType_t)0) == (BaseType_t)xSemaphoreTake(sem, timeoutTicks))
618     {
619         return KOSA_StatusTimeout; /* timeout */
620     }
621     else
622     {
623         return KOSA_StatusSuccess; /* semaphore taken */
624     }
625 }
626 
627 /*FUNCTION**********************************************************************
628  *
629  * Function Name : OSA_SemaphorePost
630  * Description   : This function is used to wake up one task that wating on the
631  * semaphore. If no task is waiting, increase the semaphore. The function returns
632  * KOSA_StatusSuccess if the semaphre is post successfully, otherwise returns
633  * KOSA_StatusError.
634  *
635  *END**************************************************************************/
OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle)636 osa_status_t OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle)
637 {
638     assert(NULL != semaphoreHandle);
639     osa_status_t status = KOSA_StatusError;
640     QueueHandle_t sem   = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)semaphoreHandle);
641 
642     if (0U != __get_IPSR())
643     {
644         portBASE_TYPE taskToWake = (portBASE_TYPE)pdFALSE;
645 
646         if (((BaseType_t)1) == (BaseType_t)xSemaphoreGiveFromISR(sem, &taskToWake))
647         {
648             portYIELD_FROM_ISR(((bool)(taskToWake)));
649             status = KOSA_StatusSuccess;
650         }
651         else
652         {
653             status = KOSA_StatusError;
654         }
655     }
656     else
657     {
658         if (((BaseType_t)1) == (BaseType_t)xSemaphoreGive(sem))
659         {
660             status = KOSA_StatusSuccess; /* sync object given */
661         }
662         else
663         {
664             status = KOSA_StatusError;
665         }
666     }
667     return status;
668 }
669 
670 /*FUNCTION**********************************************************************
671  *
672  * Function Name : OSA_MutexCreate
673  * Description   : This function is used to create a mutex.
674  * Return        : Mutex handle of the new mutex, or NULL if failed.
675  *
676  *END**************************************************************************/
OSA_MutexCreate(osa_mutex_handle_t mutexHandle)677 osa_status_t OSA_MutexCreate(osa_mutex_handle_t mutexHandle)
678 {
679 #if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
680     !((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
681     assert((sizeof(osa_mutex_handle_t) + sizeof(StaticQueue_t)) == OSA_MUTEX_HANDLE_SIZE);
682 #else
683     assert(sizeof(osa_mutex_handle_t) == OSA_MUTEX_HANDLE_SIZE);
684 #endif
685     assert(NULL != mutexHandle);
686 
687     union
688     {
689         QueueHandle_t mutex;
690         uint32_t pmutexHandle;
691     } xMutexHandle;
692 #if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
693     !((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
694     xMutexHandle.mutex = xSemaphoreCreateRecursiveMutexStatic((StaticQueue_t *)(void *)((uint8_t *)mutexHandle + sizeof(osa_mutex_handle_t)));
695 #else
696     xMutexHandle.mutex = xSemaphoreCreateRecursiveMutex();
697 #endif
698     if (NULL != xMutexHandle.mutex)
699     {
700         *(uint32_t *)mutexHandle = xMutexHandle.pmutexHandle;
701         return KOSA_StatusSuccess;
702     }
703     return KOSA_StatusError;
704 }
705 
706 /*FUNCTION**********************************************************************
707  *
708  * Function Name : OSA_MutexLock
709  * Description   : This function checks the mutex's status, if it is unlocked,
710  * lock it and returns KOSA_StatusSuccess, otherwise, wait for the mutex.
711  * This function returns KOSA_StatusSuccess if the mutex is obtained, returns
712  * KOSA_StatusError if any errors occur during waiting. If the mutex has been
713  * locked, pass 0 as timeout will return KOSA_StatusTimeout immediately.
714  *
715  *END**************************************************************************/
OSA_MutexLock(osa_mutex_handle_t mutexHandle,uint32_t millisec)716 osa_status_t OSA_MutexLock(osa_mutex_handle_t mutexHandle, uint32_t millisec)
717 {
718     assert(NULL != mutexHandle);
719     uint32_t timeoutTicks;
720     QueueHandle_t mutex = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)mutexHandle);
721 
722     /* Convert timeout from millisecond to tick. */
723     if (millisec == osaWaitForever_c)
724     {
725         timeoutTicks = portMAX_DELAY;
726     }
727     else
728     {
729         timeoutTicks = MSEC_TO_TICK(millisec);
730     }
731 
732     if (((BaseType_t)0) == (BaseType_t)xSemaphoreTakeRecursive(mutex, timeoutTicks))
733     {
734         return KOSA_StatusTimeout; /* timeout */
735     }
736     else
737     {
738         return KOSA_StatusSuccess; /* semaphore taken */
739     }
740 }
741 
742 /*FUNCTION**********************************************************************
743  *
744  * Function Name : OSA_MutexUnlock
745  * Description   : This function is used to unlock a mutex.
746  *
747  *END**************************************************************************/
OSA_MutexUnlock(osa_mutex_handle_t mutexHandle)748 osa_status_t OSA_MutexUnlock(osa_mutex_handle_t mutexHandle)
749 {
750     assert(NULL != mutexHandle);
751     QueueHandle_t mutex = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)mutexHandle);
752 
753     if (((BaseType_t)0) == (BaseType_t)xSemaphoreGiveRecursive(mutex))
754     {
755         return KOSA_StatusError;
756     }
757     else
758     {
759         return KOSA_StatusSuccess;
760     }
761 }
762 
763 /*FUNCTION**********************************************************************
764  *
765  * Function Name : OSA_MutexDestroy
766  * Description   : This function is used to destroy a mutex.
767  * Return        : KOSA_StatusSuccess if the lock object is destroyed successfully, otherwise return KOSA_StatusError.
768  *
769  *END**************************************************************************/
OSA_MutexDestroy(osa_mutex_handle_t mutexHandle)770 osa_status_t OSA_MutexDestroy(osa_mutex_handle_t mutexHandle)
771 {
772     assert(NULL != mutexHandle);
773     QueueHandle_t mutex = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)mutexHandle);
774 
775     vSemaphoreDelete(mutex);
776     return KOSA_StatusSuccess;
777 }
778 
779 /*FUNCTION**********************************************************************
780  *
781  * Function Name : OSA_EventPrecreate
782  * Description   : This function is used to pre-create a event.
783  * Return         : KOSA_StatusSuccess
784  *
785  *END**************************************************************************/
786 
OSA_EventPrecreate(osa_event_handle_t eventHandle,osa_task_ptr_t taskHandler)787 osa_status_t OSA_EventPrecreate(osa_event_handle_t eventHandle, osa_task_ptr_t taskHandler)
788 {
789     eventHandle = eventHandle;
790     taskHandler = taskHandler;
791     return KOSA_StatusSuccess;
792 }
793 
794 /*FUNCTION**********************************************************************
795  *
796  * Function Name : OSA_EventCreate
797  * Description   : This function is used to create a event object.
798  * Return        : Event handle of the new event, or NULL if failed.
799  *
800  *END**************************************************************************/
OSA_EventCreate(osa_event_handle_t eventHandle,uint8_t autoClear)801 osa_status_t OSA_EventCreate(osa_event_handle_t eventHandle, uint8_t autoClear)
802 {
803     assert(NULL != eventHandle);
804 #if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
805     !((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
806     assert((sizeof(osa_event_struct_t) + sizeof(StaticEventGroup_t)) <= OSA_EVENT_HANDLE_SIZE);
807 #else
808     assert(sizeof(osa_event_struct_t) == OSA_EVENT_HANDLE_SIZE);
809 #endif
810     osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
811 
812 #if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
813     !((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
814     pEventStruct->eventHandle = xEventGroupCreateStatic((StaticEventGroup_t *)(void *)((uint8_t *)(eventHandle) + sizeof(osa_event_struct_t)));
815 #else
816     pEventStruct->eventHandle = xEventGroupCreate();
817 #endif
818     if (NULL != pEventStruct->eventHandle)
819     {
820         pEventStruct->autoClear = autoClear;
821     }
822     else
823     {
824         return KOSA_StatusError;
825     }
826     return KOSA_StatusSuccess;
827 }
828 
829 /*FUNCTION**********************************************************************
830  *
831  * Function Name : OSA_EventSet
832  * Description   : Set one or more event flags of an event object.
833  * Return        : KOSA_StatusSuccess if set successfully, KOSA_StatusError if failed.
834  *
835  *END**************************************************************************/
OSA_EventSet(osa_event_handle_t eventHandle,osa_event_flags_t flagsToSet)836 osa_status_t OSA_EventSet(osa_event_handle_t eventHandle, osa_event_flags_t flagsToSet)
837 {
838     portBASE_TYPE taskToWake = (portBASE_TYPE)pdFALSE;
839     BaseType_t result;
840     assert(NULL != eventHandle);
841     osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
842 
843     if (NULL == pEventStruct->eventHandle)
844     {
845         return KOSA_StatusError;
846     }
847     if (0U != __get_IPSR())
848     {
849 #if (configUSE_TRACE_FACILITY == 1)
850         result = xEventGroupSetBitsFromISR(pEventStruct->eventHandle, (event_flags_t)flagsToSet, &taskToWake);
851 #else
852         result = xEventGroupSetBitsFromISR((void *)pEventStruct->eventHandle, (event_flags_t)flagsToSet, &taskToWake);
853 #endif
854         assert(pdPASS == result);
855         (void)result;
856         portYIELD_FROM_ISR(((bool)(taskToWake)));
857     }
858     else
859     {
860         (void)xEventGroupSetBits(pEventStruct->eventHandle, (event_flags_t)flagsToSet);
861     }
862 
863     (void)result;
864     return KOSA_StatusSuccess;
865 }
866 
867 /*FUNCTION**********************************************************************
868  *
869  * Function Name : OSA_EventClear
870  * Description   : Clear one or more event flags of an event object.
871  * Return        :KOSA_StatusSuccess if clear successfully, KOSA_StatusError if failed.
872  *
873  *END**************************************************************************/
OSA_EventClear(osa_event_handle_t eventHandle,osa_event_flags_t flagsToClear)874 osa_status_t OSA_EventClear(osa_event_handle_t eventHandle, osa_event_flags_t flagsToClear)
875 {
876     assert(NULL != eventHandle);
877     osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
878 
879     if (NULL == pEventStruct->eventHandle)
880     {
881         return KOSA_StatusError;
882     }
883 
884     if (0U != __get_IPSR())
885     {
886 #if (configUSE_TRACE_FACILITY == 1)
887         (void)xEventGroupClearBitsFromISR(pEventStruct->eventHandle, (event_flags_t)flagsToClear);
888 #else
889         (void)xEventGroupClearBitsFromISR((void *)pEventStruct->eventHandle, (event_flags_t)flagsToClear);
890 #endif
891     }
892     else
893     {
894         (void)xEventGroupClearBits(pEventStruct->eventHandle, (event_flags_t)flagsToClear);
895     }
896     return KOSA_StatusSuccess;
897 }
898 
899 /*FUNCTION**********************************************************************
900  *
901  * Function Name : OSA_EventGet
902  * Description   : This function is used to get event's flags that specified by prameter
903  * flagsMask, and the flags (user specified) are obatianed by parameter pFlagsOfEvent. So
904  * you should pass the parameter 0xffffffff to specify you want to check all.
905  * Return        :KOSA_StatusSuccess if event flags were successfully got, KOSA_StatusError if failed.
906  *
907  *END**************************************************************************/
OSA_EventGet(osa_event_handle_t eventHandle,osa_event_flags_t flagsMask,osa_event_flags_t * pFlagsOfEvent)908 osa_status_t OSA_EventGet(osa_event_handle_t eventHandle, osa_event_flags_t flagsMask, osa_event_flags_t *pFlagsOfEvent)
909 {
910     assert(NULL != eventHandle);
911     osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
912     EventBits_t eventFlags;
913 
914     if (NULL == pEventStruct->eventHandle)
915     {
916         return KOSA_StatusError;
917     }
918 
919     if (NULL == pFlagsOfEvent)
920     {
921         return KOSA_StatusError;
922     }
923 
924     if (0U != __get_IPSR())
925     {
926         eventFlags = xEventGroupGetBitsFromISR(pEventStruct->eventHandle);
927     }
928     else
929     {
930         eventFlags = xEventGroupGetBits(pEventStruct->eventHandle);
931     }
932 
933     *pFlagsOfEvent = (osa_event_flags_t)eventFlags & flagsMask;
934 
935     return KOSA_StatusSuccess;
936 }
937 
938 /*FUNCTION**********************************************************************
939  *
940  * Function Name : OSA_EventWait
941  * Description   : This function checks the event's status, if it meets the wait
942  * condition, return KOSA_StatusSuccess, otherwise, timeout will be used for
943  * wait. The parameter timeout indicates how long should wait in milliseconds.
944  * Pass osaWaitForever_c to wait indefinitely, pass 0 will return the value
945  * KOSA_StatusTimeout immediately if wait condition is not met. The event flags
946  * will be cleared if the event is auto clear mode. Flags that wakeup waiting
947  * task could be obtained from the parameter setFlags.
948  * This function returns KOSA_StatusSuccess if wait condition is met, returns
949  * KOSA_StatusTimeout if wait condition is not met within the specified
950  * 'timeout', returns KOSA_StatusError if any errors occur during waiting.
951  *
952  *END**************************************************************************/
OSA_EventWait(osa_event_handle_t eventHandle,osa_event_flags_t flagsToWait,uint8_t waitAll,uint32_t millisec,osa_event_flags_t * pSetFlags)953 osa_status_t OSA_EventWait(osa_event_handle_t eventHandle,
954                            osa_event_flags_t flagsToWait,
955                            uint8_t waitAll,
956                            uint32_t millisec,
957                            osa_event_flags_t *pSetFlags)
958 {
959     assert(NULL != eventHandle);
960     BaseType_t clearMode;
961     uint32_t timeoutTicks;
962     event_flags_t flagsSave;
963     osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
964 
965     /* Clean FreeRTOS cotrol flags */
966     flagsToWait = flagsToWait & 0x00FFFFFFU;
967     if (NULL == pEventStruct->eventHandle)
968     {
969         return KOSA_StatusError;
970     }
971 
972     /* Convert timeout from millisecond to tick. */
973     if (millisec == osaWaitForever_c)
974     {
975         timeoutTicks = portMAX_DELAY;
976     }
977     else
978     {
979         timeoutTicks = millisec / portTICK_PERIOD_MS;
980     }
981 
982     clearMode = (pEventStruct->autoClear != 0U) ? pdTRUE : pdFALSE;
983 
984     flagsSave = xEventGroupWaitBits(pEventStruct->eventHandle, (event_flags_t)flagsToWait, clearMode, (BaseType_t)waitAll,
985                                     timeoutTicks);
986 
987     flagsSave &= (event_flags_t)flagsToWait;
988     if (NULL != pSetFlags)
989     {
990         *pSetFlags = (osa_event_flags_t)flagsSave;
991     }
992 
993     if (0U != flagsSave)
994     {
995         return KOSA_StatusSuccess;
996     }
997     else
998     {
999         return KOSA_StatusTimeout;
1000     }
1001 }
1002 
1003 /*FUNCTION**********************************************************************
1004  *
1005  * Function Name : OSA_EventDestroy
1006  * Description   : This function is used to destroy a event object. Return
1007  * KOSA_StatusSuccess if the event object is destroyed successfully, otherwise
1008  * return KOSA_StatusError.
1009  *
1010  *END**************************************************************************/
OSA_EventDestroy(osa_event_handle_t eventHandle)1011 osa_status_t OSA_EventDestroy(osa_event_handle_t eventHandle)
1012 {
1013     assert(NULL != eventHandle);
1014     osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
1015 
1016     if (NULL == pEventStruct->eventHandle)
1017     {
1018         return KOSA_StatusError;
1019     }
1020     vEventGroupDelete(pEventStruct->eventHandle);
1021     return KOSA_StatusSuccess;
1022 }
1023 
1024 /*FUNCTION**********************************************************************
1025  *
1026  * Function Name : OSA_MsgQCreate
1027  * Description   : This function is used to create a message queue.
1028  * Return        : the handle to the message queue if create successfully, otherwise
1029  * return NULL.
1030  *
1031  *END**************************************************************************/
OSA_MsgQCreate(osa_msgq_handle_t msgqHandle,uint32_t msgNo,uint32_t msgSize)1032 osa_status_t OSA_MsgQCreate(osa_msgq_handle_t msgqHandle, uint32_t msgNo, uint32_t msgSize)
1033 {
1034 #if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
1035     !((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
1036     assert((sizeof(osa_msgq_handle_t) + sizeof(StaticQueue_t)) == OSA_MSGQ_HANDLE_SIZE);
1037 #else
1038     assert(sizeof(osa_msgq_handle_t) == OSA_MSGQ_HANDLE_SIZE);
1039 #endif
1040     assert(NULL != msgqHandle);
1041 
1042     union
1043     {
1044         QueueHandle_t msgq;
1045         uint32_t pmsgqHandle;
1046     } xMsgqHandle;
1047 
1048     /* Create the message queue where the number and size is specified by msgNo and msgSize */
1049 #if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
1050     !((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
1051     xMsgqHandle.msgq = xQueueCreateStatic(msgNo, msgSize,
1052                                           (uint8_t *)((uint8_t *)msgqHandle + sizeof(osa_msgq_handle_t) + sizeof(StaticQueue_t)),
1053                                           (StaticQueue_t *)(void *)((uint8_t *)msgqHandle + sizeof(osa_msgq_handle_t)));
1054 #else
1055     xMsgqHandle.msgq = xQueueCreate(msgNo, msgSize);
1056 #endif
1057     if (NULL != xMsgqHandle.msgq)
1058     {
1059         *(uint32_t *)msgqHandle = xMsgqHandle.pmsgqHandle;
1060         return KOSA_StatusSuccess;
1061     }
1062     return KOSA_StatusError;
1063 }
1064 
1065 /*FUNCTION**********************************************************************
1066  *
1067  * Function Name : OSA_MsgQPut
1068  * Description   : This function is used to put a message to a message queue.
1069  * Return         : KOSA_StatusSuccess if the message is put successfully, otherwise return KOSA_StatusError.
1070  *
1071  *END**************************************************************************/
OSA_MsgQPut(osa_msgq_handle_t msgqHandle,osa_msg_handle_t pMessage)1072 osa_status_t OSA_MsgQPut(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage)
1073 {
1074     osa_status_t osaStatus;
1075     assert(NULL != msgqHandle);
1076     portBASE_TYPE taskToWake = (portBASE_TYPE)pdFALSE;
1077     QueueHandle_t handler    = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)msgqHandle);
1078 
1079     if (0U != __get_IPSR())
1080     {
1081         if (((BaseType_t)1) == (BaseType_t)xQueueSendToBackFromISR(handler, pMessage, &taskToWake))
1082         {
1083             portYIELD_FROM_ISR(((bool)(taskToWake)));
1084             osaStatus = KOSA_StatusSuccess;
1085         }
1086         else
1087         {
1088             osaStatus = KOSA_StatusError;
1089         }
1090     }
1091     else
1092     {
1093         osaStatus = (xQueueSendToBack(handler, pMessage, 0) == pdPASS) ? (KOSA_StatusSuccess) : (KOSA_StatusError);
1094     }
1095 
1096     return osaStatus;
1097 }
1098 
1099 /*FUNCTION**********************************************************************
1100  *
1101  * Function Name : OSA_MsgQGet
1102  * Description   : This function checks the queue's status, if it is not empty,
1103  * get message from it and return KOSA_StatusSuccess, otherwise, timeout will
1104  * be used for wait. The parameter timeout indicates how long should wait in
1105  * milliseconds. Pass osaWaitForever_c to wait indefinitely, pass 0 will return
1106  * KOSA_StatusTimeout immediately if queue is empty.
1107  * This function returns KOSA_StatusSuccess if message is got successfully,
1108  * returns KOSA_StatusTimeout if message queue is empty within the specified
1109  * 'timeout', returns KOSA_StatusError if any errors occur during waiting.
1110  *
1111  *END**************************************************************************/
OSA_MsgQGet(osa_msgq_handle_t msgqHandle,osa_msg_handle_t pMessage,uint32_t millisec)1112 osa_status_t OSA_MsgQGet(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage, uint32_t millisec)
1113 {
1114     osa_status_t osaStatus;
1115     assert(NULL != msgqHandle);
1116     QueueHandle_t handler = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)msgqHandle);
1117 
1118     uint32_t timeoutTicks;
1119 
1120     if (millisec == osaWaitForever_c)
1121     {
1122         timeoutTicks = portMAX_DELAY;
1123     }
1124     else
1125     {
1126         timeoutTicks = MSEC_TO_TICK(millisec);
1127     }
1128     if (pdPASS != xQueueReceive(handler, pMessage, timeoutTicks))
1129     {
1130         osaStatus = KOSA_StatusTimeout; /* not able to send it to the queue? */
1131     }
1132     else
1133     {
1134         osaStatus = KOSA_StatusSuccess;
1135     }
1136     return osaStatus;
1137 }
1138 
1139 /*FUNCTION**********************************************************************
1140  *
1141  * Function Name : OSA_MsgQAvailableMsgs
1142  * Description   : This function is used to get the available message.
1143  * Return        : Available message count
1144  *
1145  *END**************************************************************************/
OSA_MsgQAvailableMsgs(osa_msgq_handle_t msgqHandle)1146 int OSA_MsgQAvailableMsgs(osa_msgq_handle_t msgqHandle)
1147 {
1148     QueueHandle_t handler;
1149     assert(NULL != msgqHandle);
1150     handler = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)msgqHandle);
1151     return (int)uxQueueMessagesWaiting((QueueHandle_t)handler);
1152 }
1153 
1154 /*FUNCTION**********************************************************************
1155  *
1156  * Function Name : OSA_MsgQDestroy
1157  * Description   : This function is used to destroy the message queue.
1158  * Return        : KOSA_StatusSuccess if the message queue is destroyed successfully, otherwise return KOSA_StatusError.
1159  *
1160  *END**************************************************************************/
OSA_MsgQDestroy(osa_msgq_handle_t msgqHandle)1161 osa_status_t OSA_MsgQDestroy(osa_msgq_handle_t msgqHandle)
1162 {
1163     assert(NULL != msgqHandle);
1164     QueueHandle_t handler = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)msgqHandle);
1165 
1166     vQueueDelete(handler);
1167     return KOSA_StatusSuccess;
1168 }
1169 
1170 /*FUNCTION**********************************************************************
1171  *
1172  * Function Name : OSA_InterruptEnable
1173  * Description   : self explanatory.
1174  *
1175  *END**************************************************************************/
OSA_InterruptEnable(void)1176 void OSA_InterruptEnable(void)
1177 {
1178     if (0U != __get_IPSR())
1179     {
1180         if (1 == s_osaState.basePriorityNesting)
1181         {
1182             portCLEAR_INTERRUPT_MASK_FROM_ISR(s_osaState.basePriority);
1183         }
1184 
1185         if (s_osaState.basePriorityNesting > 0)
1186         {
1187             s_osaState.basePriorityNesting--;
1188         }
1189     }
1190     else
1191     {
1192         portEXIT_CRITICAL();
1193     }
1194 }
1195 
1196 /*FUNCTION**********************************************************************
1197  *
1198  * Function Name : OSA_InterruptDisable
1199  * Description   : self explanatory.
1200  *
1201  *END**************************************************************************/
OSA_InterruptDisable(void)1202 void OSA_InterruptDisable(void)
1203 {
1204     if (0U != __get_IPSR())
1205     {
1206         if (0 == s_osaState.basePriorityNesting)
1207         {
1208             s_osaState.basePriority = portSET_INTERRUPT_MASK_FROM_ISR();
1209         }
1210         s_osaState.basePriorityNesting++;
1211     }
1212     else
1213     {
1214         portENTER_CRITICAL();
1215     }
1216 }
1217 
1218 /*FUNCTION**********************************************************************
1219  *
1220  * Function Name : OSA_EnableIRQGlobal
1221  * Description   : enable interrupts using PRIMASK register.
1222  *
1223  *END**************************************************************************/
OSA_EnableIRQGlobal(void)1224 void OSA_EnableIRQGlobal(void)
1225 {
1226     if (s_osaState.interruptDisableCount > 0U)
1227     {
1228         s_osaState.interruptDisableCount--;
1229 
1230         if (0U == s_osaState.interruptDisableCount)
1231         {
1232             __enable_irq();
1233         }
1234         /* call core API to enable the global interrupt*/
1235     }
1236 }
1237 
1238 /*FUNCTION**********************************************************************
1239  *
1240  * Function Name : OSA_DisableIRQGlobal
1241  * Description   : disable interrupts using PRIMASK register.
1242  *
1243  *END**************************************************************************/
OSA_DisableIRQGlobal(void)1244 void OSA_DisableIRQGlobal(void)
1245 {
1246     /* call core API to disable the global interrupt*/
1247     __disable_irq();
1248 
1249     /* update counter*/
1250     s_osaState.interruptDisableCount++;
1251 }
1252 
1253 /*FUNCTION**********************************************************************
1254  *
1255  * Function Name : OSA_DisableScheduler
1256  * Description   : Disable the scheduling of any task
1257  * This function will disable the scheduling of any task
1258  *
1259  *END**************************************************************************/
OSA_DisableScheduler(void)1260 void OSA_DisableScheduler(void)
1261 {
1262     vTaskSuspendAll();
1263 }
1264 
1265 /*FUNCTION**********************************************************************
1266  *
1267  * Function Name : OSA_EnableScheduler
1268  * Description   : Enable the scheduling of any task
1269  * This function will enable the scheduling of any task
1270  *
1271  *END**************************************************************************/
OSA_EnableScheduler(void)1272 void OSA_EnableScheduler(void)
1273 {
1274     (void)xTaskResumeAll();
1275 }
1276 
1277 /*FUNCTION**********************************************************************
1278  *
1279  * Function Name : OSA_InstallIntHandler
1280  * Description   : This function is used to install interrupt handler.
1281  *
1282  *END**************************************************************************/
OSA_InstallIntHandler(uint32_t IRQNumber,void (* handler)(void))1283 void OSA_InstallIntHandler(uint32_t IRQNumber, void (*handler)(void))
1284 {
1285 #if defined(__IAR_SYSTEMS_ICC__)
1286     _Pragma("diag_suppress = Pm138")
1287 #endif
1288 #if defined(ENABLE_RAM_VECTOR_TABLE)
1289         (void) InstallIRQHandler((IRQn_Type)IRQNumber, (uint32_t)handler);
1290 #endif /* ENABLE_RAM_VECTOR_TABLE. */
1291 #if defined(__IAR_SYSTEMS_ICC__)
1292     _Pragma("diag_remark = PM138")
1293 #endif
1294 }
1295 
1296 /*!*********************************************************************************
1297 *************************************************************************************
1298 * Private functions
1299 *************************************************************************************
1300 ********************************************************************************** */
1301 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
1302 #if (defined(FSL_OSA_MAIN_FUNC_ENABLE) && (FSL_OSA_MAIN_FUNC_ENABLE > 0U))
1303 static OSA_TASK_DEFINE(startup_task, gMainThreadPriority_c, 1, gMainThreadStackSize_c, 0);
1304 
main(void)1305 int main(void)
1306 {
1307     extern void BOARD_InitHardware(void);
1308     OSA_Init();
1309     /* Initialize MCU clock */
1310     BOARD_InitHardware();
1311 
1312     (void)OSA_TaskCreate((osa_task_handle_t)s_osaState.mainTaskHandle, OSA_TASK(startup_task), NULL);
1313 
1314     OSA_Start();
1315     return 0;
1316 }
1317 #endif /*(defined(FSL_OSA_MAIN_FUNC_ENABLE) && (FSL_OSA_MAIN_FUNC_ENABLE > 0U))*/
1318 #endif /* FSL_OSA_TASK_ENABLE */
1319 
1320 /*FUNCTION**********************************************************************
1321  *
1322  * Function Name : OSA_Init
1323  * Description   : This function is used to setup the basic services, it should
1324  * be called first in function main.
1325  *
1326  *END**************************************************************************/
1327 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_Init(void)1328 void OSA_Init(void)
1329 {
1330     LIST_Init((&s_osaState.taskList), 0);
1331     s_osaState.basePriorityNesting   = 0;
1332     s_osaState.interruptDisableCount = 0;
1333 }
1334 #endif
1335 
1336 /*FUNCTION**********************************************************************
1337  *
1338  * Function Name : OSA_Start
1339  * Description   : This function is used to start RTOS scheduler.
1340  *
1341  *END**************************************************************************/
1342 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_Start(void)1343 void OSA_Start(void)
1344 {
1345     vTaskStartScheduler();
1346 }
1347 #endif
1348 
1349 /**
1350  * Warning: Needs to be implemented
1351  */
1352 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskNotifyGet(osa_notify_time_ms_t waitTime_ms)1353 osa_status_t OSA_TaskNotifyGet(osa_notify_time_ms_t waitTime_ms)
1354 {
1355     return KOSA_StatusError;
1356 }
1357 #endif
1358 
1359 /**
1360  * Warning: Needs to be implemented
1361  */
1362 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskNotifyPost(osa_task_handle_t taskHandle)1363 osa_status_t OSA_TaskNotifyPost(osa_task_handle_t taskHandle)
1364 {
1365     return KOSA_StatusError;
1366 }
1367 #endif
1368 
1369 /**
1370  * Warning: Needs to be implemented
1371  */
OSA_SemaphoreGetCount(osa_semaphore_handle_t semaphoreHandle)1372 osa_semaphore_count_t OSA_SemaphoreGetCount(osa_semaphore_handle_t semaphoreHandle)
1373 {
1374     assert(false);
1375 
1376     return 0;
1377 }