1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020 NXP
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef _FSL_OS_ABSTRACTION_H_
10 #define _FSL_OS_ABSTRACTION_H_
11 
12 #ifndef SDK_COMPONENT_DEPENDENCY_FSL_COMMON
13 #define SDK_COMPONENT_DEPENDENCY_FSL_COMMON (1U)
14 #endif
15 #if (defined(SDK_COMPONENT_DEPENDENCY_FSL_COMMON) && (SDK_COMPONENT_DEPENDENCY_FSL_COMMON > 0U))
16 #include "fsl_common.h"
17 #else
18 #endif
19 
20 #include "fsl_os_abstraction_config.h"
21 #include "fsl_component_generic_list.h"
22 
23 /*!
24  * @addtogroup osa_adapter
25  * @{
26  */
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 /*******************************************************************************
33  * Definitions
34  ******************************************************************************/
35 
36 /*! @brief Type for the Task Priority*/
37 typedef uint16_t osa_task_priority_t;
38 /*! @brief Type for a task handler */
39 typedef void *osa_task_handle_t;
40 /*! @brief Type for the parameter to be passed to the task at its creation */
41 typedef void *osa_task_param_t;
42 /*! @brief Type for task pointer. Task prototype declaration */
43 typedef void (*osa_task_ptr_t)(osa_task_param_t task_param);
44 /*! @brief Type for the semaphore handler */
45 typedef void *osa_semaphore_handle_t;
46 /*! @brief Type for the mutex handler */
47 typedef void *osa_mutex_handle_t;
48 /*! @brief Type for the event handler */
49 typedef void *osa_event_handle_t;
50 /*! @brief Type for an event flags group, bit 32 is reserved. */
51 typedef uint32_t osa_event_flags_t;
52 /*! @brief Message definition. */
53 typedef void *osa_msg_handle_t;
54 /*! @brief Type for the message queue handler */
55 typedef void *osa_msgq_handle_t;
56 /*! @brief Type for the Timer handler */
57 typedef void *osa_timer_handle_t;
58 /*! @brief Type for the Timer callback function pointer. */
59 typedef void (*osa_timer_fct_ptr_t)(void const *argument);
60 /*! @brief Thread Definition structure contains startup information of a thread.*/
61 typedef struct osa_task_def_tag
62 {
63     osa_task_ptr_t pthread; /*!< start address of thread function*/
64     uint32_t tpriority;     /*!< initial thread priority*/
65     uint32_t instances;     /*!< maximum number of instances of that thread function*/
66     uint32_t stacksize;     /*!< stack size requirements in bytes; 0 is default stack size*/
67     uint32_t *tstack;       /*!< stack pointer*/
68     void *tlink;            /*!< link pointer*/
69     uint8_t *tname;         /*!< name pointer*/
70     uint8_t useFloat;       /*!< is use float*/
71 } osa_task_def_t;
72 /*! @brief Thread Link Definition structure .*/
73 typedef struct osa_thread_link_tag
74 {
75     uint8_t link[12];                  /*!< link*/
76     osa_task_handle_t osThreadId;      /*!< thread id*/
77     osa_task_def_t *osThreadDefHandle; /*!< pointer of thread define handle*/
78     uint32_t *osThreadStackHandle;     /*!< pointer of thread stack handle*/
79 } osa_thread_link_t, *osa_thread_link_handle_t;
80 
81 /*! @brief Definition structure contains timer parameters.*/
82 typedef struct osa_time_def_tag
83 {
84     osa_timer_fct_ptr_t pfCallback; /* < start address of a timer function */
85     void *argument;                 /* < argument of a timer function */
86 } osa_time_def_t;
87 
88 /*! @brief Type for the timer definition*/
89 typedef enum _osa_timer
90 {
91     KOSA_TimerOnce     = 0, /*!< one-shot timer*/
92     KOSA_TimerPeriodic = 1  /*!< repeating timer*/
93 } osa_timer_t;
94 
95 /*! @brief Defines the return status of OSA's functions */
96 #if (defined(SDK_COMPONENT_DEPENDENCY_FSL_COMMON) && (SDK_COMPONENT_DEPENDENCY_FSL_COMMON > 0U))
97 typedef enum _osa_status
98 {
99     KOSA_StatusSuccess = kStatus_Success,                  /*!< Success */
100     KOSA_StatusError   = MAKE_STATUS(kStatusGroup_OSA, 1), /*!< Failed */
101     KOSA_StatusTimeout = MAKE_STATUS(kStatusGroup_OSA, 2), /*!< Timeout occurs while waiting */
102     KOSA_StatusIdle    = MAKE_STATUS(kStatusGroup_OSA, 3), /*!< Used for bare metal only, the wait object is not ready
103                                                                  and timeout still not occur */
104 } osa_status_t;
105 #else
106 typedef enum _osa_status
107 {
108     KOSA_StatusSuccess = 0, /*!< Success */
109     KOSA_StatusError   = 1, /*!< Failed */
110     KOSA_StatusTimeout = 2, /*!< Timeout occurs while waiting */
111     KOSA_StatusIdle    = 3, /*!< Used for bare metal only, the wait object is not ready
112                                                 and timeout still not occur */
113 } osa_status_t;
114 
115 #endif
116 
117 #ifdef USE_RTOS
118 #undef USE_RTOS
119 #endif
120 
121 #if defined(SDK_OS_MQX)
122 #define USE_RTOS (1)
123 #elif defined(SDK_OS_FREE_RTOS)
124 #define USE_RTOS (1)
125 #if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
126 #define OSA_TASK_HANDLE_SIZE (12U)
127 #else
128 #define OSA_TASK_HANDLE_SIZE (16U)
129 #endif
130 #define OSA_EVENT_HANDLE_SIZE (8U)
131 #define OSA_SEM_HANDLE_SIZE   (4U)
132 #define OSA_MUTEX_HANDLE_SIZE (4U)
133 #define OSA_MSGQ_HANDLE_SIZE  (4U)
134 #define OSA_MSG_HANDLE_SIZE   (0U)
135 #elif defined(SDK_OS_UCOSII)
136 #define USE_RTOS (1)
137 #elif defined(SDK_OS_UCOSIII)
138 #define USE_RTOS (1)
139 #elif defined(FSL_RTOS_THREADX)
140 #define USE_RTOS (1)
141 #else
142 #define USE_RTOS (0)
143 #if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
144 #define OSA_TASK_HANDLE_SIZE (24U)
145 #else
146 #define OSA_TASK_HANDLE_SIZE (28U)
147 #endif
148 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
149 #define OSA_EVENT_HANDLE_SIZE (20U)
150 #else
151 #define OSA_EVENT_HANDLE_SIZE (16U)
152 #endif /* FSL_OSA_TASK_ENABLE */
153 #if (defined(FSL_OSA_BM_TIMEOUT_ENABLE) && (FSL_OSA_BM_TIMEOUT_ENABLE > 0U))
154 #define OSA_SEM_HANDLE_SIZE   (16U)
155 #define OSA_MUTEX_HANDLE_SIZE (12U)
156 #else
157 #define OSA_SEM_HANDLE_SIZE   (8U)
158 #define OSA_MUTEX_HANDLE_SIZE (4U)
159 #endif
160 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
161 #define OSA_MSGQ_HANDLE_SIZE (32U)
162 #else
163 #define OSA_MSGQ_HANDLE_SIZE (28U)
164 #endif /* FSL_OSA_TASK_ENABLE */
165 #define OSA_MSG_HANDLE_SIZE (4U)
166 #endif
167 
168 /*! @brief Priority setting for OSA. */
169 #ifndef OSA_PRIORITY_IDLE
170 #define OSA_PRIORITY_IDLE (6U)
171 #endif
172 
173 #ifndef OSA_PRIORITY_LOW
174 #define OSA_PRIORITY_LOW (5U)
175 #endif
176 
177 #ifndef OSA_PRIORITY_BELOW_NORMAL
178 #define OSA_PRIORITY_BELOW_NORMAL (4U)
179 #endif
180 
181 #ifndef OSA_PRIORITY_NORMAL
182 #define OSA_PRIORITY_NORMAL (3U)
183 #endif
184 
185 #ifndef OSA_PRIORITY_ABOVE_NORMAL
186 #define OSA_PRIORITY_ABOVE_NORMAL (2U)
187 #endif
188 
189 #ifndef OSA_PRIORITY_HIGH
190 #define OSA_PRIORITY_HIGH (1U)
191 #endif
192 
193 #ifndef OSA_PRIORITY_REAL_TIME
194 #define OSA_PRIORITY_REAL_TIME (0U)
195 #endif
196 
197 #ifndef OSA_TASK_PRIORITY_MAX
198 #define OSA_TASK_PRIORITY_MAX (0U)
199 #endif
200 
201 #ifndef OSA_TASK_PRIORITY_MIN
202 #define OSA_TASK_PRIORITY_MIN (15U)
203 #endif
204 
205 /*
206  * Converse the percent of the priority to the priority of the OSA.
207  * The the range of the parameter x is 0-100.
208  */
209 #define OSA_TASK_PRIORITY_PERCENT(x) ((((OSA_TASK_PRIORITY_MIN - OSA_TASK_PRIORITY_MAX) * (100 - (x))) / 100 ) + OSA_TASK_PRIORITY_MAX)
210 
211 #define SIZE_IN_UINT32_UNITS(size) (((size) + sizeof(uint32_t) - 1) / sizeof(uint32_t))
212 
213 /*! @brief Constant to pass as timeout value in order to wait indefinitely. */
214 #define osaWaitNone_c            ((uint32_t)(0))
215 #define osaWaitForever_c         ((uint32_t)(-1))
216 #define osaEventFlagsAll_c       ((osa_event_flags_t)(0x00FFFFFF))
217 #define osThreadStackArray(name) osThread_##name##_stack
218 #define osThreadStackDef(name, stacksize, instances) \
219     const uint32_t osThreadStackArray(name)[SIZE_IN_UINT32_UNITS(stacksize) * (instances)];
220 
221 /* ==== Thread Management ==== */
222 
223 /* Create a Thread Definition with function, priority, and stack requirements.
224  * \param         name         name of the thread function.
225  * \param         priority     initial priority of the thread function.
226  * \param         instances    number of possible thread instances.
227  * \param         stackSz      stack size (in bytes) requirements for the thread function.
228  * \param         useFloat
229  */
230 #if defined(SDK_OS_MQX)
231 #define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat)                                        \
232     osa_thread_link_t osThreadLink_##name[instances]                               = {0};                    \
233     osThreadStackDef(name, stackSz, instances) osa_task_def_t os_thread_def_##name = {                       \
234         (name),           (priority), (instances), (stackSz), osThreadStackArray(name), osThreadLink_##name, \
235         (uint8_t *)#name, (useFloat)}
236 #elif defined(SDK_OS_UCOSII)
237 #if gTaskMultipleInstancesManagement_c
238 #define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat)                                        \
239     osa_thread_link_t osThreadLink_##name[instances]                               = {0};                    \
240     osThreadStackDef(name, stackSz, instances) osa_task_def_t os_thread_def_##name = {                       \
241         (name),           (priority), (instances), (stackSz), osThreadStackArray(name), osThreadLink_##name, \
242         (uint8_t *)#name, (useFloat)}
243 #else
244 #define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat)                  \
245     osThreadStackDef(name, stackSz, instances) osa_task_def_t os_thread_def_##name = { \
246         (name), (priority), (instances), (stackSz), osThreadStackArray(name), NULL, (uint8_t *)#name, (useFloat)}
247 #endif
248 #elif defined(FSL_RTOS_THREADX)
249 #define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat)                   \
250     uint32_t s_stackBuffer##name[(stackSz + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]; \
251     static const osa_task_def_t os_thread_def_##name = {                                \
252         (name), (priority), (instances), (stackSz), s_stackBuffer##name, NULL, (uint8_t *)#name, (useFloat)}
253 #else
254 #define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat)                             \
255     const osa_task_def_t os_thread_def_##name = {(name), (priority), (instances),      (stackSz), \
256                                                  NULL,   NULL,       (uint8_t *)#name, (useFloat)}
257 #endif
258 /* Access a Thread defintion.
259  * \param         name          name of the thread definition object.
260  */
261 #define OSA_TASK(name) (const osa_task_def_t *)&os_thread_def_##name
262 
263 #define OSA_TASK_PROTO(name) extern osa_task_def_t os_thread_def_##name
264 /*  ==== Timer Management  ====
265  * Define a Timer object.
266  * \param         name          name of the timer object.
267  * \param         function      name of the timer call back function.
268  */
269 
270 #define OSA_TIMER_DEF(name, function) osa_time_def_t os_timer_def_##name = {(function), NULL}
271 
272 /* Access a Timer definition.
273  * \param         name          name of the timer object.
274  */
275 #define OSA_TIMER(name) &os_timer_def_##name
276 
277 /* ==== Buffer Definition ==== */
278 
279 /*!
280  * @brief Defines the semaphore handle
281  *
282  * This macro is used to define a 4 byte aligned semaphore handle.
283  * Then use "(osa_semaphore_handle_t)name" to get the semaphore handle.
284  *
285  * The macro should be global and could be optional. You could also define semaphore handle by yourself.
286  *
287  * This is an example,
288  * @code
289  *   OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle);
290  * @endcode
291  *
292  * @param name The name string of the semaphore handle.
293  */
294 #define OSA_SEMAPHORE_HANDLE_DEFINE(name) \
295     uint32_t name[(OSA_SEM_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
296 
297 /*!
298  * @brief Defines the mutex handle
299  *
300  * This macro is used to define a 4 byte aligned mutex handle.
301  * Then use "(osa_mutex_handle_t)name" to get the mutex handle.
302  *
303  * The macro should be global and could be optional. You could also define mutex handle by yourself.
304  *
305  * This is an example,
306  * @code
307  *   OSA_MUTEX_HANDLE_DEFINE(mutexHandle);
308  * @endcode
309  *
310  * @param name The name string of the mutex handle.
311  */
312 #define OSA_MUTEX_HANDLE_DEFINE(name) uint32_t name[(OSA_MUTEX_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
313 
314 /*!
315  * @brief Defines the event handle
316  *
317  * This macro is used to define a 4 byte aligned event handle.
318  * Then use "(osa_event_handle_t)name" to get the event handle.
319  *
320  * The macro should be global and could be optional. You could also define event handle by yourself.
321  *
322  * This is an example,
323  * @code
324  *   OSA_EVENT_HANDLE_DEFINE(eventHandle);
325  * @endcode
326  *
327  * @param name The name string of the event handle.
328  */
329 #define OSA_EVENT_HANDLE_DEFINE(name) uint32_t name[(OSA_EVENT_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
330 
331 /*!
332  * @brief Defines the message queue handle
333  *
334  * This macro is used to define a 4 byte aligned message queue handle.
335  * Then use "(osa_msgq_handle_t)name" to get the message queue handle.
336  *
337  * The macro should be global and could be optional. You could also define message queue handle by yourself.
338  *
339  * This is an example,
340  * @code
341  *   OSA_MSGQ_HANDLE_DEFINE(msgqHandle, 3, sizeof(msgStruct));
342  * @endcode
343  *
344  * @param name The name string of the message queue handle.
345  * @param numberOfMsgs Number of messages.
346  * @param msgSize Message size.
347  *
348  */
349 #if defined(SDK_OS_FREE_RTOS)
350 /*< Macro For FREE_RTOS*/
351 #define OSA_MSGQ_HANDLE_DEFINE(name, numberOfMsgs, msgSize) \
352     uint32_t name[(OSA_MSGQ_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
353 #else
354 /*< Macro For BARE_MATEL*/
355 #define OSA_MSGQ_HANDLE_DEFINE(name, numberOfMsgs, msgSize) \
356     uint32_t name[((OSA_MSGQ_HANDLE_SIZE + numberOfMsgs * msgSize) + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
357 #endif
358 
359 /*!
360  * @brief Defines the TASK handle
361  *
362  * This macro is used to define a 4 byte aligned TASK handle.
363  * Then use "(osa_task_handle_t)name" to get the TASK handle.
364  *
365  * The macro should be global and could be optional. You could also define TASK handle by yourself.
366  *
367  * This is an example,
368  * @code
369  *   OSA_TASK_HANDLE_DEFINE(taskHandle);
370  * @endcode
371  *
372  * @param name The name string of the TASK handle.
373  */
374 #define OSA_TASK_HANDLE_DEFINE(name) uint32_t name[(OSA_TASK_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
375 
376 #if defined(SDK_OS_FREE_RTOS)
377 #include "fsl_os_abstraction_free_rtos.h"
378 #elif defined(FSL_RTOS_THREADX)
379 #include "fsl_os_abstraction_threadx.h"
380 #else
381 #include "fsl_os_abstraction_bm.h"
382 #endif
383 
384 extern const uint8_t gUseRtos_c;
385 
386 #ifndef __DSB
387 #define __DSB()
388 #endif
389 /*
390  * alloc the temporary memory to store the status
391  */
392 #define OSA_SR_ALLOC() uint32_t osaCurrentSr = 0U;
393 /*
394  * Enter critical mode
395  */
396 #define OSA_ENTER_CRITICAL() OSA_EnterCritical(&osaCurrentSr)
397 /*
398  * Exit critical mode and retore the previous mode
399  */
400 #define OSA_EXIT_CRITICAL() \
401     __DSB();                \
402     OSA_ExitCritical(osaCurrentSr);
403 
404 /*******************************************************************************
405  * API
406  ******************************************************************************/
407 
408 /*!
409  * @brief Reserves the requested amount of memory in bytes.
410  *
411  * The function is used to reserve the requested amount of memory in bytes and initializes it to 0.
412  *
413  * @param length Amount of bytes to reserve.
414  *
415  * @return Pointer to the reserved memory. NULL if memory can't be allocated.
416  */
417 void *OSA_MemoryAllocate(uint32_t length);
418 
419 /*!
420  * @brief Frees the memory previously reserved.
421  *
422  * The function is used to free the memory block previously reserved.
423  *
424  * @param p Pointer to the start of the memory block previously reserved.
425  *
426  */
427 void OSA_MemoryFree(void *p);
428 
429 /*!
430  * @brief Enter critical with nesting mode.
431  *
432  * @param sr Store current status and return to caller.
433  */
434 void OSA_EnterCritical(uint32_t *sr);
435 
436 /*!
437  * @brief Exit critical with nesting mode.
438  *
439  * @param sr Previous status to restore.
440  */
441 void OSA_ExitCritical(uint32_t sr);
442 
443 /*!
444  * @name Task management
445  * @{
446  */
447 
448 /*!
449  * @brief Initialize OSA.
450  *
451  * This function is used to setup the basic services.
452  *
453  * Example below shows how to use this API to create the task handle.
454  * @code
455  *   OSA_Init();
456  * @endcode
457  */
458 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
459 void OSA_Init(void);
460 #endif
461 
462 /*!
463  * @brief Start OSA schedule.
464  *
465  * This function is used to start OSA scheduler.
466  *
467  * Example below shows how to use this API to start osa schedule.
468  * @code
469  *   OSA_Start();
470  * @endcode
471  */
472 #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
473 void OSA_Start(void);
474 #endif
475 
476 /*!
477  * @brief Creates a task.
478  *
479  * This function is used to create task based on the resources defined
480  * by the macro OSA_TASK_DEFINE.
481  *
482  * Example below shows how to use this API to create the task handle.
483  * @code
484  *   OSA_TASK_HANDLE_DEFINE(taskHandle);
485  *   OSA_TASK_DEFINE( Job1, OSA_PRIORITY_HIGH, 1, 800, 0);
486  *   OSA_TaskCreate((osa_task_handle_t)taskHandle, OSA_TASK(Job1), (osa_task_param_t)NULL);
487  * @endcode
488  *
489  * @param taskHandle Pointer to a memory space of size OSA_TASK_HANDLE_SIZE allocated by the caller, task handle.
490  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
491  * You can define the handle in the following two ways:
492  * #OSA_TASK_HANDLE_DEFINE(taskHandle);
493  * or
494  * uint32_t taskHandle[((OSA_TASK_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
495  * @param thread_def pointer to theosa_task_def_t structure which defines the task.
496  * @param task_param Pointer to be passed to the task when it is created.
497  * @retval KOSA_StatusSuccess The task is successfully created.
498  * @retval KOSA_StatusError   The task can not be created.
499  */
500 #if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
501 osa_status_t OSA_TaskCreate(osa_task_handle_t taskHandle,
502                             const osa_task_def_t *thread_def,
503                             osa_task_param_t task_param);
504 #endif /* FSL_OSA_TASK_ENABLE */
505 
506 /*!
507  * @brief Gets the handler of active task.
508  *
509  * @return Handler to current active task.
510  */
511 #if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
512 osa_task_handle_t OSA_TaskGetCurrentHandle(void);
513 #endif /* FSL_OSA_TASK_ENABLE */
514 
515 /*!
516  * @brief Puts the active task to the end of scheduler's queue.
517  *
518  * When a task calls this function, it gives up the CPU and puts itself to the
519  * end of a task ready list.
520  *
521  * @retval NULL
522  */
523 #if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
524 void OSA_TaskYield(void);
525 #endif /* FSL_OSA_TASK_ENABLE */
526 
527 /*!
528  * @brief Gets the priority of a task.
529  *
530  * @param taskHandle The handler of the task whose priority is received.
531  *
532  * @return Task's priority.
533  */
534 #if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
535 osa_task_priority_t OSA_TaskGetPriority(osa_task_handle_t taskHandle);
536 #endif /* FSL_OSA_TASK_ENABLE */
537 
538 /*!
539  * @brief Sets the priority of a task.
540  *
541  * @param taskHandle  The handler of the task whose priority is set.
542  * @param taskPriority The priority to set.
543  *
544  * @retval KOSA_StatusSuccess Task's priority is set successfully.
545  * @retval KOSA_StatusError   Task's priority can not be set.
546  */
547 #if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
548 osa_status_t OSA_TaskSetPriority(osa_task_handle_t taskHandle, osa_task_priority_t taskPriority);
549 #endif /* FSL_OSA_TASK_ENABLE */
550 
551 /*!
552  * @brief Destroys a previously created task.
553  *
554  * @param taskHandle The handler of the task to destroy.
555  *
556  * @retval KOSA_StatusSuccess The task was successfully destroyed.
557  * @retval KOSA_StatusError   Task destruction failed or invalid parameter.
558  */
559 #if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
560 osa_status_t OSA_TaskDestroy(osa_task_handle_t taskHandle);
561 #endif /* FSL_OSA_TASK_ENABLE */
562 
563 /*!
564  * @brief Pre-creates a semaphore.
565  *
566  * This function pre-creates a semaphore with the task handler.
567  *
568  * Example below shows how to use this API to create the semaphore handle.
569  * @code
570  *   OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle);
571  *   OSA_SemaphoreCreate((osa_semaphore_handle_t)semaphoreHandle, (osa_task_ptr_t)taskHandler);
572  * @endcode
573  *
574  * @param semaphoreHandle Pointer to a memory space of size OSA_SEM_HANDLE_SIZE allocated by the caller.
575  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
576  * You can define the handle in the following two ways:
577  * #OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle);
578  * or
579  * uint32_t semaphoreHandle[((OSA_SEM_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
580  * @param taskHandler taskHandler The task handler this event is used by.
581  *
582  * @retval KOSA_StatusSuccess  the new semaphore if the semaphore is created successfully.
583  */
584 osa_status_t OSA_SemaphorePrecreate(osa_semaphore_handle_t semaphoreHandle, osa_task_ptr_t taskHandler);
585 
586 /*!
587  * @brief Creates a semaphore with a given value.
588  *
589  * This function creates a semaphore and sets the value to the parameter
590  * initValue.
591  *
592  * Example below shows how to use this API to create the semaphore handle.
593  * @code
594  *   OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle);
595  *   OSA_SemaphoreCreate((osa_semaphore_handle_t)semaphoreHandle, 0xff);
596  * @endcode
597  *
598  * @param semaphoreHandle Pointer to a memory space of size OSA_SEM_HANDLE_SIZE allocated by the caller.
599  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
600  * You can define the handle in the following two ways:
601  * #OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle);
602  * or
603  * uint32_t semaphoreHandle[((OSA_SEM_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
604  * @param initValue Initial value the semaphore will be set to.
605  *
606  * @retval KOSA_StatusSuccess  the new semaphore if the semaphore is created successfully.
607  * @retval KOSA_StatusError   if the semaphore can not be created.
608  */
609 osa_status_t OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle, uint32_t initValue);
610 
611 /*!
612  * @brief Creates a binary semaphore.
613  *
614  * This function creates a binary semaphore
615  *
616  * Example below shows how to use this API to create the semaphore handle.
617  * @code
618  *   OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle);
619  *   OSA_SemaphoreCreateBinary((osa_semaphore_handle_t)semaphoreHandle);
620  * @endcode
621  *
622  * @param semaphoreHandle Pointer to a memory space of size OSA_SEM_HANDLE_SIZE allocated by the caller.
623  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
624  * You can define the handle in the following two ways:
625  * #OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle);
626  * or
627  * uint32_t semaphoreHandle[((OSA_SEM_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
628  *
629  * @retval KOSA_StatusSuccess  the new binary semaphore if the binary semaphore is created successfully.
630  * @retval KOSA_StatusError   if the binary semaphore can not be created.
631  */
632 osa_status_t OSA_SemaphoreCreateBinary(osa_semaphore_handle_t semaphoreHandle);
633 
634 /*!
635  * @brief Destroys a previously created semaphore.
636  *
637  * @param semaphoreHandle The semaphore handle.
638  * The macro SEMAPHORE_HANDLE_BUFFER_GET is used to get the semaphore buffer pointer,
639  * and should not be used before the macro SEMAPHORE_HANDLE_BUFFER_DEFINE is used.
640  *
641  * @retval KOSA_StatusSuccess The semaphore is successfully destroyed.
642  * @retval KOSA_StatusError   The semaphore can not be destroyed.
643  */
644 osa_status_t OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle);
645 
646 /*!
647  * @brief Pending a semaphore with timeout.
648  *
649  * This function checks the semaphore's counting value. If it is positive,
650  * decreases it and returns KOSA_StatusSuccess. Otherwise, a timeout is used
651  * to wait.
652  *
653  * @param semaphoreHandle    The semaphore handle.
654  * @param millisec The maximum number of milliseconds to wait if semaphore is not
655  *                 positive. Pass osaWaitForever_c to wait indefinitely, pass 0
656  *                 will return KOSA_StatusTimeout immediately.
657  *
658  * @retval KOSA_StatusSuccess  The semaphore is received.
659  * @retval KOSA_StatusTimeout  The semaphore is not received within the specified 'timeout'.
660  * @retval KOSA_StatusError    An incorrect parameter was passed.
661  */
662 osa_status_t OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle, uint32_t millisec);
663 
664 /*!
665  * @brief Signals for someone waiting on the semaphore to wake up.
666  *
667  * Wakes up one task that is waiting on the semaphore. If no task is waiting, increases
668  * the semaphore's counting value.
669  *
670  * @param semaphoreHandle The semaphore handle to signal.
671  *
672  * @retval KOSA_StatusSuccess The semaphore is successfully signaled.
673  * @retval KOSA_StatusError   The object can not be signaled or invalid parameter.
674  *
675  */
676 osa_status_t OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle);
677 
678 /*!
679  * @brief Create an unlocked mutex.
680  *
681  * This function creates a non-recursive mutex and sets it to unlocked status.
682  *
683  * Example below shows how to use this API to create the mutex handle.
684  * @code
685  *   OSA_MUTEX_HANDLE_DEFINE(mutexHandle);
686  *   OSA_MutexCreate((osa_mutex_handle_t)mutexHandle);
687  * @endcode
688  *
689  * @param mutexHandle       Pointer to a memory space of size OSA_MUTEX_HANDLE_SIZE allocated by the caller.
690  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
691  * You can define the handle in the following two ways:
692  * #OSA_MUTEX_HANDLE_DEFINE(mutexHandle);
693  * or
694  * uint32_t mutexHandle[((OSA_MUTEX_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
695  * @retval KOSA_StatusSuccess  the new mutex if the mutex is created successfully.
696  * @retval KOSA_StatusError   if the mutex can not be created.
697  */
698 osa_status_t OSA_MutexCreate(osa_mutex_handle_t mutexHandle);
699 
700 /*!
701  * @brief Waits for a mutex and locks it.
702  *
703  * This function checks the mutex's status. If it is unlocked, locks it and returns the
704  * KOSA_StatusSuccess. Otherwise, waits for a timeout in milliseconds to lock.
705  *
706  * @param mutexHandle The mutex handle.
707  * @param millisec The maximum number of milliseconds to wait for the mutex.
708  *                 If the mutex is locked, Pass the value osaWaitForever_c will
709  *                 wait indefinitely, pass 0 will return KOSA_StatusTimeout
710  *                 immediately.
711  *
712  * @retval KOSA_StatusSuccess The mutex is locked successfully.
713  * @retval KOSA_StatusTimeout Timeout occurred.
714  * @retval KOSA_StatusError   Incorrect parameter was passed.
715  *
716  * @note This is non-recursive mutex, a task can not try to lock the mutex it has locked.
717  */
718 osa_status_t OSA_MutexLock(osa_mutex_handle_t mutexHandle, uint32_t millisec);
719 
720 /*!
721  * @brief Unlocks a previously locked mutex.
722  *
723  * @param mutexHandle The mutex handle.
724  *
725  * @retval KOSA_StatusSuccess The mutex is successfully unlocked.
726  * @retval KOSA_StatusError   The mutex can not be unlocked or invalid parameter.
727  */
728 osa_status_t OSA_MutexUnlock(osa_mutex_handle_t mutexHandle);
729 
730 /*!
731  * @brief Destroys a previously created mutex.
732  *
733  * @param mutexHandle The mutex handle.
734  *
735  * @retval KOSA_StatusSuccess The mutex is successfully destroyed.
736  * @retval KOSA_StatusError   The mutex can not be destroyed.
737  *
738  */
739 osa_status_t OSA_MutexDestroy(osa_mutex_handle_t mutexHandle);
740 
741 /*!
742  * @brief Pre-initializes an event object.
743  *
744  * This function pre-creates an event object and indicates which task this event is used by.
745  *
746  * Example below shows how to use this API to create the event handle.
747  * @code
748  *   OSA_EVENT_HANDLE_DEFINE(eventHandle);
749  *   OSA_EventPrecreate((osa_event_handle_t)eventHandle, (osa_task_ptr_t)taskHandler);
750  * @endcode
751  *
752  * @param eventHandle Pointer to a memory space of size OSA_EVENT_HANDLE_SIZE allocated by the caller.
753  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
754  * You can define the handle in the following two ways:
755  * #OSA_EVENT_HANDLE_DEFINE(eventHandle);
756  * or
757  * uint32 eventHandle[((OSA_EVENT_HANDLE_SIZE + sizeof(uint32) - 1U) / sizeof(uint32))];
758  * @param taskHandler The task handler this event is used by.
759  * @retval KOSA_StatusSuccess  the new event if the event is pre-created successfully.
760  */
761 osa_status_t OSA_EventPrecreate(osa_event_handle_t eventHandle, osa_task_ptr_t taskHandler);
762 
763 /*!
764  * @brief Initializes an event object with all flags cleared.
765  *
766  * This function creates an event object and set its clear mode. If autoClear
767  * is 1, when a task gets the event flags, these flags will be
768  * cleared automatically. Otherwise these flags must
769  * be cleared manually.
770  *
771  * Example below shows how to use this API to create the event handle.
772  * @code
773  *   OSA_EVENT_HANDLE_DEFINE(eventHandle);
774  *   OSA_EventCreate((osa_event_handle_t)eventHandle, 0);
775  * @endcode
776  *
777  * @param eventHandle Pointer to a memory space of size OSA_EVENT_HANDLE_SIZE allocated by the caller.
778  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
779  * You can define the handle in the following two ways:
780  * #OSA_EVENT_HANDLE_DEFINE(eventHandle);
781  * or
782  * uint32_t eventHandle[((OSA_EVENT_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
783  * @param autoClear 1 The event is auto-clear.
784  *                  0 The event manual-clear
785  * @retval KOSA_StatusSuccess  the new event if the event is created successfully.
786  * @retval KOSA_StatusError   if the event can not be created.
787  */
788 osa_status_t OSA_EventCreate(osa_event_handle_t eventHandle, uint8_t autoClear);
789 
790 /*!
791  * @brief Sets one or more event flags.
792  *
793  * Sets specified flags of an event object.
794  *
795  * @param eventHandle     The event handle.
796  * @param flagsToSet  Flags to be set.
797  *
798  * @retval KOSA_StatusSuccess The flags were successfully set.
799  * @retval KOSA_StatusError   An incorrect parameter was passed.
800  */
801 osa_status_t OSA_EventSet(osa_event_handle_t eventHandle, osa_event_flags_t flagsToSet);
802 
803 /*!
804  * @brief Clears one or more flags.
805  *
806  * Clears specified flags of an event object.
807  *
808  * @param eventHandle       The event handle.
809  * @param flagsToClear  Flags to be clear.
810  *
811  * @retval KOSA_StatusSuccess The flags were successfully cleared.
812  * @retval KOSA_StatusError   An incorrect parameter was passed.
813  */
814 osa_status_t OSA_EventClear(osa_event_handle_t eventHandle, osa_event_flags_t flagsToClear);
815 
816 /*!
817  * @brief Get event's flags.
818  *
819  * Get specified flags of an event object.
820  *
821  * @param eventHandle       The event handle.
822  * The macro EVENT_HANDLE_BUFFER_GET is used to get the event buffer pointer,
823  * and should not be used before the macro EVENT_HANDLE_BUFFER_DEFINE is used.
824  * @param flagsMask         The flags user want to get are specified by this parameter.
825  * @param pFlagsOfEvent     The event flags are obtained by this parameter.
826  *
827  * @retval KOSA_StatusSuccess The event flags were successfully got.
828  * @retval KOSA_StatusError   An incorrect parameter was passed.
829  */
830 osa_status_t OSA_EventGet(osa_event_handle_t eventHandle,
831                           osa_event_flags_t flagsMask,
832                           osa_event_flags_t *pFlagsOfEvent);
833 
834 /*!
835  * @brief Waits for specified event flags to be set.
836  *
837  * This function waits for a combination of flags to be set in an event object.
838  * Applications can wait for any/all bits to be set. Also this function could
839  * obtain the flags who wakeup the waiting task.
840  *
841  * @param eventHandle     The event handle.
842  * @param flagsToWait Flags that to wait.
843  * @param waitAll     Wait all flags or any flag to be set.
844  * @param millisec    The maximum number of milliseconds to wait for the event.
845  *                    If the wait condition is not met, pass osaWaitForever_c will
846  *                    wait indefinitely, pass 0 will return KOSA_StatusTimeout
847  *                    immediately.
848  * @param pSetFlags    Flags that wakeup the waiting task are obtained by this parameter.
849  *
850  * @retval KOSA_StatusSuccess The wait condition met and function returns successfully.
851  * @retval KOSA_StatusTimeout Has not met wait condition within timeout.
852  * @retval KOSA_StatusError   An incorrect parameter was passed.
853 
854  *
855  * @note    Please pay attention to the flags bit width, FreeRTOS uses the most
856  *          significant 8 bis as control bits, so do not wait these bits while using
857  *          FreeRTOS.
858  *
859  */
860 osa_status_t OSA_EventWait(osa_event_handle_t eventHandle,
861                            osa_event_flags_t flagsToWait,
862                            uint8_t waitAll,
863                            uint32_t millisec,
864                            osa_event_flags_t *pSetFlags);
865 
866 /*!
867  * @brief Destroys a previously created event object.
868  *
869  * @param eventHandle The event handle.
870  *
871  * @retval KOSA_StatusSuccess The event is successfully destroyed.
872  * @retval KOSA_StatusError   Event destruction failed.
873  */
874 osa_status_t OSA_EventDestroy(osa_event_handle_t eventHandle);
875 
876 /*!
877  * @brief Initializes a message queue.
878  *
879  * This function  allocates memory for and initializes a message queue. Message queue elements are hardcoded as void*.
880  *
881  * Example below shows how to use this API to create the massage queue handle.
882  * @code
883  *   OSA_MSGQ_HANDLE_DEFINE(msgqHandle);
884  *   OSA_MsgQCreate((osa_msgq_handle_t)msgqHandle, 5U, sizeof(msg));
885  * @endcode
886  *
887  * @param msgqHandle    Pointer to a memory space of size #(OSA_MSGQ_HANDLE_SIZE + msgNo*msgSize) on bare-matel
888  * and #(OSA_MSGQ_HANDLE_SIZE) on FreeRTOS allocated by the caller, message queue handle.
889  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
890  * You can define the handle in the following two ways:
891  * #OSA_MSGQ_HANDLE_DEFINE(msgqHandle);
892  * or
893  * For bm: uint32_t msgqHandle[((OSA_MSGQ_HANDLE_SIZE + msgNo*msgSize + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
894  * For freertos: uint32_t msgqHandle[((OSA_MSGQ_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
895  * @param msgNo :number of messages the message queue should accommodate.
896  * @param msgSize :size of a single message structure.
897  *
898  * @retval KOSA_StatusSuccess Message queue successfully Create.
899  * @retval KOSA_StatusError     Message queue create failure.
900  */
901 osa_status_t OSA_MsgQCreate(osa_msgq_handle_t msgqHandle, uint32_t msgNo, uint32_t msgSize);
902 
903 /*!
904  * @brief Puts a message at the end of the queue.
905  *
906  * This function puts a message to the end of the message queue. If the queue
907  * is full, this function returns the KOSA_StatusError;
908  *
909  * @param msgqHandle  Message Queue handler.
910  * @param pMessage Pointer to the message to be put into the queue.
911  *
912  * @retval KOSA_StatusSuccess Message successfully put into the queue.
913  * @retval KOSA_StatusError   The queue was full or an invalid parameter was passed.
914  */
915 osa_status_t OSA_MsgQPut(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage);
916 
917 /*!
918  * @brief Reads and remove a message at the head of the queue.
919  *
920  * This function gets a message from the head of the message queue. If the
921  * queue is empty, timeout is used to wait.
922  *
923  * @param msgqHandle   Message Queue handler.
924  * @param pMessage Pointer to a memory to save the message.
925  * @param millisec The number of milliseconds to wait for a message. If the
926  *                 queue is empty, pass osaWaitForever_c will wait indefinitely,
927  *                 pass 0 will return KOSA_StatusTimeout immediately.
928  *
929  * @retval KOSA_StatusSuccess   Message successfully obtained from the queue.
930  * @retval KOSA_StatusTimeout   The queue remains empty after timeout.
931  * @retval KOSA_StatusError     Invalid parameter.
932  */
933 osa_status_t OSA_MsgQGet(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage, uint32_t millisec);
934 
935 /*!
936  * @brief Get the available message
937  *
938  * This function is used to get the available message.
939  *
940  * @param msgqHandle Message Queue handler.
941  *
942  * @return Available message count
943  */
944 int OSA_MsgQAvailableMsgs(osa_msgq_handle_t msgqHandle);
945 
946 /*!
947  * @brief Destroys a previously created queue.
948  *
949  * @param msgqHandle Message Queue handler.
950  *
951  * @retval KOSA_StatusSuccess The queue was successfully destroyed.
952  * @retval KOSA_StatusError   Message queue destruction failed.
953  */
954 osa_status_t OSA_MsgQDestroy(osa_msgq_handle_t msgqHandle);
955 
956 /*!
957  * @brief Enable all interrupts.
958  */
959 void OSA_InterruptEnable(void);
960 
961 /*!
962  * @brief Disable all interrupts.
963  */
964 void OSA_InterruptDisable(void);
965 
966 /*!
967  * @brief Enable all interrupts using PRIMASK.
968  */
969 void OSA_EnableIRQGlobal(void);
970 
971 /*!
972  * @brief Disable all interrupts using PRIMASK.
973  */
974 void OSA_DisableIRQGlobal(void);
975 
976 /*!
977  * @brief Delays execution for a number of milliseconds.
978  *
979  * @param millisec The time in milliseconds to wait.
980  */
981 void OSA_TimeDelay(uint32_t millisec);
982 
983 /*!
984  * @brief This function gets current time in milliseconds.
985  *
986  * @retval current time in milliseconds
987  */
988 uint32_t OSA_TimeGetMsec(void);
989 
990 /*!
991  * @brief Installs the interrupt handler.
992  *
993  * @param IRQNumber IRQ number of the interrupt.
994  * @param handler The interrupt handler to install.
995  */
996 void OSA_InstallIntHandler(uint32_t IRQNumber, void (*handler)(void));
997 
998 /*! @}*/
999 #ifdef __cplusplus
1000 }
1001 #endif
1002 /*! @}*/
1003 #endif
1004