1 /*!
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2019,2022 NXP
4 *
5 *
6 * This is the source file for the OS Abstraction layer for MQXLite.
7 *
8 * SPDX-License-Identifier: BSD-3-Clause
9 */
10
11 /*! *********************************************************************************
12 *************************************************************************************
13 * Include
14 *************************************************************************************
15 ********************************************************************************** */
16 #include "fsl_component_generic_list.h"
17 #include "fsl_os_abstraction.h"
18 #include "fsl_os_abstraction_bm.h"
19 #include <string.h>
20
21 /*! *********************************************************************************
22 *************************************************************************************
23 * Private macros
24 *************************************************************************************
25 ********************************************************************************** */
26
27 /* Weak function. */
28 #if defined(__GNUC__)
29 #define __WEAK_FUNC __attribute__((weak))
30 #elif defined(__ICCARM__)
31 #define __WEAK_FUNC __weak
32 #elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
33 #define __WEAK_FUNC __attribute__((weak))
34 #elif defined(__DSC__) || defined(__CW__)
35 #define __WEAK_FUNC __attribute__((weak))
36 #endif
37
38 #ifdef DEBUG_ASSERT
39 #define OS_ASSERT(condition) \
40 if (!(condition)) \
41 while (1) \
42 ;
43 #else
44 #define OS_ASSERT(condition) (void)(condition);
45 #endif
46
47 /************************************************************************************
48 *************************************************************************************
49 * Private type definitions
50 *************************************************************************************
51 ************************************************************************************/
52 /*! @brief Type for a task handler, returned by the OSA_TaskCreate function */
53 typedef void (*task_t)(task_param_t param);
54 /*! @brief Task control block for bare metal. */
55 typedef struct TaskControlBlock
56 {
57 list_element_t link;
58 osa_task_ptr_t p_func; /*!< Task's entry */
59 osa_task_priority_t priority; /*!< Task's priority */
60 osa_task_param_t param; /*!< Task's parameter */
61 uint8_t haveToRun; /*!< Task was signaled */
62 } task_control_block_t;
63
64 /*! @brief Type for a task pointer */
65 typedef task_control_block_t *task_handler_t;
66
67 /*! @brief Type for a task stack */
68 typedef uint32_t task_stack_t;
69
70 /*! @brief Type for a semaphore */
71 typedef enum semaphore_type
72 {
73 KOSA_CountingSemaphore = 0U, /*!< counting semaphore */
74 KOSA_BinarySemaphore = 1U, /*!< binary semaphore */
75 } semaphore_type_t;
76
77 /*! @brief Type for an semaphore */
78 typedef struct Semaphore
79 {
80 #if (defined(FSL_OSA_BM_TIMEOUT_ENABLE) && (FSL_OSA_BM_TIMEOUT_ENABLE > 0U))
81 uint32_t time_start; /*!< The time to start timeout */
82 uint32_t timeout; /*!< Timeout to wait in milliseconds */
83 #endif
84 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
85 task_handler_t waitingTask; /*!< Handler to the waiting task */
86 #endif
87 volatile uint8_t isWaiting; /*!< Is any task waiting for a timeout on this object */
88 volatile uint8_t semCount; /*!< The count value of the object */
89 semaphore_type_t semaphoreType; /*!< The type of the semaphore */
90 } semaphore_t;
91
92 /*! @brief Type for a mutex */
93 typedef struct Mutex
94 {
95 #if (defined(FSL_OSA_BM_TIMEOUT_ENABLE) && (FSL_OSA_BM_TIMEOUT_ENABLE > 0U))
96 uint32_t time_start; /*!< The time to start timeout */
97 uint32_t timeout; /*!< Timeout to wait in milliseconds */
98 #endif
99 volatile uint8_t isWaiting; /*!< Is any task waiting for a timeout on this mutex */
100 volatile uint8_t isLocked; /*!< Is the object locked or not */
101 } mutex_t;
102
103 #define gIdleTaskPriority_c ((task_priority_t)0)
104 #define gInvalidTaskPriority_c ((task_priority_t)-1)
105 /*! @brief Type for an event object */
106 typedef struct Event
107 {
108 uint32_t time_start; /*!< The time to start timeout */
109 uint32_t timeout; /*!< Timeout to wait in milliseconds */
110 volatile event_flags_t flags; /*!< The flags status */
111 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
112 task_handler_t waitingTask; /*!< Handler to the waiting task */
113 #endif
114 uint8_t autoClear; /*!< Auto clear or manual clear */
115 volatile uint8_t isWaiting; /*!< Is any task waiting for a timeout on this event */
116 } event_t;
117
118 /*! @brief Type for a message queue */
119 typedef struct MsgQueue
120 {
121 volatile uint8_t isWaiting; /*!< Is any task waiting for a timeout */
122 uint32_t time_start; /*!< The time to start timeout */
123 uint32_t timeout; /*!< Timeout to wait in milliseconds */
124 uint32_t size; /*!< The size(byte) of a single message */
125 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
126 task_handler_t waitingTask; /*!< Handler to the waiting task */
127 #endif
128 uint8_t *queueMem; /*!< Points to the queue memory */
129 uint16_t number; /*!< The number of messages in the queue */
130 uint16_t max; /*!< The max number of queue messages */
131 uint16_t head; /*!< Index of the next message to be read */
132 uint16_t tail; /*!< Index of the next place to write to */
133 } msg_queue_t;
134
135 /*! @brief Type for a message queue handler */
136 typedef msg_queue_t *msg_queue_handler_t;
137
138 /*! @brief State structure for bm osa manager. */
139 typedef struct _osa_state
140 {
141 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
142 list_label_t taskList;
143 task_handler_t curTaskHandler;
144 #endif
145 volatile uint32_t interruptDisableCount;
146 volatile uint32_t interruptRegPrimask;
147 volatile uint32_t tickCounter;
148 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
149 #if (defined(FSL_OSA_MAIN_FUNC_ENABLE) && (FSL_OSA_MAIN_FUNC_ENABLE > 0U))
150 OSA_TASK_HANDLE_DEFINE(mainTaskHandle);
151 #endif
152 #endif
153 } osa_state_t;
154
155 /*! *********************************************************************************
156 *************************************************************************************
157 * Private prototypes
158 *************************************************************************************
159 ********************************************************************************** */
160 __WEAK_FUNC void main_task(osa_task_param_t arg);
main_task(osa_task_param_t arg)161 __WEAK_FUNC void main_task(osa_task_param_t arg)
162 {
163 }
164 __WEAK_FUNC void OSA_TimeInit(void);
165 __WEAK_FUNC uint32_t OSA_TimeDiff(uint32_t time_start, uint32_t time_end);
166
167 /*! *********************************************************************************
168 *************************************************************************************
169 * Public memory declarations
170 *************************************************************************************
171 ********************************************************************************** */
172 const uint8_t gUseRtos_c = USE_RTOS; /* USE_RTOS = 0 for BareMetal and 1 for OS */
173
174 /*! *********************************************************************************
175 *************************************************************************************
176 * Private memory declarations
177 *************************************************************************************
178 ********************************************************************************** */
179 static osa_state_t s_osaState;
180
181 /*! *********************************************************************************
182 *************************************************************************************
183 * Public functions
184 *************************************************************************************
185 ********************************************************************************** */
186 /*FUNCTION**********************************************************************
187 *
188 * Function Name : OSA_MemoryAllocate
189 * Description : Reserves the requested amount of memory in bytes.
190 *
191 *END**************************************************************************/
OSA_MemoryAllocate(uint32_t length)192 void *OSA_MemoryAllocate(uint32_t length)
193 {
194 void *p = (void *)malloc(length);
195
196 if (NULL != p)
197 {
198 (void)memset(p, 0, length);
199 }
200
201 return p;
202 }
203
204 /*FUNCTION**********************************************************************
205 *
206 * Function Name : OSA_MemoryFree
207 * Description : Frees the memory previously reserved.
208 *
209 *END**************************************************************************/
OSA_MemoryFree(void * p)210 void OSA_MemoryFree(void *p)
211 {
212 free(p);
213 }
214
OSA_EnterCritical(uint32_t * sr)215 void OSA_EnterCritical(uint32_t *sr)
216 {
217 *sr = DisableGlobalIRQ();
218 }
219
OSA_ExitCritical(uint32_t sr)220 void OSA_ExitCritical(uint32_t sr)
221 {
222 EnableGlobalIRQ(sr);
223 }
224
225 /*FUNCTION**********************************************************************
226 *
227 * Function Name : OSA_EnableIRQGlobal
228 * Description : Disable system interrupt.
229 *
230 *END**************************************************************************/
OSA_EnableIRQGlobal(void)231 void OSA_EnableIRQGlobal(void)
232 {
233 if (s_osaState.interruptDisableCount > 0U)
234 {
235 s_osaState.interruptDisableCount--;
236
237 if (0U == s_osaState.interruptDisableCount)
238 {
239 EnableGlobalIRQ(s_osaState.interruptRegPrimask);
240 }
241 /* call core API to enable the global interrupt*/
242 }
243 }
244
245 /*FUNCTION**********************************************************************
246 *
247 * Function Name : OSA_DisableIRQGlobal
248 * Description : Disable system interrupt
249 * This function will disable the global interrupt by calling the core API
250 *
251 *END**************************************************************************/
OSA_DisableIRQGlobal(void)252 void OSA_DisableIRQGlobal(void)
253 {
254 /* call API to disable the global interrupt*/
255 if (0U == s_osaState.interruptDisableCount)
256 {
257 s_osaState.interruptRegPrimask = DisableGlobalIRQ();
258 }
259
260 /* update counter*/
261 s_osaState.interruptDisableCount++;
262 }
263
264 /*FUNCTION**********************************************************************
265 *
266 * Function Name : OSA_TaskGetCurrentHandle
267 * Description : This function is used to get current active task's handler.
268 *
269 *END**************************************************************************/
270 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskGetCurrentHandle(void)271 osa_task_handle_t OSA_TaskGetCurrentHandle(void)
272 {
273 return (osa_task_handle_t)s_osaState.curTaskHandler;
274 }
275 #endif
276 /*FUNCTION**********************************************************************
277 *
278 * Function Name : OSA_EXT_TaskYield
279 * Description : When a task calls this function, it will give up CPU and put
280 * itself to the tail of ready list.
281 *
282 *END**************************************************************************/
283 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskYield(void)284 void OSA_TaskYield(void)
285 {
286 }
287 #endif
288 /*FUNCTION**********************************************************************
289 *
290 * Function Name : OSA_TaskGetPriority
291 * Description : This function returns task's priority by task handler.
292 *
293 *END**************************************************************************/
294 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskGetPriority(osa_task_handle_t taskHandle)295 osa_task_priority_t OSA_TaskGetPriority(osa_task_handle_t taskHandle)
296 {
297 assert(taskHandle);
298 task_handler_t handler = (task_handler_t)taskHandle;
299 return handler->priority;
300 }
301 #endif
302
303 /*FUNCTION**********************************************************************
304 *
305 * Function Name : OSA_TaskSetPriority
306 * Description : This function sets task's priority by task handler.
307 *
308 *END**************************************************************************/
309 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskSetPriority(osa_task_handle_t taskHandle,osa_task_priority_t taskPriority)310 osa_status_t OSA_TaskSetPriority(osa_task_handle_t taskHandle, osa_task_priority_t taskPriority)
311 {
312 assert(taskHandle);
313 list_element_handle_t list_element;
314 task_control_block_t *tcb = NULL;
315 #if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
316 task_control_block_t *preTcb = NULL;
317 #endif
318 task_control_block_t *ptaskStruct = (task_control_block_t *)taskHandle;
319 uint32_t regPrimask;
320
321 ptaskStruct->priority = taskPriority;
322 (void)LIST_RemoveElement(&ptaskStruct->link);
323 /* Insert task control block into the task list. */
324 list_element = LIST_GetHead(&s_osaState.taskList);
325 while (NULL != list_element)
326 {
327 tcb = (task_control_block_t *)(void *)list_element;
328 if (ptaskStruct->priority <= tcb->priority)
329 {
330 #if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
331 if (preTcb == NULL)
332 {
333 (&tcb->link)->list->head = (struct list_element_tag *)(void *)ptaskStruct;
334 }
335 else
336 {
337 (&preTcb->link)->next = (struct list_element_tag *)(void *)ptaskStruct;
338 }
339 (&ptaskStruct->link)->list = (&tcb->link)->list;
340 (&ptaskStruct->link)->next = (struct list_element_tag *)(void *)tcb;
341 (&ptaskStruct->link)->list->size++;
342 #else
343 (void)LIST_AddPrevElement(&tcb->link, &ptaskStruct->link);
344 #endif
345 break;
346 }
347 #if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
348 preTcb = tcb;
349 #endif
350 list_element = LIST_GetNext(list_element);
351 }
352 if (ptaskStruct->priority > tcb->priority)
353 {
354 OSA_EnterCritical(®Primask);
355 (void)LIST_AddTail(&s_osaState.taskList, (list_element_handle_t)(void *)&(ptaskStruct->link));
356 OSA_ExitCritical(regPrimask);
357 }
358
359 return KOSA_StatusSuccess;
360 }
361 #endif
362
363 /*FUNCTION**********************************************************************
364 *
365 * Function Name : OSA_TaskCreate
366 * Description : This function is used to create a task and make it ready.
367 * Param[in] : threadDef - Definition of the thread.
368 * task_param - Parameter to pass to the new thread.
369 * Return Thread handle of the new thread, or NULL if failed.
370 *
371 *END**************************************************************************/
372 #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)373 osa_status_t OSA_TaskCreate(osa_task_handle_t taskHandle, const osa_task_def_t *thread_def, osa_task_param_t task_param)
374 {
375 list_element_handle_t list_element;
376
377 task_control_block_t *tcb = NULL;
378 #if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
379 task_control_block_t *preTcb = NULL;
380 #endif
381 list_status_t listStatus;
382
383 task_control_block_t *ptaskStruct = (task_control_block_t *)taskHandle;
384 uint32_t regPrimask;
385 assert(sizeof(task_control_block_t) == OSA_TASK_HANDLE_SIZE);
386 assert(taskHandle);
387
388 ptaskStruct->p_func = thread_def->pthread;
389 ptaskStruct->haveToRun = 1U;
390 ptaskStruct->priority = (uint16_t)PRIORITY_OSA_TO_RTOS(thread_def->tpriority);
391 ptaskStruct->param = task_param;
392
393 list_element = LIST_GetHead(&s_osaState.taskList);
394 while (NULL != list_element)
395 {
396 tcb = (task_control_block_t *)(void *)list_element;
397 if (ptaskStruct->priority <= tcb->priority)
398 {
399 OSA_EnterCritical(®Primask);
400 #if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
401 if (preTcb == NULL)
402 {
403 (&tcb->link)->list->head = (struct list_element_tag *)(void *)ptaskStruct;
404 }
405 else
406 {
407 (&preTcb->link)->next = (struct list_element_tag *)(void *)ptaskStruct;
408 }
409 (&ptaskStruct->link)->list = (&tcb->link)->list;
410 (&ptaskStruct->link)->next = (struct list_element_tag *)(void *)tcb;
411 (&ptaskStruct->link)->list->size++;
412 OSA_ExitCritical(regPrimask);
413 return KOSA_StatusSuccess;
414 #else
415 listStatus = LIST_AddPrevElement(&tcb->link, &ptaskStruct->link);
416 OSA_ExitCritical(regPrimask);
417 if (listStatus == (list_status_t)kLIST_DuplicateError)
418 {
419 return KOSA_StatusError;
420 }
421 break;
422 #endif
423 }
424 #if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
425 preTcb = tcb;
426 #endif
427 list_element = LIST_GetNext(list_element);
428 }
429
430 if ((NULL == tcb) || (ptaskStruct->priority > tcb->priority))
431 {
432 OSA_EnterCritical(®Primask);
433 listStatus = LIST_AddTail(&s_osaState.taskList, (list_element_handle_t)(void *)&(ptaskStruct->link));
434 (void)listStatus;
435 assert(listStatus == kLIST_Ok);
436 OSA_ExitCritical(regPrimask);
437 }
438
439 return KOSA_StatusSuccess;
440 }
441 #endif
442
443 /*FUNCTION**********************************************************************
444 *
445 * Function Name : OSA_TaskDestroy
446 * Description : This function destroy a task.
447 * Param[in] :taskHandle - Thread handle.
448 * Return KOSA_StatusSuccess if the task is destroied, otherwise return KOSA_StatusError.
449 *
450 *END**************************************************************************/
451 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskDestroy(osa_task_handle_t taskHandle)452 osa_status_t OSA_TaskDestroy(osa_task_handle_t taskHandle)
453 {
454 uint32_t regPrimask;
455 assert(taskHandle);
456
457 OSA_EnterCritical(®Primask);
458 (void)LIST_RemoveElement(taskHandle);
459 OSA_ExitCritical(regPrimask);
460 return KOSA_StatusSuccess;
461 }
462 #endif
463
464 /*FUNCTION**********************************************************************
465 *
466 * Function Name : OSA_TimeInit
467 * Description : This function initializes the timer used in BM OSA, the
468 * functions such as OSA_TimeDelay, OSA_TimeGetMsec, and the timeout are all
469 * based on this timer.
470 *
471 *END**************************************************************************/
OSA_TimeInit(void)472 __WEAK_FUNC void OSA_TimeInit(void)
473 {
474 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
475 SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk);
476 SysTick->LOAD = (uint32_t)(SystemCoreClock / 1000U - 1U);
477 SysTick->VAL = 0;
478 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_CLKSOURCE_Msk;
479 #endif
480 }
481
482 /*FUNCTION**********************************************************************
483 *
484 * Function Name : OSA_TimeDiff
485 * Description : This function gets the difference between two time stamp,
486 * time overflow is considered.
487 *
488 *END**************************************************************************/
OSA_TimeDiff(uint32_t time_start,uint32_t time_end)489 __WEAK_FUNC uint32_t OSA_TimeDiff(uint32_t time_start, uint32_t time_end)
490 {
491 if (time_end >= time_start)
492 {
493 return time_end - time_start;
494 }
495 else
496 {
497 return FSL_OSA_TIME_RANGE - time_start + time_end + 1UL;
498 }
499 }
500
501 /*FUNCTION**********************************************************************
502 *
503 * Function Name : OSA__TimeDelay
504 * Description : This function is used to suspend the active thread for the given number of milliseconds.
505 *
506 *END**************************************************************************/
OSA_TimeDelay(uint32_t millisec)507 void OSA_TimeDelay(uint32_t millisec)
508 {
509 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
510 uint32_t currTime, timeStart;
511
512 timeStart = OSA_TimeGetMsec();
513
514 do
515 {
516 currTime = OSA_TimeGetMsec(); /* Get current time stamp */
517 } while (millisec >= OSA_TimeDiff(timeStart, currTime));
518 #endif
519 }
520 /*FUNCTION**********************************************************************
521 *
522 * Function Name : OSA_TimeGetMsec
523 * Description : This function gets current time in milliseconds.
524 *
525 *END**************************************************************************/
OSA_TimeGetMsec(void)526 __WEAK_FUNC uint32_t OSA_TimeGetMsec(void)
527 {
528 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
529 return s_osaState.tickCounter;
530 #else
531 return 0;
532 #endif
533 }
534
535 /*FUNCTION**********************************************************************
536 *
537 * Function Name : OSA_SemaphorePrecreate
538 * Description : This function is used to pre-create a semaphore.
539 * Return : KOSA_StatusSuccess
540 *
541 *END**************************************************************************/
542
OSA_SemaphorePrecreate(osa_semaphore_handle_t semaphoreHandle,osa_task_ptr_t taskHandler)543 osa_status_t OSA_SemaphorePrecreate(osa_semaphore_handle_t semaphoreHandle, osa_task_ptr_t taskHandler)
544 {
545 semaphoreHandle = semaphoreHandle;
546 taskHandler = taskHandler;
547 return KOSA_StatusSuccess;
548 }
549
550 /*FUNCTION**********************************************************************
551 *
552 * Function Name : OSA_SemaphoreCreate
553 * Description : This function is used to create a counting semaphore.
554 * Return : Semaphore handle of the new semaphore, or NULL if failed.
555 *
556 *END**************************************************************************/
557
OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle,uint32_t initValue)558 osa_status_t OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle, uint32_t initValue)
559 {
560 semaphore_t *pSemStruct = (semaphore_t *)semaphoreHandle;
561 assert(sizeof(semaphore_t) <= OSA_SEM_HANDLE_SIZE);
562 assert(semaphoreHandle);
563
564 pSemStruct->semCount = (uint8_t)initValue;
565 pSemStruct->isWaiting = 0U;
566 pSemStruct->semaphoreType = KOSA_CountingSemaphore;
567 #if (defined(FSL_OSA_BM_TIMEOUT_ENABLE) && (FSL_OSA_BM_TIMEOUT_ENABLE > 0U))
568 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
569
570 pSemStruct->time_start = 0U;
571 pSemStruct->timeout = 0U;
572 #endif
573 #endif
574 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
575 pSemStruct->waitingTask = NULL;
576 #endif
577 return KOSA_StatusSuccess;
578 }
579
580 /*FUNCTION**********************************************************************
581 *
582 * Function Name : OSA_SemaphoreCreateBinary
583 * Description : This function is used to create a binary semaphore.
584 * Return : Semaphore handle of the new binary semaphore, or NULL if failed.
585 *
586 *END**************************************************************************/
OSA_SemaphoreCreateBinary(osa_semaphore_handle_t semaphoreHandle)587 osa_status_t OSA_SemaphoreCreateBinary(osa_semaphore_handle_t semaphoreHandle)
588 {
589 semaphore_t *pSemStruct = (semaphore_t *)semaphoreHandle;
590 assert(sizeof(semaphore_t) <= OSA_SEM_HANDLE_SIZE);
591 assert(semaphoreHandle);
592
593 pSemStruct->semCount = 1U;
594 pSemStruct->isWaiting = 0U;
595 pSemStruct->semaphoreType = KOSA_BinarySemaphore;
596 #if (defined(FSL_OSA_BM_TIMEOUT_ENABLE) && (FSL_OSA_BM_TIMEOUT_ENABLE > 0U))
597 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
598 pSemStruct->time_start = 0U;
599 pSemStruct->timeout = 0U;
600 #endif
601 #endif
602 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
603 pSemStruct->waitingTask = NULL;
604 #endif
605 return KOSA_StatusSuccess;
606 }
607
608 /*FUNCTION**********************************************************************
609 *
610 * Function Name : OSA_SemaphoreDestroy
611 * Description : This function is used to destroy a semaphore.
612 * Return : KOSA_StatusSuccess if the semaphore is destroyed successfully, otherwise return KOSA_StatusError.
613 *
614 *END**************************************************************************/
OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle)615 osa_status_t OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle)
616 {
617 assert(semaphoreHandle);
618 semaphore_t *pSemStruct = (semaphore_t *)semaphoreHandle;
619
620 /* Destroy semaphoreHandle's data */
621 (void)memset(pSemStruct, 0, sizeof(semaphore_t));
622
623 return KOSA_StatusSuccess;
624 }
625 /*FUNCTION**********************************************************************
626 *
627 * Function Name : OSA_SemaphoreWait
628 * Description : This function checks the semaphore's counting value, if it is
629 * positive, decreases it and returns KOSA_StatusSuccess, otherwise, timeout
630 * will be used for wait. The parameter timeout indicates how long should wait
631 * in milliseconds. Pass osaWaitForever_c to wait indefinitely, pass 0 will
632 * return KOSA_StatusTimeout immediately if semaphore is not positive.
633 * This function returns KOSA_StatusSuccess if the semaphore is received, returns
634 * KOSA_StatusTimeout if the semaphore is not received within the specified
635 * 'timeout', returns KOSA_StatusError if any errors occur during waiting.
636 *
637 *END**************************************************************************/
OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle,uint32_t millisec)638 osa_status_t OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle, uint32_t millisec)
639 {
640 semaphore_t *pSemStruct = (semaphore_t *)semaphoreHandle;
641 uint32_t regPrimask;
642 assert(semaphoreHandle);
643 #if (defined(FSL_OSA_BM_TIMEOUT_ENABLE) && (FSL_OSA_BM_TIMEOUT_ENABLE > 0U))
644 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
645 uint32_t currentTime;
646 #endif
647 #endif
648 /* Check the sem count first. Deal with timeout only if not already set */
649 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
650 #if (TASK_MAX_NUM > 0)
651 pSemStruct->waitingTask = OSA_TaskGetCurrentHandle();
652 #endif
653 #endif
654 if (0U != pSemStruct->semCount)
655 {
656 OSA_EnterCritical(®Primask);
657 pSemStruct->semCount--;
658 pSemStruct->isWaiting = 0U;
659 OSA_ExitCritical(regPrimask);
660 return KOSA_StatusSuccess;
661 }
662 else
663 {
664 if (0U == millisec)
665 {
666 /* If timeout is 0 and semaphore is not available, return kStatus_OSA_Timeout. */
667 return KOSA_StatusTimeout;
668 }
669 #if (defined(FSL_OSA_BM_TIMEOUT_ENABLE) && (FSL_OSA_BM_TIMEOUT_ENABLE > 0U))
670 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
671 else if (0U != pSemStruct->isWaiting)
672 {
673 /* Check for timeout */
674 currentTime = OSA_TimeGetMsec();
675 if (pSemStruct->timeout < OSA_TimeDiff(pSemStruct->time_start, currentTime))
676 {
677 OSA_EnterCritical(®Primask);
678 pSemStruct->isWaiting = 0U;
679 OSA_ExitCritical(regPrimask);
680 return KOSA_StatusTimeout;
681 }
682 }
683 else if (millisec != osaWaitForever_c) /* If don't wait forever, start the timer */
684 {
685 /* Start the timeout counter */
686 OSA_EnterCritical(®Primask);
687 pSemStruct->isWaiting = 1U;
688 OSA_ExitCritical(regPrimask);
689 pSemStruct->time_start = OSA_TimeGetMsec();
690 pSemStruct->timeout = millisec;
691 }
692 #endif
693 #endif
694 else
695 {
696 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
697 pSemStruct->waitingTask->haveToRun = 0U;
698 #endif
699 }
700 }
701
702 return KOSA_StatusIdle;
703 }
704 /*FUNCTION**********************************************************************
705 *
706 * Function Name : OSA_SemaphorePost
707 * Description : This function is used to wake up one task that wating on the
708 * semaphore. If no task is waiting, increase the semaphore. The function returns
709 * KOSA_StatusSuccess if the semaphre is post successfully, otherwise returns
710 * KOSA_StatusError.
711 *
712 *END**************************************************************************/
OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle)713 osa_status_t OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle)
714 {
715 semaphore_t *pSemStruct = (semaphore_t *)semaphoreHandle;
716 uint32_t regPrimask;
717 assert(semaphoreHandle);
718
719 /* check whether max value is reached */
720 if (((KOSA_CountingSemaphore == pSemStruct->semaphoreType) &&
721 (0xFFU == pSemStruct->semCount)) || /* For counting semaphore: the max value is 0xFF */
722 ((0x01U == pSemStruct->semCount) &&
723 (KOSA_BinarySemaphore == pSemStruct->semaphoreType))) /* For binary semaphore: the max value is 0x01 */
724 {
725 return KOSA_StatusError;
726 }
727
728 OSA_EnterCritical(®Primask);
729 ++pSemStruct->semCount;
730 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
731 if (pSemStruct->waitingTask != NULL)
732 {
733 pSemStruct->waitingTask->haveToRun = 1U;
734 }
735 #endif
736
737 OSA_ExitCritical(regPrimask);
738
739 return KOSA_StatusSuccess;
740 }
741
742 /*FUNCTION**********************************************************************
743 *
744 * Function Name : OSA_MutexCreate
745 * Description : This function is used to create a mutex.
746 * Return : Mutex handle of the new mutex, or NULL if failed.
747 *
748 *END**************************************************************************/
OSA_MutexCreate(osa_mutex_handle_t mutexHandle)749 osa_status_t OSA_MutexCreate(osa_mutex_handle_t mutexHandle)
750 {
751 mutex_t *pMutexStruct = (mutex_t *)mutexHandle;
752 assert(sizeof(mutex_t) <= OSA_MUTEX_HANDLE_SIZE);
753 assert(mutexHandle);
754
755 pMutexStruct->isLocked = 0U;
756 pMutexStruct->isWaiting = 0U;
757 #if (defined(FSL_OSA_BM_TIMEOUT_ENABLE) && (FSL_OSA_BM_TIMEOUT_ENABLE > 0U))
758 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
759
760 pMutexStruct->time_start = 0u;
761 pMutexStruct->timeout = 0u;
762 #endif
763 #endif
764 return KOSA_StatusSuccess;
765 }
766
767 /*FUNCTION**********************************************************************
768 *
769 * Function Name : OSA_MutexLock
770 * Description : This function checks the mutex's status, if it is unlocked,
771 * lock it and returns KOSA_StatusSuccess, otherwise, wait for the mutex.
772 * MQX does not support timeout to wait for a mutex.
773 * This function returns KOSA_StatusSuccess if the mutex is obtained, returns
774 * KOSA_StatusError if any errors occur during waiting. If the mutex has been
775 * locked, pass 0 as timeout will return KOSA_StatusTimeout immediately.
776 *
777 *END**************************************************************************/
OSA_MutexLock(osa_mutex_handle_t mutexHandle,uint32_t millisec)778 osa_status_t OSA_MutexLock(osa_mutex_handle_t mutexHandle, uint32_t millisec)
779 {
780 #if (defined(FSL_OSA_BM_TIMEOUT_ENABLE) && (FSL_OSA_BM_TIMEOUT_ENABLE > 0U))
781 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
782 uint32_t currentTime;
783 #endif
784 #endif
785 mutex_t *pMutexStruct = (mutex_t *)mutexHandle;
786 uint32_t regPrimask;
787
788 /* Always check first. Deal with timeout only if not available. */
789 if (0U == pMutexStruct->isLocked)
790 {
791 /* Get the lock and return success */
792 OSA_EnterCritical(®Primask);
793 pMutexStruct->isLocked = 1U;
794 pMutexStruct->isWaiting = 0U;
795 OSA_ExitCritical(regPrimask);
796 return KOSA_StatusSuccess;
797 }
798 else
799 {
800 if (0U == millisec)
801 {
802 /* If timeout is 0 and mutex is not available, return kStatus_OSA_Timeout. */
803 return KOSA_StatusTimeout;
804 }
805 #if (defined(FSL_OSA_BM_TIMEOUT_ENABLE) && (FSL_OSA_BM_TIMEOUT_ENABLE > 0U))
806 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
807 else if (pMutexStruct->isWaiting != 0U)
808 {
809 /* Check for timeout */
810 currentTime = OSA_TimeGetMsec();
811 if (pMutexStruct->timeout < OSA_TimeDiff(pMutexStruct->time_start, currentTime))
812 {
813 OSA_EnterCritical(®Primask);
814 pMutexStruct->isWaiting = 0U;
815 OSA_ExitCritical(regPrimask);
816 return KOSA_StatusTimeout;
817 }
818 }
819 else if (millisec != osaWaitForever_c) /* If dont't wait forever, start timer. */
820 {
821 /* Start the timeout counter */
822 OSA_EnterCritical(®Primask);
823 pMutexStruct->isWaiting = 1U;
824 OSA_ExitCritical(regPrimask);
825 pMutexStruct->time_start = OSA_TimeGetMsec();
826 pMutexStruct->timeout = millisec;
827 }
828 #endif
829 #endif
830 else
831 {
832 ;
833 }
834 }
835
836 return KOSA_StatusIdle;
837 }
838 /*FUNCTION**********************************************************************
839 *
840 * Function Name : OSA_MutexUnlock
841 * Description : This function is used to unlock a mutex.
842 *
843 *END**************************************************************************/
OSA_MutexUnlock(osa_mutex_handle_t mutexHandle)844 osa_status_t OSA_MutexUnlock(osa_mutex_handle_t mutexHandle)
845 {
846 mutex_t *pMutexStruct = (mutex_t *)mutexHandle;
847 uint32_t regPrimask;
848 assert(mutexHandle);
849
850 OSA_EnterCritical(®Primask);
851 pMutexStruct->isLocked = 0U;
852 OSA_ExitCritical(regPrimask);
853 return KOSA_StatusSuccess;
854 }
855 /*FUNCTION**********************************************************************
856 *
857 * Function Name : OSA_MutexDestroy
858 * Description : This function is used to destroy a mutex.
859 * Return : KOSA_StatusSuccess if the lock object is destroyed successfully, otherwise return KOSA_StatusError.
860 *
861 *END**************************************************************************/
OSA_MutexDestroy(osa_mutex_handle_t mutexHandle)862 osa_status_t OSA_MutexDestroy(osa_mutex_handle_t mutexHandle)
863 {
864 assert(mutexHandle);
865 mutex_t *pMutexStruct = (mutex_t *)mutexHandle;
866
867 /* Destory mutexHandle's data */
868 (void)memset(pMutexStruct, 0, sizeof(mutex_t));
869
870 return KOSA_StatusSuccess;
871 }
872
873 /*FUNCTION**********************************************************************
874 *
875 * Function Name : OSA_EventPrecreate
876 * Description : This function is used to pre-create a event.
877 * Return : KOSA_StatusSuccess
878 *
879 *END**************************************************************************/
880
OSA_EventPrecreate(osa_event_handle_t eventHandle,osa_task_ptr_t taskHandler)881 osa_status_t OSA_EventPrecreate(osa_event_handle_t eventHandle, osa_task_ptr_t taskHandler)
882 {
883 eventHandle = eventHandle;
884 taskHandler = taskHandler;
885 return KOSA_StatusSuccess;
886 }
887
888 /*FUNCTION**********************************************************************
889 *
890 * Function Name : OSA_EventCreate
891 * Description : This function is used to create a event object.
892 * Return : Event handle of the new event, or NULL if failed.
893 *
894 *END**************************************************************************/
OSA_EventCreate(osa_event_handle_t eventHandle,uint8_t autoClear)895 osa_status_t OSA_EventCreate(osa_event_handle_t eventHandle, uint8_t autoClear)
896 {
897 event_t *pEventStruct = eventHandle;
898 assert(sizeof(event_t) == OSA_EVENT_HANDLE_SIZE);
899 assert(eventHandle);
900
901 pEventStruct->isWaiting = 0U;
902 pEventStruct->flags = 0;
903 pEventStruct->autoClear = autoClear;
904 pEventStruct->time_start = 0u;
905 pEventStruct->timeout = 0u;
906 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
907 pEventStruct->waitingTask = NULL;
908 #endif
909 return KOSA_StatusSuccess;
910 }
911 /*FUNCTION**********************************************************************
912 *
913 * Function Name : OSA_EventSet
914 * Description : Set one or more event flags of an event object.
915 * Return : KOSA_StatusSuccess if set successfully, KOSA_StatusError if failed.
916 *
917 *END**************************************************************************/
OSA_EventSet(osa_event_handle_t eventHandle,osa_event_flags_t flagsToSet)918 osa_status_t OSA_EventSet(osa_event_handle_t eventHandle, osa_event_flags_t flagsToSet)
919 {
920 event_t *pEventStruct;
921 uint32_t regPrimask;
922 pEventStruct = (event_t *)eventHandle;
923 /* Set flags ensuring atomic operation */
924 OSA_EnterCritical(®Primask);
925 pEventStruct->flags |= flagsToSet;
926 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
927 if (pEventStruct->waitingTask != NULL)
928 {
929 pEventStruct->waitingTask->haveToRun = 1U;
930 }
931 #endif
932 OSA_ExitCritical(regPrimask);
933
934 return KOSA_StatusSuccess;
935 }
936 /*FUNCTION**********************************************************************
937 *
938 * Function Name : OSA_EventClear
939 * Description : Clear one or more event flags of an event object.
940 * Return :KOSA_StatusSuccess if clear successfully, KOSA_StatusError if failed.
941 *
942 *END**************************************************************************/
OSA_EventClear(osa_event_handle_t eventHandle,osa_event_flags_t flagsToClear)943 osa_status_t OSA_EventClear(osa_event_handle_t eventHandle, osa_event_flags_t flagsToClear)
944 {
945 event_t *pEventStruct;
946 uint32_t regPrimask;
947 pEventStruct = (event_t *)eventHandle;
948 /* Clear flags ensuring atomic operation */
949 OSA_EnterCritical(®Primask);
950 pEventStruct->flags &= ~flagsToClear;
951 if (0U != pEventStruct->flags)
952 {
953 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
954 if (NULL != pEventStruct->waitingTask)
955 {
956 pEventStruct->waitingTask->haveToRun = 1U;
957 }
958 #endif
959 }
960 OSA_ExitCritical(regPrimask);
961
962 return KOSA_StatusSuccess;
963 }
964 /*FUNCTION**********************************************************************
965 *
966 * Function Name : OSA_EventGet
967 * Description : This function is used to get event's flags that specified by prameter
968 * flagsMask, and the flags (user specified) are obatianed by parameter pFlagsOfEvent. So
969 * you should pass the parameter 0xffffffff to specify you want to get all.
970 * Return :KOSA_StatusSuccess if event flags were successfully got, KOSA_StatusError if failed.
971 *
972 *END**************************************************************************/
OSA_EventGet(osa_event_handle_t eventHandle,osa_event_flags_t flagsMask,osa_event_flags_t * pFlagsOfEvent)973 osa_status_t OSA_EventGet(osa_event_handle_t eventHandle, osa_event_flags_t flagsMask, osa_event_flags_t *pFlagsOfEvent)
974 {
975 event_t *pEventStruct;
976 uint32_t regPrimask;
977 pEventStruct = (event_t *)eventHandle;
978
979 if (NULL == pFlagsOfEvent)
980 {
981 return KOSA_StatusError;
982 }
983
984 OSA_EnterCritical(®Primask);
985 *pFlagsOfEvent = pEventStruct->flags & flagsMask;
986 OSA_ExitCritical(regPrimask);
987
988 return KOSA_StatusSuccess;
989 }
990 /*FUNCTION**********************************************************************
991 *
992 * Function Name : OSA_EventWait
993 * Description : This function checks the event's status, if it meets the wait
994 * condition, return KOSA_StatusSuccess, otherwise, timeout will be used for
995 * wait. The parameter timeout indicates how long should wait in milliseconds.
996 * Pass osaWaitForever_c to wait indefinitely, pass 0 will return the value
997 * KOSA_StatusTimeout immediately if wait condition is not met. The event flags
998 * will be cleared if the event is auto clear mode. Flags that wakeup waiting
999 * task could be obtained from the parameter setFlags.
1000 * This function returns KOSA_StatusSuccess if wait condition is met, returns
1001 * KOSA_StatusTimeout if wait condition is not met within the specified
1002 * 'timeout', returns KOSA_StatusError if any errors occur during waiting.
1003 *
1004 *END**************************************************************************/
OSA_EventWait(osa_event_handle_t eventHandle,osa_event_flags_t flagsToWait,uint8_t waitAll,uint32_t millisec,osa_event_flags_t * pSetFlags)1005 osa_status_t OSA_EventWait(osa_event_handle_t eventHandle,
1006 osa_event_flags_t flagsToWait,
1007 uint8_t waitAll,
1008 uint32_t millisec,
1009 osa_event_flags_t *pSetFlags)
1010 {
1011 event_t *pEventStruct;
1012 uint32_t regPrimask;
1013 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
1014 uint32_t currentTime;
1015 #endif
1016 osa_status_t retVal = KOSA_StatusIdle;
1017 if (NULL == pSetFlags)
1018 {
1019 return KOSA_StatusError;
1020 }
1021
1022 pEventStruct = (event_t *)eventHandle;
1023
1024 OSA_EnterCritical(®Primask);
1025 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
1026 #if (TASK_MAX_NUM > 0)
1027 pEventStruct->waitingTask = OSA_TaskGetCurrentHandle();
1028 #endif
1029 #endif
1030
1031 *pSetFlags = pEventStruct->flags & flagsToWait;
1032
1033 /* Check the event flag first, if does not meet wait condition, deal with timeout. */
1034 if (((0U == waitAll) && (0U != *pSetFlags)) || (*pSetFlags == flagsToWait))
1035 {
1036 pEventStruct->isWaiting = 0U;
1037 if (1U == pEventStruct->autoClear)
1038 {
1039 pEventStruct->flags &= ~flagsToWait;
1040 }
1041 retVal = KOSA_StatusSuccess;
1042 }
1043 else
1044 {
1045 if (0U == millisec)
1046 {
1047 /* If timeout is 0 and wait condition is not met, return kStatus_OSA_Timeout. */
1048 retVal = KOSA_StatusTimeout;
1049 }
1050 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
1051 else if (0U != pEventStruct->isWaiting)
1052 {
1053 /* Check for timeout */
1054 currentTime = OSA_TimeGetMsec();
1055 if (pEventStruct->timeout < OSA_TimeDiff(pEventStruct->time_start, currentTime))
1056 {
1057 pEventStruct->isWaiting = 0U;
1058 retVal = KOSA_StatusTimeout;
1059 }
1060 }
1061 else if (millisec != osaWaitForever_c) /* If no timeout, don't start the timer */
1062 {
1063 /* Start the timeout counter */
1064 pEventStruct->isWaiting = 1U;
1065 pEventStruct->time_start = OSA_TimeGetMsec();
1066 pEventStruct->timeout = millisec;
1067 }
1068 #endif
1069 else
1070 {
1071 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
1072 pEventStruct->waitingTask->haveToRun = 0U;
1073 #endif
1074 }
1075 }
1076
1077 OSA_ExitCritical(regPrimask);
1078
1079 return retVal;
1080 }
1081 /*FUNCTION**********************************************************************
1082 *
1083 * Function Name : OSA_EventDestroy
1084 * Description : This function is used to destroy a event object. Return
1085 * KOSA_StatusSuccess if the event object is destroyed successfully, otherwise
1086 * return KOSA_StatusError.
1087 *
1088 *END**************************************************************************/
OSA_EventDestroy(osa_event_handle_t eventHandle)1089 osa_status_t OSA_EventDestroy(osa_event_handle_t eventHandle)
1090 {
1091 assert(eventHandle);
1092 event_t *pEventStruct = (event_t *)eventHandle;
1093
1094 /* Destroy eventHandle's data */
1095 (void)memset(pEventStruct, 0, sizeof(event_t));
1096
1097 return KOSA_StatusSuccess;
1098 }
1099
1100 /*FUNCTION**********************************************************************
1101 *
1102 * Function Name : OSA_MsgQCreate
1103 * Description : This function is used to create a message queue.
1104 * Return : the handle to the message queue if create successfully, otherwise
1105 * return NULL.
1106 *
1107 *END**************************************************************************/
OSA_MsgQCreate(osa_msgq_handle_t msgqHandle,uint32_t msgNo,uint32_t msgSize)1108 osa_status_t OSA_MsgQCreate(osa_msgq_handle_t msgqHandle, uint32_t msgNo, uint32_t msgSize)
1109 {
1110 msg_queue_t *pMsgQStruct = msgqHandle;
1111 assert(sizeof(msg_queue_t) == OSA_MSGQ_HANDLE_SIZE);
1112 assert(msgqHandle);
1113
1114 pMsgQStruct->max = (uint16_t)msgNo;
1115 pMsgQStruct->number = 0;
1116 pMsgQStruct->head = 0;
1117 pMsgQStruct->tail = 0;
1118 pMsgQStruct->size = msgSize;
1119 pMsgQStruct->queueMem = (uint8_t *)((uint8_t *)msgqHandle + sizeof(msg_queue_t));
1120 return KOSA_StatusSuccess;
1121 }
1122
1123 /*FUNCTION**********************************************************************
1124 *
1125 * Function Name : OSA_MsgQPut
1126 * Description : This function is used to put a message to a message queue.
1127 * Return : KOSA_StatusSuccess if the message is put successfully, otherwise return KOSA_StatusError.
1128 *
1129 *END**************************************************************************/
OSA_MsgQPut(osa_msgq_handle_t msgqHandle,osa_msg_handle_t pMessage)1130 osa_status_t OSA_MsgQPut(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage)
1131 {
1132 assert(msgqHandle);
1133 msg_queue_t *pQueue;
1134 osa_status_t status = KOSA_StatusSuccess;
1135 uint32_t regPrimask;
1136
1137 uint8_t *pMsgArray;
1138
1139 pQueue = (msg_queue_t *)msgqHandle;
1140
1141 if (NULL == pQueue->queueMem)
1142 {
1143 return KOSA_StatusError;
1144 }
1145
1146 OSA_EnterCritical(®Primask);
1147 if (pQueue->number >= pQueue->max)
1148 {
1149 status = KOSA_StatusError;
1150 }
1151 else
1152 {
1153 pMsgArray = &pQueue->queueMem[pQueue->tail];
1154 for (uint32_t i = 0; i < pQueue->size; i++)
1155 {
1156 pMsgArray[i] = *((uint8_t *)pMessage + i);
1157 }
1158
1159 pQueue->number++;
1160 pQueue->tail += (uint16_t)pQueue->size;
1161
1162 if (pQueue->tail >= (pQueue->max * pQueue->size))
1163 {
1164 pQueue->tail = 0;
1165 }
1166 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
1167 if (NULL != pQueue->waitingTask)
1168 {
1169 pQueue->waitingTask->haveToRun = 1U;
1170 }
1171 #endif
1172 }
1173 OSA_ExitCritical(regPrimask);
1174 return status;
1175 }
1176 /*FUNCTION**********************************************************************
1177 *
1178 * Function Name : OSA_MsgQGet
1179 * Description : This function checks the queue's status, if it is not empty,
1180 * get message from it and return KOSA_StatusSuccess, otherwise, timeout will
1181 * be used for wait. The parameter timeout indicates how long should wait in
1182 * milliseconds. Pass osaWaitForever_c to wait indefinitely, pass 0 will return
1183 * KOSA_StatusTimeout immediately if queue is empty.
1184 * This function returns KOSA_StatusSuccess if message is got successfully,
1185 * returns KOSA_StatusTimeout if message queue is empty within the specified
1186 * 'timeout', returns KOSA_StatusError if any errors occur during waiting.
1187 *
1188 *END**************************************************************************/
OSA_MsgQGet(osa_msgq_handle_t msgqHandle,osa_msg_handle_t pMessage,uint32_t millisec)1189 osa_status_t OSA_MsgQGet(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage, uint32_t millisec)
1190 {
1191 assert(msgqHandle);
1192 msg_queue_t *pQueue;
1193 osa_status_t status = KOSA_StatusSuccess;
1194 uint32_t regPrimask;
1195
1196 uint8_t *pMsgArray;
1197
1198 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
1199 uint32_t currentTime;
1200 #endif
1201
1202 pQueue = (msg_queue_t *)msgqHandle;
1203
1204 if (NULL == pQueue->queueMem)
1205 {
1206 return KOSA_StatusError;
1207 }
1208
1209 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
1210 pQueue->waitingTask = OSA_TaskGetCurrentHandle();
1211 #endif
1212
1213 OSA_EnterCritical(®Primask);
1214 if (0U != pQueue->number)
1215 {
1216 pMsgArray = (uint8_t *)pMessage;
1217 for (uint32_t i = 0; i < pQueue->size; i++)
1218 {
1219 pMsgArray[i] = pQueue->queueMem[pQueue->head + i];
1220 }
1221
1222 pQueue->number--;
1223 pQueue->head += (uint16_t)pQueue->size;
1224 pQueue->isWaiting = 0U;
1225
1226 if (pQueue->head >= (pQueue->max * pQueue->size))
1227 {
1228 pQueue->head = 0;
1229 }
1230 status = KOSA_StatusSuccess;
1231 }
1232 else
1233 {
1234 if (0U == millisec)
1235 {
1236 /* If timeout is 0 and wait condition is not met, return kStatus_OSA_Timeout. */
1237 status = KOSA_StatusTimeout;
1238 }
1239 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
1240 else if (0U != pQueue->isWaiting)
1241 {
1242 /* Check for timeout */
1243 status = KOSA_StatusIdle; /* Before a timeout, the status should be idle. */
1244 currentTime = OSA_TimeGetMsec();
1245 if (pQueue->timeout < OSA_TimeDiff(pQueue->time_start, currentTime))
1246 {
1247 pQueue->isWaiting = 0U;
1248 status = KOSA_StatusTimeout;
1249 }
1250 }
1251 else if (millisec != osaWaitForever_c) /* If no timeout, don't start the timer */
1252 {
1253 /* Start the timeout counter */
1254 pQueue->isWaiting = 1U;
1255 pQueue->time_start = OSA_TimeGetMsec();
1256 pQueue->timeout = millisec;
1257 status = KOSA_StatusIdle;
1258 }
1259 #endif
1260 else
1261 {
1262 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
1263 pQueue->waitingTask->haveToRun = 0U;
1264 #endif
1265 status = KOSA_StatusIdle;
1266 }
1267 }
1268 OSA_ExitCritical(regPrimask);
1269
1270 return status;
1271 }
1272
1273 /*FUNCTION**********************************************************************
1274 *
1275 * Function Name : OSA_MsgQAvailableMsgs
1276 * Description : This function is used to get the available message.
1277 * Return : Available message count
1278 *
1279 *END**************************************************************************/
OSA_MsgQAvailableMsgs(osa_msgq_handle_t msgqHandle)1280 int OSA_MsgQAvailableMsgs(osa_msgq_handle_t msgqHandle)
1281 {
1282 assert(msgqHandle);
1283 msg_queue_t *pQueue = (msg_queue_t *)msgqHandle;
1284
1285 return (int)pQueue->number;
1286 }
1287
1288 /*FUNCTION**********************************************************************
1289 *
1290 * Function Name : OSA_EXT_MsgQDestroy
1291 * Description : This function is used to destroy the message queue.
1292 * Return : KOSA_StatusSuccess if the message queue is destroyed successfully, otherwise return KOSA_StatusError.
1293 *
1294 *END**************************************************************************/
OSA_MsgQDestroy(osa_msgq_handle_t msgqHandle)1295 osa_status_t OSA_MsgQDestroy(osa_msgq_handle_t msgqHandle)
1296 {
1297 assert(msgqHandle);
1298 msg_queue_t *pQueue = (msg_queue_t *)msgqHandle;
1299
1300 /* Destory msgqHandle's data */
1301 /* OSA_MsgQGet() & OSA_MsgQPut() will check queueMem, if NULL will return an error. */
1302 (void)memset(pQueue, 0, sizeof(msg_queue_t));
1303
1304 return KOSA_StatusSuccess;
1305 }
1306
1307 /*FUNCTION**********************************************************************
1308 *
1309 * Function Name : OSA_InterruptEnable
1310 * Description : self explanatory.
1311 *
1312 *END**************************************************************************/
OSA_InterruptEnable(void)1313 void OSA_InterruptEnable(void)
1314 {
1315 OSA_EnableIRQGlobal();
1316 }
1317 /*FUNCTION**********************************************************************
1318 *
1319 * Function Name : OSA_InterruptDisable
1320 * Description : self explanatory.
1321 *
1322 *END**************************************************************************/
OSA_InterruptDisable(void)1323 void OSA_InterruptDisable(void)
1324 {
1325 OSA_DisableIRQGlobal();
1326 }
1327
1328 /*FUNCTION**********************************************************************
1329 *
1330 * Function Name : OSA_InstallIntHandler
1331 * Description : This function is used to install interrupt handler.
1332 *
1333 *END**************************************************************************/
OSA_InstallIntHandler(uint32_t IRQNumber,void (* handler)(void))1334 void OSA_InstallIntHandler(uint32_t IRQNumber, void (*handler)(void))
1335 {
1336 #if defined(__IAR_SYSTEMS_ICC__)
1337 _Pragma("diag_suppress = Pm138")
1338 #endif
1339 #if defined(ENABLE_RAM_VECTOR_TABLE)
1340 (void) InstallIRQHandler((IRQn_Type)IRQNumber, (uint32_t) * (uint32_t *)&handler);
1341 #endif /* ENABLE_RAM_VECTOR_TABLE. */
1342 #if defined(__IAR_SYSTEMS_ICC__)
1343 _Pragma("diag_remark = PM138")
1344 #endif
1345 }
1346
1347 /*! *********************************************************************************
1348 *************************************************************************************
1349 * Private functions
1350 *************************************************************************************
1351 ********************************************************************************** */
1352 #if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
1353 #if (defined(FSL_OSA_MAIN_FUNC_ENABLE) && (FSL_OSA_MAIN_FUNC_ENABLE > 0U))
1354 static OSA_TASK_DEFINE(main_task, gMainThreadPriority_c, 1, gMainThreadStackSize_c, 0);
1355
main(void)1356 void main(void)
1357 {
1358 OSA_Init();
1359
1360 /* Initialize MCU clock */
1361 extern void BOARD_InitHardware(void);
1362 BOARD_InitHardware();
1363
1364 (void)OSA_TaskCreate((osa_task_handle_t)s_osaState.mainTaskHandle, OSA_TASK(main_task), NULL);
1365
1366 OSA_Start();
1367 }
1368 #endif /*(defined(FSL_OSA_MAIN_FUNC_ENABLE) && (FSL_OSA_MAIN_FUNC_ENABLE > 0U))*/
1369 #endif /* FSL_OSA_TASK_ENABLE */
1370
1371 /*FUNCTION**********************************************************************
1372 *
1373 * Function Name : OSA_Init
1374 * Description : This function is used to setup the basic services, it should
1375 * be called first in function main.
1376 *
1377 *END**************************************************************************/
1378 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_Init(void)1379 void OSA_Init(void)
1380 {
1381 LIST_Init((&s_osaState.taskList), 0);
1382 s_osaState.curTaskHandler = NULL;
1383 s_osaState.interruptDisableCount = 0U;
1384 s_osaState.tickCounter = 0U;
1385 }
1386 #endif
1387
1388 /*FUNCTION**********************************************************************
1389 *
1390 * Function Name : OSA_Start
1391 * Description : This function is used to start RTOS scheduler.
1392 *
1393 *END**************************************************************************/
1394 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_Start(void)1395 void OSA_Start(void)
1396 {
1397 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
1398 OSA_TimeInit();
1399 #endif
1400 while (true)
1401 {
1402 OSA_ProcessTasks();
1403 }
1404 }
1405
1406 /*FUNCTION**********************************************************************
1407 *
1408 * Function Name : OSA_ProcessTasks
1409 * Description : This function is used to process registered tasks.
1410 *
1411 *END**************************************************************************/
OSA_ProcessTasks(void)1412 void OSA_ProcessTasks(void)
1413 {
1414 list_element_handle_t list_element;
1415 task_control_block_t *tcb;
1416
1417 list_element = LIST_GetHead(&s_osaState.taskList);
1418 while (NULL != list_element)
1419 {
1420 tcb = (task_control_block_t *)(void *)list_element;
1421 s_osaState.curTaskHandler = (osa_task_handle_t)tcb;
1422 if (0U != tcb->haveToRun)
1423 {
1424 if (NULL != tcb->p_func)
1425 {
1426 tcb->p_func(tcb->param);
1427 }
1428 list_element = LIST_GetHead(&s_osaState.taskList);
1429 }
1430 else
1431 {
1432 list_element = LIST_GetNext(list_element);
1433 }
1434 }
1435 }
1436
1437 /*FUNCTION**********************************************************************
1438 *
1439 * Function Name : OSA_TaskShouldYield
1440 * Description : When this function returns TRUE, an OSA task has to run
1441 *
1442 *END**************************************************************************/
OSA_TaskShouldYield(void)1443 uint8_t OSA_TaskShouldYield(void)
1444 {
1445 list_element_handle_t list_element;
1446 uint8_t status = 0;
1447 task_control_block_t *tcb;
1448
1449 list_element = LIST_GetHead(&s_osaState.taskList);
1450 while ((list_element != NULL))
1451 {
1452 tcb = (task_control_block_t *)(void *)list_element;
1453 if (1U == tcb->haveToRun)
1454 {
1455 status = 1U;
1456 break;
1457 }
1458 list_element = LIST_GetNext(list_element);
1459 }
1460 return status;
1461 }
1462 #endif
1463
1464 /*FUNCTION**********************************************************************
1465 *
1466 * Function Name : SysTick_Handler
1467 * Description : This ISR of the SYSTICK timer.
1468 *
1469 *END**************************************************************************/
1470 #if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
1471 void SysTick_Handler(void);
SysTick_Handler(void)1472 void SysTick_Handler(void)
1473 {
1474 s_osaState.tickCounter++;
1475 }
1476 #endif
1477