1 /*! *********************************************************************************
2  * Copyright 2020-2021 NXP
3  * All rights reserved.
4  *
5  *
6  * This is the source file for the OS Abstraction layer for thread.
7  *
8  * SPDX-License-Identifier: BSD-3-Clause
9  ********************************************************************************** */
10 
11 /*! *********************************************************************************
12 *************************************************************************************
13 * Include
14 *************************************************************************************
15 ********************************************************************************** */
16 #include "fsl_common.h"
17 #include "fsl_os_abstraction.h"
18 #include "tx_api.h"
19 #include "tx_event_flags.h"
20 #include <string.h>
21 #include "fsl_component_generic_list.h"
22 #include "fsl_os_abstraction_threadx.h"
23 
24 /*! *********************************************************************************
25 *************************************************************************************
26 * Private macros
27 *************************************************************************************
28 ********************************************************************************** */
29 
30 /* Weak function. */
31 #if defined(__GNUC__)
32 #define __WEAK_FUNC __attribute__((weak))
33 #elif defined(__ICCARM__)
34 #define __WEAK_FUNC __weak
35 #elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
36 #define __WEAK_FUNC __attribute__((weak))
37 #endif
38 
39 #define millisecToTicks(millisec) (((millisec)*TX_TIMER_TICKS_PER_SECOND + 999U) / 1000U)
40 
41 #ifdef DEBUG_ASSERT
42 #define OS_ASSERT(condition) \
43     if (!(condition))        \
44         while (1)            \
45             ;
46 #else
47 #define OS_ASSERT(condition) (void)(condition);
48 #endif
49 
50 /*! @brief Converts milliseconds to ticks*/
51 #define MSEC_TO_TICK(msec) \
52     (((uint32_t)(msec) + 500uL / (uint32_t)TX_TIMER_TICKS_PER_SECOND) * (uint32_t)TX_TIMER_TICKS_PER_SECOND / 1000uL)
53 
54 #define TICKS_TO_MSEC(tick) ((uint32_t)((uint64_t)(tick)*1000uL / (uint64_t)TX_TIMER_TICKS_PER_SECOND))
55 
56 /************************************************************************************
57 *************************************************************************************
58 * Private type definitions
59 *************************************************************************************
60 ************************************************************************************/
61 typedef struct osa_thread_task
62 {
63     list_element_t link;
64     TX_THREAD taskHandle;
65 } osa_thread_task_t;
66 
67 typedef struct _osa_event_struct
68 {
69     TX_EVENT_FLAGS_GROUP handle; /* The event handle */
70     uint8_t autoClear;           /*!< Auto clear or manual clear   */
71 } osa_event_struct_t;
72 
73 /*! @brief State structure for thread osa manager. */
74 typedef struct _osa_state
75 {
76 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
77     list_label_t taskList;
78 #endif
79     uint32_t basePriority;
80     int32_t basePriorityNesting;
81     uint32_t interruptDisableCount;
82 } osa_state_t;
83 
84 /*! *********************************************************************************
85 *************************************************************************************
86 * Private prototypes
87 *************************************************************************************
88 ********************************************************************************** */
89 
90 /*! *********************************************************************************
91 *************************************************************************************
92 * Public memory declarations
93 *************************************************************************************
94 ********************************************************************************** */
95 const uint8_t gUseRtos_c = USE_RTOS; // USE_RTOS = 0 for BareMetal and 1 for OS
96 
97 static TX_INTERRUPT_SAVE_AREA
98 
99 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
100     static osa_state_t s_osaState = {0};
101 #endif
102 
103 /*! *********************************************************************************
104 *************************************************************************************
105 * Private memory declarations
106 *************************************************************************************
107 ********************************************************************************** */
108 
109 /*! *********************************************************************************
110 *************************************************************************************
111 * Public functions
112 *************************************************************************************
113 ********************************************************************************** */
114 /*FUNCTION**********************************************************************
115  *
116  * Function Name : OSA_MemoryAllocate
117  * Description   : Reserves the requested amount of memory in bytes.
118  *
119  *END**************************************************************************/
OSA_MemoryAllocate(uint32_t length)120 void *OSA_MemoryAllocate(uint32_t length)
121 {
122     return NULL;
123 }
124 
125 /*FUNCTION**********************************************************************
126  *
127  * Function Name : OSA_MemoryFree
128  * Description   : Frees the memory previously reserved.
129  *
130  *END**************************************************************************/
OSA_MemoryFree(void * p)131 void OSA_MemoryFree(void *p)
132 {
133 }
134 
135 /*FUNCTION**********************************************************************
136  *
137  * Function Name : OSA_EnterCritical
138  * Description   : Enter critical.
139  *
140  *END**************************************************************************/
OSA_EnterCritical(uint32_t * sr)141 void OSA_EnterCritical(uint32_t *sr)
142 {
143 }
144 
145 /*FUNCTION**********************************************************************
146  *
147  * Function Name : OSA_ExitCritical
148  * Description   : Exit critical.
149  *
150  *END**************************************************************************/
OSA_ExitCritical(uint32_t sr)151 void OSA_ExitCritical(uint32_t sr)
152 {
153 }
154 
155 /*FUNCTION**********************************************************************
156  *
157  * Function Name : OSA_Init
158  * Description   : This function is used to setup the basic services, it should
159  * be called first in function main.
160  *
161  *END**************************************************************************/
162 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_Init(void)163 void OSA_Init(void)
164 {
165     LIST_Init((&s_osaState.taskList), 0);
166     s_osaState.basePriorityNesting   = 0;
167     s_osaState.interruptDisableCount = 0;
168 }
169 #endif
170 
171 /*FUNCTION**********************************************************************
172  *
173  * Function Name : OSA_Start
174  * Description   : This function is used to start RTOS scheduler.
175  *
176  *END**************************************************************************/
177 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
178 /* Configures _tx_initialize_low_level_ptr and tx_application_define_ptr */
179 extern void Prepare_ThreadX(void);
180 
OSA_Start(void)181 void OSA_Start(void)
182 {
183     Prepare_ThreadX();
184     /* Start ThreadX */
185     tx_kernel_enter();
186 }
187 #endif
188 
189 /*FUNCTION**********************************************************************
190  *
191  * Function Name : OSA_TaskGetCurrentHandle
192  * Description   : This function is used to get current active task's handler.
193  *
194  *END**************************************************************************/
195 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskGetCurrentHandle(void)196 osa_task_handle_t OSA_TaskGetCurrentHandle(void)
197 {
198     return NULL;
199 }
200 #endif
201 
202 /*FUNCTION**********************************************************************
203  *
204  * Function Name : OSA_TaskYield
205  * Description   : When a task calls this function, it will give up CPU and put
206  * itself to the tail of ready list.
207  *
208  *END**************************************************************************/
209 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskYield(void)210 void OSA_TaskYield(void)
211 {
212 }
213 #endif
214 
215 /*FUNCTION**********************************************************************
216  *
217  * Function Name : OSA_TaskGetPriority
218  * Description   : This function returns task's priority by task handler.
219  *
220  *END**************************************************************************/
221 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskGetPriority(osa_task_handle_t taskHandle)222 osa_task_priority_t OSA_TaskGetPriority(osa_task_handle_t taskHandle)
223 {
224     return 0U;
225 }
226 #endif
227 
228 /*FUNCTION**********************************************************************
229  *
230  * Function Name : OSA_TaskSetPriority
231  * Description   : This function sets task's priority by task handler.
232  *
233  *END**************************************************************************/
234 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskSetPriority(osa_task_handle_t taskHandle,osa_task_priority_t taskPriority)235 osa_status_t OSA_TaskSetPriority(osa_task_handle_t taskHandle, osa_task_priority_t taskPriority)
236 {
237     return KOSA_StatusSuccess;
238 }
239 #endif
240 
241 /*FUNCTION**********************************************************************
242  *
243  * Function Name : OSA_TaskCreate
244  * Description   : This function is used to create a task and make it ready.
245  * Param[in]     :  threadDef  - Definition of the thread.
246  *                  task_param - Parameter to pass to the new thread.
247  * Return Thread handle of the new thread, or NULL if failed.
248  *
249  *END**************************************************************************/
250 #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)251 osa_status_t OSA_TaskCreate(osa_task_handle_t taskHandle, const osa_task_def_t *thread_def, osa_task_param_t task_param)
252 {
253     assert(taskHandle);
254     osa_status_t status      = KOSA_StatusError;
255     osa_thread_task_t *ptask = (osa_thread_task_t *)taskHandle;
256 
257     if (tx_thread_create(&ptask->taskHandle,                            /* task handle, allocated by application */
258                          (char *)thread_def->tname,                     /* thread name */
259                          (void (*)(ULONG))thread_def->pthread,          /* entry function */
260                          (ULONG)((ULONG *)task_param),                  /* entry input */
261                          (void *)thread_def->tstack,                    /* stack start */
262                          (ULONG)thread_def->stacksize,                  /* stack size */
263                          PRIORITY_OSA_TO_THREAD(thread_def->tpriority), /* initial priority */
264                          PRIORITY_OSA_TO_THREAD(thread_def->tpriority), /* preempt threshold (same value than the priority means disabled) */
265                          0U,                                            /* time slice */
266                          true                                           /* auto start */
267                          ) == TX_SUCCESS)
268     {
269         OSA_InterruptDisable();
270         (void)LIST_AddTail(&s_osaState.taskList, (list_element_handle_t) & (ptask->link));
271         OSA_InterruptEnable();
272         status = KOSA_StatusSuccess;
273     }
274     return status;
275 }
276 #endif
277 
278 /*FUNCTION**********************************************************************
279  *
280  * Function Name : OSA_TaskDestroy
281  * Description   : This function destroy a task.
282  * Param[in]     :taskHandle - Thread handle.
283  * Return KOSA_StatusSuccess if the task is destroied, otherwise return KOSA_StatusError.
284  *
285  *END**************************************************************************/
286 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskDestroy(osa_task_handle_t taskHandle)287 osa_status_t OSA_TaskDestroy(osa_task_handle_t taskHandle)
288 {
289     assert(taskHandle);
290     osa_thread_task_t *ptask = (osa_thread_task_t *)taskHandle;
291     osa_status_t status      = KOSA_StatusSuccess;
292 
293 #if 0
294     uint16_t oldPriority;
295     /*Change priority to avoid context switches*/
296     oldPriority = OSA_TaskGetPriority(OSA_TaskGetCurrentHandle());
297     (void)OSA_TaskSetPriority(OSA_TaskGetCurrentHandle(), OSA_PRIORITY_REAL_TIME);
298     if (TX_SUCCESS != tx_thread_delete(&ptask->taskHandle))
299     {
300         status = KOSA_StatusError;
301     }
302     (void)OSA_TaskSetPriority(OSA_TaskGetCurrentHandle(), oldPriority);
303     OSA_InterruptDisable();
304     (void)LIST_RemoveElement(taskHandle);
305     OSA_InterruptEnable();
306 #else
307     if (TX_SUCCESS != tx_thread_delete(&ptask->taskHandle))
308     {
309         status = KOSA_StatusError;
310     }
311     (void)LIST_RemoveElement(taskHandle);
312 #endif
313     return status;
314 }
315 #endif
316 
317 /*FUNCTION**********************************************************************
318  *
319  * Function Name : OSA_TimeDelay
320  * Description   : This function is used to suspend the active thread for the given number of milliseconds.
321  *
322  *END**************************************************************************/
OSA_TimeDelay(uint32_t millisec)323 void OSA_TimeDelay(uint32_t millisec)
324 {
325     (void)tx_thread_sleep(millisecToTicks(millisec));
326 }
327 /*FUNCTION**********************************************************************
328  *
329  * Function Name : OSA_TimeGetMsec
330  * Description   : This function gets current time in milliseconds.
331  *
332  *END**************************************************************************/
OSA_TimeGetMsec(void)333 uint32_t OSA_TimeGetMsec(void)
334 {
335     return TICKS_TO_MSEC(tx_time_get());
336 }
337 
338 /*FUNCTION**********************************************************************
339  *
340  * Function Name : OSA_SemaphorePrecreate
341  * Description   : This function is used to pre-create a semaphore.
342  * Return         : KOSA_StatusSuccess
343  *
344  *END**************************************************************************/
345 
OSA_SemaphorePrecreate(osa_semaphore_handle_t semaphoreHandle,osa_task_ptr_t taskHandler)346 osa_status_t OSA_SemaphorePrecreate(osa_semaphore_handle_t semaphoreHandle, osa_task_ptr_t taskHandler)
347 {
348     semaphoreHandle = semaphoreHandle;
349     taskHandler     = taskHandler;
350     return KOSA_StatusSuccess;
351 }
352 
353 /*FUNCTION**********************************************************************
354  *
355  * Function Name : OSA_SemaphoreCreate
356  * Description   : This function is used to create a semaphore.
357  * Return         : Semaphore handle of the new semaphore, or NULL if failed.
358  *
359  *END**************************************************************************/
OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle,uint32_t initValue)360 osa_status_t OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle, uint32_t initValue)
361 {
362     osa_status_t status = KOSA_StatusSuccess;
363 
364     assert(semaphoreHandle != NULL);
365 
366     if (TX_SUCCESS != tx_semaphore_create((TX_SEMAPHORE *)semaphoreHandle, NULL, (ULONG)initValue))
367     {
368         status = KOSA_StatusError;
369     }
370 
371     return status;
372 }
373 
374 /*FUNCTION**********************************************************************
375  *
376  * Function Name : OSA_SemaphoreCreateBinary
377  * Description   : This function is used to create a binary semaphore.
378  * Return        : Semaphore handle of the new binary semaphore, or NULL if failed.
379  *
380  *END**************************************************************************/
OSA_SemaphoreCreateBinary(osa_semaphore_handle_t semaphoreHandle)381 osa_status_t OSA_SemaphoreCreateBinary(osa_semaphore_handle_t semaphoreHandle)
382 {
383     /* TODO */
384     return KOSA_StatusError;
385 }
386 
387 /*FUNCTION**********************************************************************
388  *
389  * Function Name : OSA_SemaphoreDestroy
390  * Description   : This function is used to destroy a semaphore.
391  * Return        : KOSA_StatusSuccess if the semaphore is destroyed successfully, otherwise return KOSA_StatusError.
392  *
393  *END**************************************************************************/
OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle)394 osa_status_t OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle)
395 {
396     osa_status_t status = KOSA_StatusSuccess;
397 
398     assert(semaphoreHandle != NULL);
399 
400     if (TX_SUCCESS != tx_semaphore_delete((TX_SEMAPHORE *)semaphoreHandle))
401     {
402         status = KOSA_StatusError;
403     }
404 
405     return status;
406 }
407 
408 /*FUNCTION**********************************************************************
409  *
410  * Function Name : OSA_SemaphoreWait
411  * Description   : This function checks the semaphore's counting value, if it is
412  * positive, decreases it and returns KOSA_StatusSuccess, otherwise, timeout
413  * will be used for wait. The parameter timeout indicates how long should wait
414  * in milliseconds. Pass osaWaitForever_c to wait indefinitely, pass 0 will
415  * return KOSA_StatusTimeout immediately if semaphore is not positive.
416  * This function returns KOSA_StatusSuccess if the semaphore is received, returns
417  * KOSA_StatusTimeout if the semaphore is not received within the specified
418  * 'timeout', returns KOSA_StatusError if any errors occur during waiting.
419  *
420  *END**************************************************************************/
OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle,uint32_t millisec)421 osa_status_t OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle, uint32_t millisec)
422 {
423     osa_status_t status = KOSA_StatusSuccess;
424     ULONG timeoutTicks;
425 
426     assert(semaphoreHandle != NULL);
427 
428     /* Convert timeout from millisecond to tick. */
429     if (millisec == osaWaitForever_c)
430     {
431         timeoutTicks = TX_WAIT_FOREVER;
432     }
433     else if (millisec == osaWaitNone_c)
434     {
435         timeoutTicks = TX_NO_WAIT;
436     }
437     else
438     {
439         timeoutTicks = MSEC_TO_TICK(millisec);
440     }
441 
442     if (TX_SUCCESS != tx_semaphore_get((TX_SEMAPHORE *)semaphoreHandle, timeoutTicks))
443     {
444         status = KOSA_StatusError;
445     }
446 
447     return status;
448 }
449 
450 /*FUNCTION**********************************************************************
451  *
452  * Function Name : OSA_SemaphorePost
453  * Description   : This function is used to wake up one task that wating on the
454  * semaphore. If no task is waiting, increase the semaphore. The function returns
455  * KOSA_StatusSuccess if the semaphre is post successfully, otherwise returns
456  * KOSA_StatusError.
457  *
458  *END**************************************************************************/
OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle)459 osa_status_t OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle)
460 {
461     osa_status_t status = KOSA_StatusSuccess;
462 
463     assert(semaphoreHandle != NULL);
464 
465     if (TX_SUCCESS != tx_semaphore_put((TX_SEMAPHORE *)semaphoreHandle))
466     {
467         status = KOSA_StatusError;
468     }
469 
470     return status;
471 }
472 
473 /*FUNCTION**********************************************************************
474  *
475  * Function Name : OSA_MutexCreate
476  * Description   : This function is used to create a mutex.
477  * Return        : KOSA_StatusSuccess if mutex is created successfully, otherwise returns
478  *                 KOSA_StatusError.
479  *
480  *END**************************************************************************/
OSA_MutexCreate(osa_mutex_handle_t mutexHandle)481 osa_status_t OSA_MutexCreate(osa_mutex_handle_t mutexHandle)
482 {
483     assert(mutexHandle);
484     osa_status_t status = KOSA_StatusSuccess;
485 
486 #ifndef CPU2
487     if (TX_SUCCESS != tx_mutex_create((TX_MUTEX *)mutexHandle, NULL, 0U))
488     {
489         status = KOSA_StatusError;
490     }
491 #endif
492     return status;
493 }
494 
495 /*FUNCTION**********************************************************************
496  *
497  * Function Name : OSA_MutexLock
498  * Description   : This function checks the mutex's status, if it is unlocked,
499  * lock it and returns KOSA_StatusSuccess, otherwise, wait for the mutex.
500  * This function returns KOSA_StatusSuccess if the mutex is obtained, returns
501  * KOSA_StatusError if any errors occur during waiting. If the mutex has been
502  * locked, pass 0 as timeout will return KOSA_StatusTimeout immediately.
503  *
504  *END**************************************************************************/
OSA_MutexLock(osa_mutex_handle_t mutexHandle,uint32_t millisec)505 osa_status_t OSA_MutexLock(osa_mutex_handle_t mutexHandle, uint32_t millisec)
506 {
507     assert(mutexHandle);
508     osa_status_t status = KOSA_StatusSuccess;
509 
510 #ifndef CPU2
511     uint32_t timeoutTicks;
512     /* Convert timeout from millisecond to tick. */
513     if (millisec == osaWaitForever_c)
514     {
515         timeoutTicks = TX_WAIT_FOREVER;
516     }
517     else
518     {
519         timeoutTicks = MSEC_TO_TICK(millisec);
520     }
521 
522     if (TX_SUCCESS != tx_mutex_get((TX_MUTEX *)mutexHandle, timeoutTicks))
523     {
524         status = KOSA_StatusError;
525     }
526 #endif
527     return status;
528 }
529 
530 /*FUNCTION**********************************************************************
531  *
532  * Function Name : OSA_MutexUnlock
533  * Description   : This function is used to unlock a mutex.
534  *
535  *END**************************************************************************/
OSA_MutexUnlock(osa_mutex_handle_t mutexHandle)536 osa_status_t OSA_MutexUnlock(osa_mutex_handle_t mutexHandle)
537 {
538     assert(mutexHandle);
539     osa_status_t status = KOSA_StatusSuccess;
540 
541 #ifndef CPU2
542     if (TX_SUCCESS != tx_mutex_put((TX_MUTEX *)mutexHandle))
543     {
544         status = KOSA_StatusError;
545     }
546 #endif
547     return status;
548 }
549 
550 /*FUNCTION**********************************************************************
551  *
552  * Function Name : OSA_MutexDestroy
553  * Description   : This function is used to destroy a mutex.
554  * Return        : KOSA_StatusSuccess if the lock object is destroyed successfully, otherwise return KOSA_StatusError.
555  *
556  *END**************************************************************************/
OSA_MutexDestroy(osa_mutex_handle_t mutexHandle)557 osa_status_t OSA_MutexDestroy(osa_mutex_handle_t mutexHandle)
558 {
559     assert(mutexHandle);
560     osa_status_t status = KOSA_StatusSuccess;
561 
562     if (TX_SUCCESS != tx_mutex_delete((TX_MUTEX *)mutexHandle))
563     {
564         status = KOSA_StatusError;
565     }
566     return status;
567 }
568 
569 /*FUNCTION**********************************************************************
570  *
571  * Function Name : OSA_EventPrecreate
572  * Description   : This function is used to pre-create a event.
573  * Return         : KOSA_StatusSuccess
574  *
575  *END**************************************************************************/
576 
OSA_EventPrecreate(osa_event_handle_t eventHandle,osa_task_ptr_t taskHandler)577 osa_status_t OSA_EventPrecreate(osa_event_handle_t eventHandle, osa_task_ptr_t taskHandler)
578 {
579     eventHandle = eventHandle;
580     taskHandler = taskHandler;
581     return KOSA_StatusSuccess;
582 }
583 
584 /*FUNCTION**********************************************************************
585  *
586  * Function Name : OSA_EventCreate
587  * Description   : This function is used to create a event object.
588  * Return        : Event handle of the new event, or NULL if failed.
589  *
590  *END**************************************************************************/
OSA_EventCreate(osa_event_handle_t eventHandle,uint8_t autoClear)591 osa_status_t OSA_EventCreate(osa_event_handle_t eventHandle, uint8_t autoClear)
592 {
593     osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
594     osa_status_t status              = KOSA_StatusSuccess;
595 
596     assert(eventHandle != NULL);
597 
598     pEventStruct->autoClear = autoClear;
599 
600     if (TX_SUCCESS != tx_event_flags_create(&pEventStruct->handle, NULL))
601     {
602         status = KOSA_StatusError;
603     }
604 
605     return status;
606 }
607 
608 /*FUNCTION**********************************************************************
609  *
610  * Function Name : OSA_EventSet
611  * Description   : Set one or more event flags of an event object.
612  * Return        : KOSA_StatusSuccess if set successfully, KOSA_StatusError if failed.
613  *
614  *END**************************************************************************/
OSA_EventSet(osa_event_handle_t eventHandle,osa_event_flags_t flagsToSet)615 osa_status_t OSA_EventSet(osa_event_handle_t eventHandle, osa_event_flags_t flagsToSet)
616 {
617     osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
618     osa_status_t status              = KOSA_StatusSuccess;
619 
620     assert(eventHandle != NULL);
621 
622     if (TX_SUCCESS != tx_event_flags_set(&pEventStruct->handle, (ULONG)flagsToSet, TX_OR))
623     {
624         status = KOSA_StatusError;
625     }
626 
627     return status;
628 }
629 
630 /*FUNCTION**********************************************************************
631  *
632  * Function Name : OSA_EventClear
633  * Description   : Clear one or more event flags of an event object.
634  * Return        :KOSA_StatusSuccess if clear successfully, KOSA_StatusError if failed.
635  *
636  *END**************************************************************************/
OSA_EventClear(osa_event_handle_t eventHandle,osa_event_flags_t flagsToClear)637 osa_status_t OSA_EventClear(osa_event_handle_t eventHandle, osa_event_flags_t flagsToClear)
638 {
639     osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
640     osa_status_t status              = KOSA_StatusSuccess;
641 
642     assert(eventHandle != NULL);
643 
644     if (TX_SUCCESS != tx_event_flags_set(&pEventStruct->handle, (ULONG)~flagsToClear, TX_AND))
645     {
646         status = KOSA_StatusError;
647     }
648 
649     return status;
650 }
651 
652 /*FUNCTION**********************************************************************
653  *
654  * Function Name : OSA_EventGet
655  * Description   : This function is used to get event's flags that specified by prameter
656  * flagsMask, and the flags (user specified) are obatianed by parameter pFlagsOfEvent. So
657  * you should pass the parameter 0xffffffff to specify you want to check all.
658  * Return        :KOSA_StatusSuccess if event flags were successfully got, KOSA_StatusError if failed.
659  *
660  *END**************************************************************************/
OSA_EventGet(osa_event_handle_t eventHandle,osa_event_flags_t flagsMask,osa_event_flags_t * pFlagsOfEvent)661 osa_status_t OSA_EventGet(osa_event_handle_t eventHandle, osa_event_flags_t flagsMask, osa_event_flags_t *pFlagsOfEvent)
662 {
663     osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
664     osa_status_t status              = KOSA_StatusSuccess;
665     ULONG flags;
666 
667     assert(eventHandle != NULL);
668 
669     if (NULL == pFlagsOfEvent)
670     {
671         return KOSA_StatusError;
672     }
673 
674     if (TX_SUCCESS != tx_event_flags_info_get(&pEventStruct->handle, NULL, &flags, NULL, NULL, NULL))
675     {
676         status = KOSA_StatusError;
677     }
678     else
679     {
680         *pFlagsOfEvent = (osa_event_flags_t)flags & flagsMask;
681     }
682 
683     return status;
684 }
685 
686 /*FUNCTION**********************************************************************
687  *
688  * Function Name : OSA_EventWait
689  * Description   : This function checks the event's status, if it meets the wait
690  * condition, return KOSA_StatusSuccess, otherwise, timeout will be used for
691  * wait. The parameter timeout indicates how long should wait in milliseconds.
692  * Pass osaWaitForever_c to wait indefinitely, pass 0 will return the value
693  * KOSA_StatusTimeout immediately if wait condition is not met. The event flags
694  * will be cleared if the event is auto clear mode. Flags that wakeup waiting
695  * task could be obtained from the parameter setFlags.
696  * This function returns KOSA_StatusSuccess if wait condition is met, returns
697  * KOSA_StatusTimeout if wait condition is not met within the specified
698  * 'timeout', returns KOSA_StatusError if any errors occur during waiting.
699  *
700  *END**************************************************************************/
OSA_EventWait(osa_event_handle_t eventHandle,osa_event_flags_t flagsToWait,uint8_t waitAll,uint32_t millisec,osa_event_flags_t * pSetFlags)701 osa_status_t OSA_EventWait(osa_event_handle_t eventHandle,
702                            osa_event_flags_t flagsToWait,
703                            uint8_t waitAll,
704                            uint32_t millisec,
705                            osa_event_flags_t *pSetFlags)
706 {
707     osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
708     uint32_t timeoutTicks;
709     osa_event_flags_t flagsSave;
710     UINT options = 0;
711     UINT status  = 0;
712 
713     assert(eventHandle != NULL);
714 
715     /* Clean FreeRTOS cotrol flags */
716     flagsToWait = flagsToWait & 0x00FFFFFFU;
717 
718     /* Convert timeout from millisecond to tick. */
719     if (millisec == osaWaitForever_c)
720     {
721         timeoutTicks = TX_WAIT_FOREVER;
722     }
723     else if (millisec == osaWaitNone_c)
724     {
725         timeoutTicks = TX_NO_WAIT;
726     }
727     else
728     {
729         timeoutTicks = MSEC_TO_TICK(millisec);
730     }
731 
732     if (1U == pEventStruct->autoClear)
733     {
734         options |= TX_EVENT_FLAGS_CLEAR_MASK;
735     }
736 
737     if (1U == waitAll)
738     {
739         options |= TX_EVENT_FLAGS_AND_MASK;
740     }
741 
742     status = tx_event_flags_get(&pEventStruct->handle, flagsToWait, options, (ULONG *)&flagsSave, timeoutTicks);
743     if (status != TX_SUCCESS && status != TX_NO_EVENTS)
744     {
745         return KOSA_StatusError;
746     }
747 
748     flagsSave &= (osa_event_flags_t)flagsToWait;
749 
750     if (NULL != pSetFlags)
751     {
752         *pSetFlags = (osa_event_flags_t)flagsSave;
753     }
754 
755     if (0U != flagsSave)
756     {
757         return KOSA_StatusSuccess;
758     }
759     else
760     {
761         return KOSA_StatusTimeout;
762     }
763 }
764 
765 /*FUNCTION**********************************************************************
766  *
767  * Function Name : OSA_EventDestroy
768  * Description   : This function is used to destroy a event object. Return
769  * KOSA_StatusSuccess if the event object is destroyed successfully, otherwise
770  * return KOSA_StatusError.
771  *
772  *END**************************************************************************/
OSA_EventDestroy(osa_event_handle_t eventHandle)773 osa_status_t OSA_EventDestroy(osa_event_handle_t eventHandle)
774 {
775     osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
776     osa_status_t status              = KOSA_StatusSuccess;
777 
778     assert(eventHandle != NULL);
779 
780     if (TX_SUCCESS != tx_event_flags_delete(&pEventStruct->handle))
781     {
782         status = KOSA_StatusError;
783     }
784 
785     return status;
786 }
787 
788 /*FUNCTION**********************************************************************
789  *
790  * Function Name : OSA_InterruptEnable
791  * Description   : self explanatory.
792  *
793  *END**************************************************************************/
OSA_InterruptEnable(void)794 void OSA_InterruptEnable(void)
795 {
796 #if 0
797     if (0U != __get_IPSR())
798     {
799         if (1 == s_osaState.basePriorityNesting)
800         {
801             portCLEAR_INTERRUPT_MASK_FROM_ISR(s_osaState.basePriority);
802         }
803 
804         if (s_osaState.basePriorityNesting > 0)
805         {
806             s_osaState.basePriorityNesting--;
807         }
808     }
809     else
810     {
811         portEXIT_CRITICAL();
812     }
813 #endif
814 }
815 
816 /*FUNCTION**********************************************************************
817  *
818  * Function Name : OSA_InterruptDisable
819  * Description   : self explanatory.
820  *
821  *END**************************************************************************/
OSA_InterruptDisable(void)822 void OSA_InterruptDisable(void)
823 {
824 #if 0
825     if (0U != __get_IPSR())
826     {
827         if (0 == s_osaState.basePriorityNesting)
828         {
829             s_osaState.basePriority = portSET_INTERRUPT_MASK_FROM_ISR();
830         }
831         s_osaState.basePriorityNesting++;
832     }
833     else
834     {
835         portENTER_CRITICAL();
836     }
837 #endif
838 }
839 
840 /*FUNCTION**********************************************************************
841  *
842  * Function Name : OSA_EnableIRQGlobal
843  * Description   : enable interrupts using PRIMASK register.
844  *
845  *END**************************************************************************/
OSA_EnableIRQGlobal(void)846 void OSA_EnableIRQGlobal(void)
847 {
848     TX_RESTORE
849 }
850 
851 /*FUNCTION**********************************************************************
852  *
853  * Function Name : OSA_DisableIRQGlobal
854  * Description   : disable interrupts using PRIMASK register.
855  *
856  *END**************************************************************************/
OSA_DisableIRQGlobal(void)857 void OSA_DisableIRQGlobal(void)
858 {
859     TX_DISABLE
860 }
861 
862 /*FUNCTION**********************************************************************
863  *
864  * Function Name : OSA_InstallIntHandler
865  * Description   : This function is used to install interrupt handler.
866  *
867  *END**************************************************************************/
OSA_InstallIntHandler(uint32_t IRQNumber,void (* handler)(void))868 void OSA_InstallIntHandler(uint32_t IRQNumber, void (*handler)(void))
869 {
870 #if defined(__IAR_SYSTEMS_ICC__)
871     _Pragma("diag_suppress = Pm138")
872 #endif
873 #if defined(ENABLE_RAM_VECTOR_TABLE)
874         (void) InstallIRQHandler((IRQn_Type)IRQNumber, (uint32_t) * (uint32_t *)&handler);
875 #endif /* ENABLE_RAM_VECTOR_TABLE. */
876 #if defined(__IAR_SYSTEMS_ICC__)
877     _Pragma("diag_remark = PM138")
878 #endif
879 }
880