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 }