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