1 /*! *********************************************************************************
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017, 2019-2024 NXP
4  * All rights reserved.
5  *
6  *
7  * This is the source file for the OS Abstraction layer for Zephyr.
8  *
9  * SPDX-License-Identifier: BSD-3-Clause
10  ********************************************************************************** */
11 
12 #include "fsl_os_abstraction.h"
13 #include "fsl_os_abstraction_zephyr.h"
14 
15 #include <string.h>
16 #include <zephyr/kernel.h>
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 
22 #define OSA_RETURN_IF_HANDLE_IS_NULL(handlePtr, retVal) \
23     {                                                   \
24         if (handlePtr == NULL)                          \
25         {                                               \
26             OSA_ASSERT(false, "OSA Handle is NULL!");   \
27             return retVal;                              \
28         }                                               \
29     }
30 
31 #define OSA_RETURN_IF_IS_IN_ISR(retVal)                          \
32     {                                                            \
33         if (k_is_in_isr())                                       \
34         {                                                        \
35             OSA_ASSERT(false, "Cannot execute in isr routine!"); \
36             return retVal;                                       \
37         }                                                        \
38     }
39 
40 #define OSA_RETURN_IF_WRONG_CHECKMARK(checked, expected, retVal) \
41     {                                                            \
42         if (checked != expected)                                 \
43         {                                                        \
44             OSA_ASSERT(false, "Checkmark is not correct");       \
45             return retVal;                                       \
46         }                                                        \
47     }
48 
49 #define OSA_RETURN_IF_WAITING_IN_ISR(timeToWait, retVal)               \
50     {                                                                  \
51         if (k_is_in_isr() && timeToWait > 0)                           \
52         {                                                              \
53             OSA_ASSERT(false, "Cannot wait for event in ISR routine"); \
54             return retVal;                                             \
55         }                                                              \
56     }
57 
58 #ifndef CONFIG_OSA_DEBUG_ASSERT_ENABLED
59 /** Enable this macro to trigger assert on error */
60 #define CONFIG_OSA_DEBUG_ASSERT_ENABLED (0u)
61 #endif
62 
63 #if (CONFIG_OSA_DEBUG_ASSERT_ENABLED == 1)
64 #define OSA_ASSERT(condition, message, ...) __ASSERT(condition, message __VA_OPT__(, ) __VA_ARGS__)
65 #else
66 #define OSA_ASSERT(condition, message, ...)
67 #endif
68 
69 /*******************************************************************************
70  * Variables
71  ******************************************************************************/
72 
73 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
74 static sys_dlist_t s_OSA_TaskList = {0}; /*!< List of alive tasks. Used for binding Zephyr and OSA task handles. */
75 static bool s_OSA_IsInitialized   = false; /*!< Indicates whether OSA_Init() was called. */
76 #endif
77 
78 static uint32_t s_OSA_InterruptDisableCount = 0; /*!< Used for correct enabling/disabling IRQs based on call count. */
79 
80 const uint8_t gUseRtos_c = USE_RTOS; /*!< USE_RTOS = 0 for BareMetal and 1 for OS. */
81 
82 /*******************************************************************************
83  * Code - Helpers and static functions
84  ******************************************************************************/
85 
86 /**
87  * @brief Coverts timeout in OSA's data type into Zephyr's data type
88  *
89  * @param timeout_ms Input time to be converted in ms
90  * @return k_timeout_t Output time in Zephyr's data type
91  */
s_OSA_ConvertTimeoutToZephyr(uint32_t timeout_ms)92 static k_timeout_t s_OSA_ConvertTimeoutToZephyr(uint32_t timeout_ms)
93 {
94     switch (timeout_ms)
95     {
96         case osaWaitNone_c:
97             return K_NO_WAIT;
98         case osaWaitForever_c:
99             return K_FOREVER;
100         default:
101             return K_MSEC(timeout_ms);
102     }
103 }
104 
105 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
106 /*!
107  * @brief Converts task priority from OSA format to Zephyr format
108  *
109  * @param taskPriority_osa OSA task priority
110  * @return task priority in Zephyr format
111  *
112  * uint16_t is converted into int16_t. Be aware, if result is negative, thread
113  * will become cooperative thread. See Zephyr's docu related to cooperative threads.
114  */
s_OSA_ConvertTaskPriorityFromOsaToZephyr(osa_task_priority_t taskPriority_osa)115 static int s_OSA_ConvertTaskPriorityFromOsaToZephyr(osa_task_priority_t taskPriority_osa)
116 {
117     int taskPriority_zephyr = (int)(int16_t)taskPriority_osa;
118 
119     return taskPriority_zephyr;
120 }
121 #endif /* (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) */
122 
123 /*!
124  * @brief Wrapper - Translates one argument API into three arguments API
125  *
126  * @param p1 Function pointer to the task body function
127  * @param p2 Argument to the task body function
128  * @param p3 Thread custom data or NULL
129 
130  OSA API supports task body function which takes only one argument.
131  Zephyr API supports task body function which takes three arguments.
132  When creating task using OSA we must somehow ensure the translation.
133  This is helper function which does the job. Zephyrs task enters this
134  function (with 3 arguments) and jumps on function stored in p1 with
135  arguments stored in p2 afterwards.
136  */
s_OSA_TaskCallback(void * p1,void * p2,void * p3)137 void s_OSA_TaskCallback(void *p1, void *p2, void *p3)
138 {
139     /* Save thread data */
140 #ifdef CONFIG_THREAD_CUSTOM_DATA
141     k_thread_custom_data_set(p3);
142 #endif
143 
144     void (*taskBodyFunction)(void *taskArgs) = p1;
145 
146     taskBodyFunction(p2);
147 }
148 
149 /*******************************************************************************
150  * Code - System API
151  ******************************************************************************/
152 
OSA_MemoryAllocate(uint32_t memLength)153 void *OSA_MemoryAllocate(uint32_t memLength)
154 {
155     /* Allocating on the System Heap */
156     void *p = k_malloc(memLength);
157 
158     if (p != NULL)
159     {
160         (void)memset(p, 0, memLength);
161     }
162 
163     return p;
164 }
165 
OSA_MemoryFree(void * p)166 void OSA_MemoryFree(void *p)
167 {
168     if (p != NULL)
169     {
170         k_free(p);
171     }
172 }
173 
OSA_MemoryAllocateAlign(uint32_t memLength,uint32_t alignbytes)174 void *OSA_MemoryAllocateAlign(uint32_t memLength, uint32_t alignbytes)
175 {
176     /* Allocating on the System Heap */
177     void *p = k_aligned_alloc(alignbytes, memLength);
178 
179     if (p != NULL)
180     {
181         (void)memset(p, 0, memLength);
182     }
183 
184     return p;
185 }
186 
OSA_MemoryFreeAlign(void * p)187 void OSA_MemoryFreeAlign(void *p)
188 {
189     if (p != NULL)
190     {
191         k_free(p);
192     }
193 }
194 
OSA_EnterCritical(uint32_t * sr)195 void OSA_EnterCritical(uint32_t *sr)
196 {
197     OSA_ASSERT(sr != NULL, "Critical section counter pointer is NULL\r\n");
198 
199     *sr = irq_lock();
200 }
201 
OSA_ExitCritical(uint32_t sr)202 void OSA_ExitCritical(uint32_t sr)
203 {
204     irq_unlock(sr);
205 }
206 
207 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
208 /**
209  * @brief OSA initialization.
210  *
211  * This function has to be called once before calling any task API.
212  *
213  * Currently it initializes only things related to Task API (currently nothing more to initialize).
214  * Warning: If OSA_Init is not explicitely called, initialization is called inside OSA_TaskCreate,
215  *          ensuring OSA Task API will work correctly.
216  */
OSA_Init(void)217 void OSA_Init(void)
218 {
219     OSA_InterruptDisable();
220 
221     if(s_OSA_IsInitialized != true)
222     {
223         sys_dlist_init(&s_OSA_TaskList);
224     #if 0
225         // Initialization to 0 should be done automatically since it is static varriable
226         s_OSA_InterruptDisableCount = 0;
227     #endif
228         s_OSA_IsInitialized = true;
229     }
230 
231     OSA_InterruptEnable();
232 }
233 #endif
234 
235 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
236 /**
237  * Warning: Function OSA_Start without effect. Scheduler started automatically in Zephyr.
238  */
OSA_Start(void)239 void OSA_Start(void)
240 {
241 }
242 #endif
243 
OSA_InterruptEnable(void)244 void OSA_InterruptEnable(void)
245 {
246     __enable_irq();
247 }
248 
OSA_InterruptDisable(void)249 void OSA_InterruptDisable(void)
250 {
251     __disable_irq();
252 }
253 
OSA_EnableIRQGlobal(void)254 void OSA_EnableIRQGlobal(void)
255 {
256     if (s_OSA_InterruptDisableCount > 0U)
257     {
258         s_OSA_InterruptDisableCount--;
259 
260         if (0U == s_OSA_InterruptDisableCount)
261         {
262             __enable_irq();
263         }
264         /* call core API to enable the global interrupt*/
265     }
266 }
267 
OSA_DisableIRQGlobal(void)268 void OSA_DisableIRQGlobal(void)
269 {
270     /* call core API to disable the global interrupt*/
271     __disable_irq();
272 
273     /* update counter*/
274     s_OSA_InterruptDisableCount++;
275 }
276 
277 /*!
278  * Prevents scheduler for scheduling out currently running task.
279  */
OSA_DisableScheduler(void)280 void OSA_DisableScheduler(void)
281 {
282     k_sched_lock();
283 }
284 
285 /*!
286  * Enables scheduler for scheduling out currently running task.
287  */
OSA_EnableScheduler(void)288 void OSA_EnableScheduler(void)
289 {
290     k_sched_unlock();
291 }
292 
OSA_TimeDelay(uint32_t millisec)293 void OSA_TimeDelay(uint32_t millisec)
294 {
295     k_msleep(millisec);
296 }
297 
298 /**
299  * Time overflows after ~8 years of continuous usage.
300  */
OSA_TimeGetMsec(void)301 uint32_t OSA_TimeGetMsec(void)
302 {
303     return k_uptime_get_32();
304 }
305 
306 /**
307  * Function OSA_InstallIntHandler currently not supported.
308  */
OSA_InstallIntHandler(uint32_t IRQNumber,void (* handler)(void))309 void OSA_InstallIntHandler(uint32_t IRQNumber, void (*handler)(void))
310 {
311     OSA_ASSERT(false, "Function %s not implemented/supported", __FUNCTION__);
312 }
313 
314 /*******************************************************************************
315  * Code - Thread API
316  ******************************************************************************/
317 
318 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
319 /**
320  * Warning: Unused following variables in thread_def: tlink, useFloat, instances.
321  *
322  * Calls also OSA_Init if it wasn't called explicitely before to ensure OSA Task API
323  * works correctly. Please see OSA_Init().
324  */
OSA_TaskCreate(osa_task_handle_t taskHandle,const osa_task_def_t * thread_def,osa_task_param_t task_param)325 osa_status_t OSA_TaskCreate(osa_task_handle_t taskHandle, const osa_task_def_t *thread_def, osa_task_param_t task_param)
326 {
327     osa_zephyr_taskHandle_t *z_taskHandle = (osa_zephyr_taskHandle_t *)taskHandle;
328 
329     OSA_RETURN_IF_IS_IN_ISR(KOSA_StatusError)
330     OSA_RETURN_IF_HANDLE_IS_NULL(z_taskHandle, KOSA_StatusError)
331 
332     (void)memset(z_taskHandle, 0, OSA_TASK_HANDLE_SIZE);
333 
334     OSA_Init();
335 
336     /* Converting from uint16_t OSA format into Zephyr's priority format */
337     int taskPriority = s_OSA_ConvertTaskPriorityFromOsaToZephyr(thread_def->tpriority);
338 
339     if (thread_def->stacksize == 0)
340     {
341         OSA_ASSERT(false, "Stack size is less or equall 0!\r\n");
342         return KOSA_StatusError;
343     }
344 
345     OSA_InterruptDisable();
346 
347     /* init semaphore before create thread to avoid restart thread getting semaphore unexpectedly */
348     if (k_sem_init(&z_taskHandle->notification, 0, 1) != 0)
349     {
350         OSA_ASSERT(false, "Could not create notification semaphore!\r\n");
351         return KOSA_StatusError;
352     }
353 
354     z_taskHandle->stackPtr = (k_thread_stack_t *) thread_def->tstack;
355 
356     /* Create a task */
357     z_taskHandle->handle =
358         k_thread_create(&z_taskHandle->controlBlock, (k_thread_stack_t *)z_taskHandle->stackPtr,
359                         thread_def->stacksize, s_OSA_TaskCallback, (void *)thread_def->pthread, (void *)task_param,
360                         &(z_taskHandle->controlBlock), taskPriority, 0, K_NO_WAIT);
361     if (z_taskHandle->handle == NULL)
362     {
363         OSA_ASSERT(false, "Task handle was not created!\r\n");
364         OSA_InterruptEnable();
365         return KOSA_StatusError;
366     }
367 
368     if (thread_def->tname != NULL)
369     {
370         k_thread_name_set(z_taskHandle->handle, thread_def->tname);
371     }
372 
373     if(s_OSA_IsInitialized == true)
374     {
375         sys_dlist_append(&s_OSA_TaskList, &(z_taskHandle->listNode));
376     }
377 
378     z_taskHandle->checkmark = OSA_CHECKMARK_TASK;
379 
380     OSA_InterruptEnable();
381 
382     return KOSA_StatusSuccess;
383 }
384 #endif /* (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) */
385 
386 #if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskDestroy(osa_task_handle_t taskHandle)387 osa_status_t OSA_TaskDestroy(osa_task_handle_t taskHandle)
388 {
389     osa_zephyr_taskHandle_t *z_taskHandle = (osa_zephyr_taskHandle_t *)taskHandle;
390 
391     OSA_RETURN_IF_HANDLE_IS_NULL(z_taskHandle, KOSA_StatusError)
392     OSA_RETURN_IF_WRONG_CHECKMARK(z_taskHandle->checkmark, OSA_CHECKMARK_TASK, KOSA_StatusError)
393 
394     k_thread_abort(z_taskHandle->handle);
395 
396     z_taskHandle->checkmark = OSA_CHECKMARK_EMPTY;
397 
398     k_sem_reset((struct k_sem *)&z_taskHandle->notification);
399 
400     /* Functions for link manipulation are not thread safe. */
401     OSA_InterruptDisable();
402     sys_dlist_remove(taskHandle);
403     OSA_InterruptEnable();
404 
405     return KOSA_StatusSuccess;
406 }
407 #endif /* FSL_OSA_TASK_ENABLE */
408 
409 #if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskYield(void)410 void OSA_TaskYield(void)
411 {
412     if (k_can_yield())
413     {
414         k_yield();
415     }
416 }
417 #endif /* FSL_OSA_TASK_ENABLE */
418 
419 #if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskGetCurrentHandle(void)420 osa_task_handle_t OSA_TaskGetCurrentHandle(void)
421 {
422     sys_dnode_t *list_element;
423     osa_zephyr_taskHandle_t *z_taskHandle;
424     k_tid_t currentThreadTid;
425 
426     OSA_RETURN_IF_IS_IN_ISR(NULL);
427 
428     if(s_OSA_IsInitialized != true)
429     {
430         OSA_ASSERT(false, "First initialize OSA by ccalling OSA_Init bbefore any task creation to be able to use this function correctly");
431         return NULL;
432     }
433 
434     if(sys_dlist_is_empty(&s_OSA_TaskList))
435     {
436         OSA_ASSERT(false, "Should never happen, unless function is called outside task.");
437         return NULL;
438     }
439 
440     currentThreadTid = k_current_get();
441     list_element = &s_OSA_TaskList;
442 
443     /* Functions for link manipulation are not thread safe. */
444     OSA_InterruptDisable();
445     do
446     {
447         list_element = sys_dlist_peek_next(&s_OSA_TaskList, list_element);
448         z_taskHandle = (osa_zephyr_taskHandle_t *)(void *)list_element;
449 
450         if(z_taskHandle->handle == currentThreadTid)
451         {
452             OSA_InterruptEnable();
453             return (osa_task_handle_t) z_taskHandle;
454         }
455     } while (! sys_dlist_is_tail(&s_OSA_TaskList, list_element));
456 
457     OSA_InterruptEnable();
458 
459     return NULL;
460 }
461 #endif /* FSL_OSA_TASK_ENABLE */
462 
463 #if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
464 #include <limits.h>
465 /*!
466  * Warning: Loss convertion. When priority is bigger or smaller than limits of int16,
467  * priority is set as SHRT_MAX or SHRT_MIN. Result is returned as uint16 (osa_task_priority_t).
468  */
OSA_TaskGetPriority(osa_task_handle_t taskHandle)469 osa_task_priority_t OSA_TaskGetPriority(osa_task_handle_t taskHandle)
470 {
471     osa_zephyr_taskHandle_t *z_taskHandle = (osa_zephyr_taskHandle_t *)taskHandle;
472 
473     OSA_RETURN_IF_HANDLE_IS_NULL(z_taskHandle, OSA_ZEPHYR_TASK_GET_PRIORITY_ERROR)
474     OSA_RETURN_IF_WRONG_CHECKMARK(z_taskHandle->checkmark, OSA_CHECKMARK_TASK, OSA_ZEPHYR_TASK_GET_PRIORITY_ERROR)
475 
476     int zephyr_taskPriority = k_thread_priority_get(z_taskHandle->handle);
477 
478     OSA_ASSERT((zephyr_taskPriority < SHRT_MAX && zephyr_taskPriority > SHRT_MIN), "Priority conversion loss");
479 
480     osa_task_priority_t osa_taskPriority;
481 
482     if (zephyr_taskPriority > SHRT_MAX)
483     {
484         osa_taskPriority = SHRT_MAX;
485     }
486     else if (zephyr_taskPriority < SHRT_MIN)
487     {
488         osa_taskPriority = (uint16_t)SHRT_MIN;
489     }
490     else
491     {
492         osa_taskPriority = (uint16_t)zephyr_taskPriority;
493     }
494 
495     return osa_taskPriority;
496 }
497 #endif /* FSL_OSA_TASK_ENABLE */
498 
499 #if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
500 /*!
501  * Warning: uint16_t is converted into int16_t and int afterwards. Be aware, if result is
502  * negative, thread will become cooperative thread. See Zephyr's docu related to cooperative threads.
503  */
OSA_TaskSetPriority(osa_task_handle_t taskHandle,osa_task_priority_t taskPriority)504 osa_status_t OSA_TaskSetPriority(osa_task_handle_t taskHandle, osa_task_priority_t taskPriority)
505 {
506     osa_zephyr_taskHandle_t *z_taskHandle = (osa_zephyr_taskHandle_t *)taskHandle;
507 
508     OSA_RETURN_IF_IS_IN_ISR(KOSA_StatusError)
509     OSA_RETURN_IF_HANDLE_IS_NULL(z_taskHandle, KOSA_StatusError)
510     OSA_RETURN_IF_WRONG_CHECKMARK(z_taskHandle->checkmark, OSA_CHECKMARK_TASK, KOSA_StatusError)
511 
512     int taskPrio_zephyr = s_OSA_ConvertTaskPriorityFromOsaToZephyr(taskPriority);
513 
514     k_thread_priority_set(z_taskHandle->handle, taskPrio_zephyr);
515 
516     return KOSA_StatusSuccess;
517 }
518 #endif /* FSL_OSA_TASK_ENABLE */
519 
520 /*******************************************************************************
521  * Code - Mutex API
522  ******************************************************************************/
523 
OSA_MutexCreate(osa_mutex_handle_t mutexHandle)524 osa_status_t OSA_MutexCreate(osa_mutex_handle_t mutexHandle)
525 {
526     osa_zephyr_mutexHandle_t *z_mutexHandle = mutexHandle;
527 
528     OSA_RETURN_IF_IS_IN_ISR(KOSA_StatusError)
529     OSA_RETURN_IF_HANDLE_IS_NULL(z_mutexHandle, KOSA_StatusError)
530 
531     if (k_mutex_init(&z_mutexHandle->handle) != 0)
532     {
533         return KOSA_StatusError;
534     }
535 
536     z_mutexHandle->checkmark = OSA_CHECKMARK_MUTEX;
537 
538     return KOSA_StatusSuccess;
539 }
540 
OSA_MutexLock(osa_mutex_handle_t mutexHandle,uint32_t millisec)541 osa_status_t OSA_MutexLock(osa_mutex_handle_t mutexHandle, uint32_t millisec)
542 {
543     osa_zephyr_mutexHandle_t *z_mutexHandle = mutexHandle;
544 
545     OSA_RETURN_IF_IS_IN_ISR(KOSA_StatusError)
546     OSA_RETURN_IF_HANDLE_IS_NULL(z_mutexHandle, KOSA_StatusError)
547     OSA_RETURN_IF_WRONG_CHECKMARK(z_mutexHandle->checkmark, OSA_CHECKMARK_MUTEX, KOSA_StatusError)
548 
549     int retVal = k_mutex_lock(&z_mutexHandle->handle, s_OSA_ConvertTimeoutToZephyr(millisec));
550     switch (retVal)
551     {
552         case -EBUSY:
553             return KOSA_StatusTimeout;
554         case -EAGAIN:
555             return KOSA_StatusTimeout;
556         case 0:
557             return KOSA_StatusSuccess; /* Mutex locked */
558         default:
559             return KOSA_StatusError;
560     }
561 
562     return KOSA_StatusError;
563 }
564 
OSA_MutexUnlock(osa_mutex_handle_t mutexHandle)565 osa_status_t OSA_MutexUnlock(osa_mutex_handle_t mutexHandle)
566 {
567     osa_zephyr_mutexHandle_t *z_mutexHandle = mutexHandle;
568 
569     OSA_RETURN_IF_IS_IN_ISR(KOSA_StatusError)
570     OSA_RETURN_IF_HANDLE_IS_NULL(z_mutexHandle, KOSA_StatusError)
571     OSA_RETURN_IF_WRONG_CHECKMARK(z_mutexHandle->checkmark, OSA_CHECKMARK_MUTEX, KOSA_StatusError)
572 
573     int retVal = k_mutex_unlock(&z_mutexHandle->handle);
574     switch (retVal)
575     {
576         case 0:
577             return KOSA_StatusSuccess;
578         case -EPERM:
579             return KOSA_StatusError;
580         case -EINVAL:
581             return KOSA_StatusError; /* Mutex is not locked */
582         default:
583             return KOSA_StatusError;
584     }
585 
586     return KOSA_StatusError;
587 }
588 
589 /**
590  * WARNING: API does not ensure there is none task waiting in mutexe's queue when function for
591  * destroying is called.
592  */
OSA_MutexDestroy(osa_mutex_handle_t mutexHandle)593 osa_status_t OSA_MutexDestroy(osa_mutex_handle_t mutexHandle)
594 {
595     /* Zephyr does not have any function for destroying the mutex */
596     osa_zephyr_mutexHandle_t *z_mutexHandle = mutexHandle;
597 
598     OSA_RETURN_IF_IS_IN_ISR(KOSA_StatusError)
599     OSA_RETURN_IF_HANDLE_IS_NULL(z_mutexHandle, KOSA_StatusError)
600     OSA_RETURN_IF_WRONG_CHECKMARK(z_mutexHandle->checkmark, OSA_CHECKMARK_MUTEX, KOSA_StatusError)
601 
602     z_mutexHandle->checkmark = OSA_CHECKMARK_EMPTY;
603 
604     return KOSA_StatusSuccess;
605 }
606 
607 /*******************************************************************************
608  * Code - Event API
609  ******************************************************************************/
610 
611 #ifdef CONFIG_EVENTS
612 
OSA_EventCreate(osa_event_handle_t eventHandle,uint8_t autoClear)613 osa_status_t OSA_EventCreate(osa_event_handle_t eventHandle, uint8_t autoClear)
614 {
615     osa_zephyr_eventHandle_t *z_eventHandle = (osa_zephyr_eventHandle_t *)eventHandle;
616 
617     OSA_RETURN_IF_IS_IN_ISR(KOSA_StatusError)
618     OSA_RETURN_IF_HANDLE_IS_NULL(z_eventHandle, KOSA_StatusError)
619 
620     k_event_init(&z_eventHandle->handle);
621     z_eventHandle->is_autoClear = (bool)autoClear;
622 
623     z_eventHandle->checkmark = OSA_CHECKMARK_EVENT;
624 
625     return KOSA_StatusSuccess;
626 }
627 
OSA_EventSet(osa_event_handle_t eventHandle,osa_event_flags_t flagsToSet)628 osa_status_t OSA_EventSet(osa_event_handle_t eventHandle, osa_event_flags_t flagsToSet)
629 {
630     osa_zephyr_eventHandle_t *z_eventHandle = (osa_zephyr_eventHandle_t *)eventHandle;
631 
632     OSA_RETURN_IF_HANDLE_IS_NULL(z_eventHandle, KOSA_StatusError)
633     OSA_RETURN_IF_WRONG_CHECKMARK(z_eventHandle->checkmark, OSA_CHECKMARK_EVENT, KOSA_StatusError)
634 
635     k_event_post(&z_eventHandle->handle, flagsToSet);
636 
637     return KOSA_StatusSuccess;
638 }
639 
OSA_EventWait(osa_event_handle_t eventHandle,osa_event_flags_t flagsToWait,uint8_t waitAll,uint32_t millisec,osa_event_flags_t * pSetFlags)640 osa_status_t OSA_EventWait(osa_event_handle_t eventHandle,
641                            osa_event_flags_t flagsToWait,
642                            uint8_t waitAll,
643                            uint32_t millisec,
644                            osa_event_flags_t *pSetFlags)
645 {
646     osa_zephyr_eventHandle_t *z_eventHandle = (osa_zephyr_eventHandle_t *)eventHandle;
647 
648     OSA_RETURN_IF_HANDLE_IS_NULL(z_eventHandle, KOSA_StatusError)
649     OSA_RETURN_IF_WAITING_IN_ISR(millisec, KOSA_StatusError)
650     OSA_RETURN_IF_WRONG_CHECKMARK(z_eventHandle->checkmark, OSA_CHECKMARK_EVENT, KOSA_StatusError)
651 
652     osa_event_flags_t setFlags = 0;
653     bool isTimeouted           = false;
654 
655     if (waitAll)
656     {
657         setFlags =
658             k_event_wait_all(&z_eventHandle->handle, flagsToWait, false, s_OSA_ConvertTimeoutToZephyr(millisec));
659     }
660     else
661     {
662         setFlags = k_event_wait(&z_eventHandle->handle, flagsToWait, false, s_OSA_ConvertTimeoutToZephyr(millisec));
663     }
664 
665     isTimeouted = (setFlags == 0) ? true : false;
666 
667     if(isTimeouted)
668     {
669         return KOSA_StatusTimeout;
670     }
671 
672     // Means it was not timeouted as well
673     if (z_eventHandle->is_autoClear)
674     {
675         (void)k_event_clear(&z_eventHandle->handle, setFlags);
676     }
677 
678     if (NULL != pSetFlags)
679     {
680         *pSetFlags = (osa_event_flags_t)setFlags;
681     }
682 
683     return KOSA_StatusSuccess;
684 }
685 
686 /**
687  * WARNING: API does not ensure there is none task waiting for Event when
688  * destroying is made.
689  */
OSA_EventDestroy(osa_event_handle_t eventHandle)690 osa_status_t OSA_EventDestroy(osa_event_handle_t eventHandle)
691 {
692     osa_zephyr_eventHandle_t *z_eventHandle = (osa_zephyr_eventHandle_t *)eventHandle;
693 
694     OSA_RETURN_IF_IS_IN_ISR(KOSA_StatusError)
695     OSA_RETURN_IF_HANDLE_IS_NULL(z_eventHandle, KOSA_StatusError)
696     OSA_RETURN_IF_WRONG_CHECKMARK(z_eventHandle->checkmark, OSA_CHECKMARK_EVENT, KOSA_StatusError)
697 
698     z_eventHandle->checkmark = OSA_CHECKMARK_EMPTY;
699 
700     return KOSA_StatusSuccess;
701 }
702 
OSA_EventPrecreate(osa_event_handle_t eventHandle,osa_task_ptr_t taskHandler)703 osa_status_t OSA_EventPrecreate(osa_event_handle_t eventHandle, osa_task_ptr_t taskHandler)
704 {
705     eventHandle = eventHandle;
706     taskHandler = taskHandler;
707 
708     return KOSA_StatusSuccess;
709 }
710 
OSA_EventClear(osa_event_handle_t eventHandle,osa_event_flags_t flagsToClear)711 osa_status_t OSA_EventClear(osa_event_handle_t eventHandle, osa_event_flags_t flagsToClear)
712 {
713     osa_zephyr_eventHandle_t *z_eventHandle = (osa_zephyr_eventHandle_t *)eventHandle;
714 
715     OSA_RETURN_IF_HANDLE_IS_NULL(z_eventHandle, KOSA_StatusError)
716     OSA_RETURN_IF_WRONG_CHECKMARK(z_eventHandle->checkmark, OSA_CHECKMARK_EVENT, KOSA_StatusError)
717 
718     k_event_clear(&z_eventHandle->handle, flagsToClear);
719 
720     return KOSA_StatusSuccess;
721 }
722 
OSA_EventGet(osa_event_handle_t eventHandle,osa_event_flags_t flagsMask,osa_event_flags_t * pFlagsOfEvent)723 osa_status_t OSA_EventGet(osa_event_handle_t eventHandle, osa_event_flags_t flagsMask, osa_event_flags_t *pFlagsOfEvent)
724 {
725     osa_zephyr_eventHandle_t *z_eventHandle = (osa_zephyr_eventHandle_t *)eventHandle;
726 
727     OSA_RETURN_IF_HANDLE_IS_NULL(z_eventHandle, KOSA_StatusError)
728     OSA_RETURN_IF_WRONG_CHECKMARK(z_eventHandle->checkmark, OSA_CHECKMARK_EVENT, KOSA_StatusError)
729 
730     if (pFlagsOfEvent == NULL)
731     {
732         OSA_ASSERT(false, "OSA Events flag pointer is NULL\r\n");
733         return KOSA_StatusError;
734     }
735 
736     *pFlagsOfEvent = k_event_test(&z_eventHandle->handle, flagsMask);
737 
738     return KOSA_StatusSuccess;
739 }
740 
741 #else // CONFIG_EVENTS not defined
742 
OSA_EventCreate(osa_event_handle_t eventHandle,uint8_t autoClear)743 osa_status_t OSA_EventCreate(osa_event_handle_t eventHandle, uint8_t autoClear)
744 {
745     return KOSA_StatusError;
746 }
747 
OSA_EventSet(osa_event_handle_t eventHandle,osa_event_flags_t flagsToSet)748 osa_status_t OSA_EventSet(osa_event_handle_t eventHandle, osa_event_flags_t flagsToSet)
749 {
750     return KOSA_StatusError;
751 }
752 
OSA_EventWait(osa_event_handle_t eventHandle,osa_event_flags_t flagsToWait,uint8_t waitAll,uint32_t millisec,osa_event_flags_t * pSetFlags)753 osa_status_t OSA_EventWait(osa_event_handle_t eventHandle,
754                            osa_event_flags_t flagsToWait,
755                            uint8_t waitAll,
756                            uint32_t millisec,
757                            osa_event_flags_t *pSetFlags)
758 {
759     return KOSA_StatusError;
760 }
761 
OSA_EventDestroy(osa_event_handle_t eventHandle)762 osa_status_t OSA_EventDestroy(osa_event_handle_t eventHandle)
763 {
764     return KOSA_StatusError;
765 }
766 
OSA_EventPrecreate(osa_event_handle_t eventHandle,osa_task_ptr_t taskHandler)767 osa_status_t OSA_EventPrecreate(osa_event_handle_t eventHandle, osa_task_ptr_t taskHandler)
768 {
769     return KOSA_StatusError;
770 }
771 
OSA_EventClear(osa_event_handle_t eventHandle,osa_event_flags_t flagsToClear)772 osa_status_t OSA_EventClear(osa_event_handle_t eventHandle, osa_event_flags_t flagsToClear)
773 {
774     return KOSA_StatusError;
775 }
776 
OSA_EventGet(osa_event_handle_t eventHandle,osa_event_flags_t flagsMask,osa_event_flags_t * pFlagsOfEvent)777 osa_status_t OSA_EventGet(osa_event_handle_t eventHandle, osa_event_flags_t flagsMask, osa_event_flags_t *pFlagsOfEvent)
778 {
779     return KOSA_StatusError;
780 }
781 
782 #endif // CONFIG_EVENTS
783 
784 /*******************************************************************************
785  * Code - Message queue API
786  ******************************************************************************/
787 
OSA_MsgQCreate(osa_msgq_handle_t msgqHandle,uint32_t msgNo,uint32_t msgSize)788 osa_status_t OSA_MsgQCreate(osa_msgq_handle_t msgqHandle, uint32_t msgNo, uint32_t msgSize)
789 {
790     osa_zephyr_msgQueueHandle_t *z_msgqHandle = (osa_zephyr_msgQueueHandle_t *)msgqHandle;
791     uint32_t bufferSize_B                     = (msgNo * msgSize);
792     uint8_t *buffer_addr                      = (uint8_t *)((uint8_t *)msgqHandle + OSA_MSGQ_HANDLE_SIZE);
793 
794     OSA_RETURN_IF_HANDLE_IS_NULL(z_msgqHandle, KOSA_StatusError)
795 
796     if (bufferSize_B == 0)
797     {
798         OSA_ASSERT(false, "Allocated buffer size must be bigger than 0.\r\n");
799         return KOSA_StatusError;
800     }
801 
802     k_msgq_init(&z_msgqHandle->handle, buffer_addr, msgSize, msgNo);
803     z_msgqHandle->checkmark = OSA_CHECKMARK_MSGQ;
804 
805     return KOSA_StatusSuccess;
806 }
807 
OSA_MsgQPut(osa_msgq_handle_t msgqHandle,osa_msg_handle_t pMessage)808 osa_status_t OSA_MsgQPut(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage)
809 {
810     osa_zephyr_msgQueueHandle_t *z_msgqHandle = (osa_zephyr_msgQueueHandle_t *)msgqHandle;
811 
812     OSA_RETURN_IF_HANDLE_IS_NULL(z_msgqHandle, KOSA_StatusError)
813     OSA_RETURN_IF_WRONG_CHECKMARK(z_msgqHandle->checkmark, OSA_CHECKMARK_MSGQ, KOSA_StatusError)
814 
815     int retVal = k_msgq_put(&z_msgqHandle->handle, pMessage, K_NO_WAIT);
816 
817     switch (retVal)
818     {
819         case 0:
820             return KOSA_StatusSuccess;
821         case -ENOMSG:
822             return KOSA_StatusError;
823         case -EAGAIN:
824             return KOSA_StatusTimeout;
825         default:
826             return KOSA_StatusError;
827     }
828 
829     return KOSA_StatusError;
830 }
831 
OSA_MsgQGet(osa_msgq_handle_t msgqHandle,osa_msg_handle_t pMessage,uint32_t millisec)832 osa_status_t OSA_MsgQGet(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage, uint32_t millisec)
833 {
834     osa_zephyr_msgQueueHandle_t *z_msgqHandle = (osa_zephyr_msgQueueHandle_t *)msgqHandle;
835 
836     OSA_RETURN_IF_WAITING_IN_ISR(millisec, KOSA_StatusError)
837     OSA_RETURN_IF_HANDLE_IS_NULL(z_msgqHandle, KOSA_StatusError)
838     OSA_RETURN_IF_WRONG_CHECKMARK(z_msgqHandle->checkmark, OSA_CHECKMARK_MSGQ, KOSA_StatusError)
839 
840     int retVal = k_msgq_get(&z_msgqHandle->handle, pMessage, s_OSA_ConvertTimeoutToZephyr(millisec));
841     switch (retVal)
842     {
843         case 0:
844             return KOSA_StatusSuccess;
845         case -ENOMSG:
846             return KOSA_StatusError;
847         case -EAGAIN:
848             return KOSA_StatusTimeout;
849         default:
850             return KOSA_StatusError;
851     }
852 
853     return KOSA_StatusError;
854 }
855 
OSA_MsgQDestroy(osa_msgq_handle_t msgqHandle)856 osa_status_t OSA_MsgQDestroy(osa_msgq_handle_t msgqHandle)
857 {
858     osa_zephyr_msgQueueHandle_t *z_msgqHandle = (osa_zephyr_msgQueueHandle_t *)msgqHandle;
859 
860     OSA_RETURN_IF_IS_IN_ISR(KOSA_StatusError)
861     OSA_RETURN_IF_HANDLE_IS_NULL(z_msgqHandle, KOSA_StatusError)
862     OSA_RETURN_IF_WRONG_CHECKMARK(z_msgqHandle->checkmark, OSA_CHECKMARK_MSGQ, KOSA_StatusError)
863 
864     k_msgq_purge(&z_msgqHandle->handle);
865 
866     z_msgqHandle->checkmark = OSA_CHECKMARK_EMPTY;
867 
868     return KOSA_StatusSuccess;
869 }
870 
OSA_MsgQAvailableMsgs(osa_msgq_handle_t msgqHandle)871 int OSA_MsgQAvailableMsgs(osa_msgq_handle_t msgqHandle)
872 {
873     osa_zephyr_msgQueueHandle_t *z_msgqHandle = (osa_zephyr_msgQueueHandle_t *)msgqHandle;
874     uint32_t message_number                   = 0;
875 
876     OSA_RETURN_IF_HANDLE_IS_NULL(z_msgqHandle, 0)
877     OSA_RETURN_IF_WRONG_CHECKMARK(z_msgqHandle->checkmark, OSA_CHECKMARK_MSGQ, 0)
878 
879     message_number = k_msgq_num_used_get(&z_msgqHandle->handle);
880 
881     return message_number;
882 }
883 
884 /*******************************************************************************
885  * Code - Semaphore API
886  ******************************************************************************/
887 
OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle,uint32_t initValue)888 osa_status_t OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle, uint32_t initValue)
889 {
890     osa_zephyr_semHandle_t *z_semHandle = (osa_zephyr_semHandle_t *)semaphoreHandle;
891 
892     OSA_RETURN_IF_IS_IN_ISR(KOSA_StatusError)
893     OSA_RETURN_IF_HANDLE_IS_NULL(z_semHandle, KOSA_StatusError)
894 
895     if (k_sem_init(&(z_semHandle->handle), initValue, K_SEM_MAX_LIMIT) != 0)
896     {
897         return KOSA_StatusError;
898     }
899 
900     z_semHandle->checkmark = OSA_CHECKMARK_SEM;
901 
902     return KOSA_StatusSuccess;
903 }
904 
OSA_SemaphoreCreateBinary(osa_semaphore_handle_t semaphoreHandle)905 osa_status_t OSA_SemaphoreCreateBinary(osa_semaphore_handle_t semaphoreHandle)
906 {
907     osa_zephyr_semHandle_t *z_semHandle = (osa_zephyr_semHandle_t *)semaphoreHandle;
908 
909     OSA_RETURN_IF_IS_IN_ISR(KOSA_StatusError)
910     OSA_RETURN_IF_HANDLE_IS_NULL(z_semHandle, KOSA_StatusError)
911 
912     if (k_sem_init(&(z_semHandle->handle), 0, 1) != 0)
913     {
914         return KOSA_StatusError;
915     }
916 
917     z_semHandle->checkmark = OSA_CHECKMARK_SEM;
918 
919     return KOSA_StatusSuccess;
920 }
921 
922 /**
923  * WARNING: API does not ensure there is none task waiting for semaphore when
924  * destroying is made.
925  */
OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle)926 osa_status_t OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle)
927 {
928     osa_zephyr_semHandle_t *z_semHandle = (osa_zephyr_semHandle_t *)semaphoreHandle;
929 
930     OSA_RETURN_IF_HANDLE_IS_NULL(z_semHandle, KOSA_StatusError)
931     OSA_RETURN_IF_WRONG_CHECKMARK(z_semHandle->checkmark, OSA_CHECKMARK_SEM, KOSA_StatusError)
932 
933     z_semHandle->checkmark = OSA_CHECKMARK_EMPTY;
934 
935     return KOSA_StatusSuccess;
936 }
937 
OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle,uint32_t millisec)938 osa_status_t OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle, uint32_t millisec)
939 {
940     osa_zephyr_semHandle_t *z_semHandle = (osa_zephyr_semHandle_t *)semaphoreHandle;
941 
942     OSA_RETURN_IF_WAITING_IN_ISR(millisec, KOSA_StatusError)
943     OSA_RETURN_IF_HANDLE_IS_NULL(z_semHandle, KOSA_StatusError)
944     OSA_RETURN_IF_WRONG_CHECKMARK(z_semHandle->checkmark, OSA_CHECKMARK_SEM, KOSA_StatusError)
945 
946     int retVal = k_sem_take(&(z_semHandle->handle), s_OSA_ConvertTimeoutToZephyr(millisec));
947     switch (retVal)
948     {
949         case -EBUSY:
950             return KOSA_StatusTimeout;
951         case -EAGAIN:
952             return KOSA_StatusTimeout;
953         case 0:
954             return KOSA_StatusSuccess;
955         default:
956             return KOSA_StatusError;
957     }
958 
959     return KOSA_StatusError;
960 }
961 
OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle)962 osa_status_t OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle)
963 {
964     osa_zephyr_semHandle_t *z_semHandle = (osa_zephyr_semHandle_t *)semaphoreHandle;
965 
966     OSA_RETURN_IF_HANDLE_IS_NULL(z_semHandle, KOSA_StatusError)
967     OSA_RETURN_IF_WRONG_CHECKMARK(z_semHandle->checkmark, OSA_CHECKMARK_SEM, KOSA_StatusError)
968 
969     k_sem_give(&(z_semHandle->handle));
970 
971     return KOSA_StatusSuccess;
972 }
973 
OSA_SemaphorePrecreate(osa_semaphore_handle_t semaphoreHandle,osa_task_ptr_t taskHandler)974 osa_status_t OSA_SemaphorePrecreate(osa_semaphore_handle_t semaphoreHandle, osa_task_ptr_t taskHandler)
975 {
976     semaphoreHandle = semaphoreHandle;
977     taskHandler     = taskHandler;
978 
979     return KOSA_StatusSuccess;
980 }
981 
OSA_SemaphoreGetCount(osa_semaphore_handle_t semaphoreHandle)982 osa_semaphore_count_t OSA_SemaphoreGetCount(osa_semaphore_handle_t semaphoreHandle)
983 {
984     osa_zephyr_semHandle_t *z_semHandle = (osa_zephyr_semHandle_t *)semaphoreHandle;
985     osa_semaphore_count_t semCount;
986 
987     OSA_RETURN_IF_HANDLE_IS_NULL(z_semHandle, 0)
988     OSA_RETURN_IF_WRONG_CHECKMARK(z_semHandle->checkmark, OSA_CHECKMARK_SEM, 0)
989 
990     semCount = (osa_semaphore_count_t) k_sem_count_get((struct k_sem *)&z_semHandle->handle);
991 
992     return semCount;
993 }
994 
995 /*******************************************************************************
996  * Code - Notifications
997  ******************************************************************************/
998 
999 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
OSA_TaskNotifyGet(osa_notify_time_ms_t waitTime_ms)1000 osa_status_t OSA_TaskNotifyGet(osa_notify_time_ms_t waitTime_ms)
1001 {
1002     OSA_RETURN_IF_IS_IN_ISR(KOSA_StatusError);
1003 
1004     osa_zephyr_taskHandle_t *z_taskHandle = OSA_TaskGetCurrentHandle();
1005 
1006     OSA_RETURN_IF_HANDLE_IS_NULL(z_taskHandle, KOSA_StatusError)
1007     OSA_RETURN_IF_WRONG_CHECKMARK(z_taskHandle->checkmark, OSA_CHECKMARK_TASK, KOSA_StatusError)
1008 
1009     int retVal = k_sem_take(&(z_taskHandle->notification), s_OSA_ConvertTimeoutToZephyr(waitTime_ms));
1010     switch (retVal)
1011     {
1012         case -EBUSY:
1013             return KOSA_StatusTimeout;
1014         case -EAGAIN:
1015             return KOSA_StatusTimeout;
1016         case 0:
1017             return KOSA_StatusSuccess;
1018         default:
1019             return KOSA_StatusError;
1020     }
1021 }
1022 
OSA_TaskNotifyPost(osa_task_handle_t taskHandle)1023 osa_status_t OSA_TaskNotifyPost(osa_task_handle_t taskHandle)
1024 {
1025     osa_zephyr_taskHandle_t *z_taskHandle = (osa_zephyr_taskHandle_t *)taskHandle;
1026 
1027     OSA_RETURN_IF_HANDLE_IS_NULL(z_taskHandle, KOSA_StatusError)
1028     OSA_RETURN_IF_WRONG_CHECKMARK(z_taskHandle->checkmark, OSA_CHECKMARK_TASK, KOSA_StatusError)
1029 
1030     k_sem_give(&z_taskHandle->notification);
1031 
1032     return KOSA_StatusSuccess;
1033 }
1034 #endif /* FSL_OSA_TASK_ENABLE */