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 */