fsl_os_abstraction_rtthread.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917
  1. /*! *********************************************************************************
  2. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2017, 2019 NXP
  4. * All rights reserved.
  5. *
  6. *
  7. * This is the source file for the OS Abstraction layer for freertos.
  8. *
  9. * SPDX-License-Identifier: BSD-3-Clause
  10. ********************************************************************************** */
  11. /*! *********************************************************************************
  12. *************************************************************************************
  13. * Include
  14. *************************************************************************************
  15. ********************************************************************************** */
  16. #include "fsl_common.h"
  17. #include "fsl_os_abstraction.h"
  18. #include "fsl_os_abstraction_rtthread.h"
  19. #include <string.h>
  20. #include "generic_list.h"
  21. /*! *********************************************************************************
  22. *************************************************************************************
  23. * Private macros
  24. *************************************************************************************
  25. ********************************************************************************** */
  26. /* Weak function. */
  27. #if defined(__GNUC__)
  28. #define __WEAK_FUNC __attribute__((weak))
  29. #elif defined(__ICCARM__)
  30. #define __WEAK_FUNC __weak
  31. #elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
  32. #define __WEAK_FUNC __attribute__((weak))
  33. #endif
  34. #define millisecToTicks(millisec) (((millisec)*configTICK_RATE_HZ + 999U) / 1000U)
  35. #ifdef DEBUG_ASSERT
  36. #define OS_ASSERT(condition) \
  37. if (!(condition)) \
  38. while (1) \
  39. ;
  40. #else
  41. #define OS_ASSERT(condition) (void)(condition);
  42. #endif
  43. /*! @brief Converts milliseconds to ticks*/
  44. #define MSEC_TO_TICK(msec) \
  45. (((uint32_t)(msec) + 500uL / (uint32_t)configTICK_RATE_HZ) * (uint32_t)configTICK_RATE_HZ / 1000uL)
  46. #define TICKS_TO_MSEC(tick) ((uint32_t)((uint64_t)(tick)*1000uL / (uint64_t)configTICK_RATE_HZ))
  47. /************************************************************************************
  48. *************************************************************************************
  49. * Private type definitions
  50. *************************************************************************************
  51. ************************************************************************************/
  52. typedef struct osa_freertos_task
  53. {
  54. list_element_t link;
  55. rt_thread_t taskHandle;
  56. } osa_freertos_task_t;
  57. typedef struct _osa_event_struct
  58. {
  59. rt_event_t handle; /* The event handle */
  60. uint8_t autoClear; /*!< Auto clear or manual clear */
  61. } osa_event_struct_t;
  62. /*! @brief State structure for bm osa manager. */
  63. typedef struct _osa_state
  64. {
  65. #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
  66. list_label_t taskList;
  67. OSA_TASK_HANDLE_DEFINE(mainTaskHandle);
  68. #endif
  69. uint32_t basePriority;
  70. int32_t basePriorityNesting;
  71. uint32_t interruptDisableCount;
  72. } osa_state_t;
  73. /*! *********************************************************************************
  74. *************************************************************************************
  75. * Private prototypes
  76. *************************************************************************************
  77. ********************************************************************************** */
  78. __WEAK_FUNC void main_task(void const *argument);
  79. __WEAK_FUNC void main_task(void const *argument)
  80. {
  81. }
  82. void startup_task(void *argument);
  83. /*! *********************************************************************************
  84. *************************************************************************************
  85. * Public memory declarations
  86. *************************************************************************************
  87. ********************************************************************************** */
  88. const uint8_t gUseRtos_c = USE_RTOS; // USE_RTOS = 0 for BareMetal and 1 for OS
  89. static osa_state_t s_osaState = {0};
  90. /*! *********************************************************************************
  91. *************************************************************************************
  92. * Private memory declarations
  93. *************************************************************************************
  94. ********************************************************************************** */
  95. /*! *********************************************************************************
  96. *************************************************************************************
  97. * Public functions
  98. *************************************************************************************
  99. ********************************************************************************** */
  100. /*FUNCTION**********************************************************************
  101. *
  102. * Function Name : OSA_MemoryAllocate
  103. * Description : Reserves the requested amount of memory in bytes.
  104. *
  105. *END**************************************************************************/
  106. void *OSA_MemoryAllocate(uint32_t length)
  107. {
  108. void *p = rt_malloc(length);
  109. if (RT_NULL != p)
  110. {
  111. rt_memset(p, 0, length);
  112. }
  113. return p;
  114. }
  115. /*FUNCTION**********************************************************************
  116. *
  117. * Function Name : OSA_MemoryFree
  118. * Description : Frees the memory previously reserved.
  119. *
  120. *END**************************************************************************/
  121. void OSA_MemoryFree(void *p)
  122. {
  123. rt_free(p);
  124. }
  125. void OSA_EnterCritical(uint32_t *sr)
  126. {
  127. if (rt_thread_self() != RT_NULL)
  128. rt_enter_critical();
  129. }
  130. void OSA_ExitCritical(uint32_t sr)
  131. {
  132. if (rt_thread_self() != RT_NULL)
  133. rt_exit_critical();
  134. }
  135. /*FUNCTION**********************************************************************
  136. *
  137. * Function Name : startup_task
  138. * Description : Wrapper over main_task..
  139. *
  140. *END**************************************************************************/
  141. void startup_task(void *argument)
  142. {
  143. main_task(argument);
  144. }
  145. /*FUNCTION**********************************************************************
  146. *
  147. * Function Name : OSA_TaskGetCurrentHandle
  148. * Description : This function is used to get current active task's handler.
  149. *
  150. *END**************************************************************************/
  151. #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
  152. osa_task_handle_t OSA_TaskGetCurrentHandle(void)
  153. {
  154. list_element_handle_t list_element;
  155. osa_freertos_task_t *ptask;
  156. list_element = LIST_GetHead(&s_osaState.taskList);
  157. while (NULL != list_element)
  158. {
  159. ptask = (osa_freertos_task_t *)(void *)list_element;
  160. if (ptask->taskHandle == xTaskGetCurrentTaskHandle())
  161. {
  162. return (osa_task_handle_t)ptask;
  163. }
  164. list_element = LIST_GetNext(list_element);
  165. }
  166. return NULL;
  167. }
  168. #endif
  169. /*FUNCTION**********************************************************************
  170. *
  171. * Function Name : OSA_TaskYield
  172. * Description : When a task calls this function, it will give up CPU and put
  173. * itself to the tail of ready list.
  174. *
  175. *END**************************************************************************/
  176. #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
  177. osa_status_t OSA_TaskYield(void)
  178. {
  179. taskYIELD();
  180. return KOSA_StatusSuccess;
  181. }
  182. #endif
  183. /*FUNCTION**********************************************************************
  184. *
  185. * Function Name : OSA_TaskGetPriority
  186. * Description : This function returns task's priority by task handler.
  187. *
  188. *END**************************************************************************/
  189. #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
  190. osa_task_priority_t OSA_TaskGetPriority(osa_task_handle_t taskHandle)
  191. {
  192. assert(taskHandle);
  193. osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
  194. return (osa_task_priority_t)(PRIORITY_RTOS_TO_OSA(uxTaskPriorityGet(ptask->taskHandle)));
  195. }
  196. #endif
  197. /*FUNCTION**********************************************************************
  198. *
  199. * Function Name : OSA_TaskSetPriority
  200. * Description : This function sets task's priority by task handler.
  201. *
  202. *END**************************************************************************/
  203. #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
  204. osa_status_t OSA_TaskSetPriority(osa_task_handle_t taskHandle, osa_task_priority_t taskPriority)
  205. {
  206. assert(taskHandle);
  207. osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
  208. vTaskPrioritySet((task_handler_t)ptask->taskHandle, PRIORITY_OSA_TO_RTOS(taskPriority));
  209. return KOSA_StatusSuccess;
  210. }
  211. #endif
  212. /*FUNCTION**********************************************************************
  213. *
  214. * Function Name : OSA_TaskCreate
  215. * Description : This function is used to create a task and make it ready.
  216. * Param[in] : threadDef - Definition of the thread.
  217. * task_param - Parameter to pass to the new thread.
  218. * Return Thread handle of the new thread, or NULL if failed.
  219. *
  220. *END**************************************************************************/
  221. #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
  222. osa_status_t OSA_TaskCreate(osa_task_handle_t taskHandle, osa_task_def_t *thread_def, osa_task_param_t task_param)
  223. {
  224. assert(sizeof(osa_freertos_task_t) == OSA_TASK_HANDLE_SIZE);
  225. assert(taskHandle);
  226. TaskHandle_t pxCreatedTask;
  227. osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
  228. if (xTaskCreate((TaskFunction_t)thread_def->pthread, /* pointer to the task */
  229. (char const *)thread_def->tname, /* task name for kernel awareness debugging */
  230. (configSTACK_DEPTH_TYPE)thread_def->stacksize / sizeof(portSTACK_TYPE), /* task stack size */
  231. (task_param_t)task_param, /* optional task startup argument */
  232. PRIORITY_OSA_TO_RTOS(thread_def->tpriority), /* initial priority */
  233. &pxCreatedTask /* optional task handle to create */
  234. ) == pdPASS)
  235. {
  236. ptask->taskHandle = pxCreatedTask;
  237. OSA_InterruptDisable();
  238. (void)LIST_AddTail(&s_osaState.taskList, (list_element_handle_t) & (ptask->link));
  239. OSA_InterruptEnable();
  240. return KOSA_StatusSuccess;
  241. }
  242. return KOSA_StatusError;
  243. }
  244. #endif
  245. /*FUNCTION**********************************************************************
  246. *
  247. * Function Name : OSA_TaskDestroy
  248. * Description : This function destroy a task.
  249. * Param[in] :taskHandle - Thread handle.
  250. * Return KOSA_StatusSuccess if the task is destroied, otherwise return KOSA_StatusError.
  251. *
  252. *END**************************************************************************/
  253. #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
  254. osa_status_t OSA_TaskDestroy(osa_task_handle_t taskHandle)
  255. {
  256. assert(taskHandle);
  257. osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
  258. osa_status_t status;
  259. uint16_t oldPriority;
  260. /*Change priority to avoid context switches*/
  261. oldPriority = OSA_TaskGetPriority(OSA_TaskGetCurrentHandle());
  262. (void)OSA_TaskSetPriority(OSA_TaskGetCurrentHandle(), OSA_PRIORITY_REAL_TIME);
  263. #if INCLUDE_vTaskDelete /* vTaskDelete() enabled */
  264. vTaskDelete((task_handler_t)ptask->taskHandle);
  265. status = KOSA_StatusSuccess;
  266. #else
  267. status = KOSA_StatusError; /* vTaskDelete() not available */
  268. #endif
  269. (void)OSA_TaskSetPriority(OSA_TaskGetCurrentHandle(), oldPriority);
  270. OSA_InterruptDisable();
  271. (void)LIST_RemoveElement(taskHandle);
  272. OSA_InterruptEnable();
  273. return status;
  274. }
  275. #endif
  276. /*FUNCTION**********************************************************************
  277. *
  278. * Function Name : OSA_TimeDelay
  279. * Description : This function is used to suspend the active thread for the given number of milliseconds.
  280. *
  281. *END**************************************************************************/
  282. void OSA_TimeDelay(uint32_t millisec)
  283. {
  284. rt_thread_mdelay(millisec);
  285. }
  286. /*FUNCTION**********************************************************************
  287. *
  288. * Function Name : OSA_TimeGetMsec
  289. * Description : This function gets current time in milliseconds.
  290. *
  291. *END**************************************************************************/
  292. uint32_t OSA_TimeGetMsec(void)
  293. {
  294. return rt_tick_get_millisecond();
  295. }
  296. /*FUNCTION**********************************************************************
  297. *
  298. * Function Name : OSA_SemaphoreCreate
  299. * Description : This function is used to create a semaphore.
  300. * Return : Semaphore handle of the new semaphore, or NULL if failed.
  301. *
  302. *END**************************************************************************/
  303. osa_status_t OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle, uint32_t initValue)
  304. {
  305. assert(sizeof(osa_semaphore_handle_t) == OSA_SEM_HANDLE_SIZE);
  306. assert(semaphoreHandle);
  307. union
  308. {
  309. rt_sem_t sem;
  310. uint32_t semhandle;
  311. } xSemaHandle;
  312. xSemaHandle.sem = rt_sem_create("osa_sem", initValue, RT_IPC_FLAG_PRIO);
  313. if (NULL != xSemaHandle.sem)
  314. {
  315. *(uint32_t *)semaphoreHandle = xSemaHandle.semhandle;
  316. return KOSA_StatusSuccess;
  317. }
  318. return KOSA_StatusError;
  319. }
  320. /*FUNCTION**********************************************************************
  321. *
  322. * Function Name : OSA_SemaphoreDestroy
  323. * Description : This function is used to destroy a semaphore.
  324. * Return : KOSA_StatusSuccess if the semaphore is destroyed successfully, otherwise return KOSA_StatusError.
  325. *
  326. *END**************************************************************************/
  327. osa_status_t OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle)
  328. {
  329. assert(semaphoreHandle);
  330. rt_sem_t sem = (rt_sem_t)(void *)(uint32_t *)(*(uint32_t *)semaphoreHandle);
  331. rt_sem_delete(sem);
  332. return KOSA_StatusSuccess;
  333. }
  334. /*FUNCTION**********************************************************************
  335. *
  336. * Function Name : OSA_SemaphoreWait
  337. * Description : This function checks the semaphore's counting value, if it is
  338. * positive, decreases it and returns KOSA_StatusSuccess, otherwise, timeout
  339. * will be used for wait. The parameter timeout indicates how long should wait
  340. * in milliseconds. Pass osaWaitForever_c to wait indefinitely, pass 0 will
  341. * return KOSA_StatusTimeout immediately if semaphore is not positive.
  342. * This function returns KOSA_StatusSuccess if the semaphore is received, returns
  343. * KOSA_StatusTimeout if the semaphore is not received within the specified
  344. * 'timeout', returns KOSA_StatusError if any errors occur during waiting.
  345. *
  346. *END**************************************************************************/
  347. osa_status_t OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle, uint32_t millisec)
  348. {
  349. uint32_t timeoutTicks;
  350. assert(semaphoreHandle);
  351. rt_sem_t sem = (rt_sem_t)(void *)(uint32_t *)(*(uint32_t *)semaphoreHandle);
  352. /* Convert timeout from millisecond to tick. */
  353. if (millisec == osaWaitForever_c)
  354. {
  355. timeoutTicks = RT_WAITING_FOREVER;
  356. }
  357. else
  358. {
  359. timeoutTicks = rt_tick_from_millisecond(millisec);
  360. }
  361. if (RT_EOK != rt_sem_take(sem, timeoutTicks))
  362. {
  363. return KOSA_StatusTimeout; /* timeout */
  364. }
  365. else
  366. {
  367. return KOSA_StatusSuccess; /* semaphore taken */
  368. }
  369. }
  370. /*FUNCTION**********************************************************************
  371. *
  372. * Function Name : OSA_SemaphorePost
  373. * Description : This function is used to wake up one task that wating on the
  374. * semaphore. If no task is waiting, increase the semaphore. The function returns
  375. * KOSA_StatusSuccess if the semaphre is post successfully, otherwise returns
  376. * KOSA_StatusError.
  377. *
  378. *END**************************************************************************/
  379. osa_status_t OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle)
  380. {
  381. assert(semaphoreHandle);
  382. rt_sem_t sem = (rt_sem_t)(void *)(uint32_t *)(*(uint32_t *)semaphoreHandle);
  383. rt_sem_release(sem);
  384. return KOSA_StatusSuccess;
  385. }
  386. /*FUNCTION**********************************************************************
  387. *
  388. * Function Name : OSA_MutexCreate
  389. * Description : This function is used to create a mutex.
  390. * Return : Mutex handle of the new mutex, or NULL if failed.
  391. *
  392. *END**************************************************************************/
  393. osa_status_t OSA_MutexCreate(osa_mutex_handle_t mutexHandle)
  394. {
  395. assert(sizeof(osa_mutex_handle_t) == OSA_MUTEX_HANDLE_SIZE);
  396. assert(mutexHandle);
  397. union
  398. {
  399. rt_mutex_t mutex;
  400. uint32_t pmutexHandle;
  401. } xMutexHandle;
  402. xMutexHandle.mutex = rt_mutex_create("osa_mutex", RT_IPC_FLAG_PRIO);
  403. if (RT_NULL != xMutexHandle.mutex)
  404. {
  405. *(uint32_t *)mutexHandle = xMutexHandle.pmutexHandle;
  406. return KOSA_StatusSuccess;
  407. }
  408. return KOSA_StatusError;
  409. }
  410. /*FUNCTION**********************************************************************
  411. *
  412. * Function Name : OSA_MutexLock
  413. * Description : This function checks the mutex's status, if it is unlocked,
  414. * lock it and returns KOSA_StatusSuccess, otherwise, wait for the mutex.
  415. * This function returns KOSA_StatusSuccess if the mutex is obtained, returns
  416. * KOSA_StatusError if any errors occur during waiting. If the mutex has been
  417. * locked, pass 0 as timeout will return KOSA_StatusTimeout immediately.
  418. *
  419. *END**************************************************************************/
  420. osa_status_t OSA_MutexLock(osa_mutex_handle_t mutexHandle, uint32_t millisec)
  421. {
  422. assert(mutexHandle);
  423. uint32_t timeoutTicks;
  424. rt_mutex_t mutex = (rt_mutex_t)(void *)(uint32_t *)(*(uint32_t *)mutexHandle);
  425. /* Convert timeout from millisecond to tick. */
  426. if (millisec == osaWaitForever_c)
  427. {
  428. timeoutTicks = RT_WAITING_FOREVER;
  429. }
  430. else
  431. {
  432. timeoutTicks = rt_tick_from_millisecond(millisec);
  433. }
  434. if (RT_EOK != rt_mutex_take(mutex, timeoutTicks))
  435. {
  436. return KOSA_StatusTimeout; /* timeout */
  437. }
  438. else
  439. {
  440. return KOSA_StatusSuccess; /* semaphore taken */
  441. }
  442. }
  443. /*FUNCTION**********************************************************************
  444. *
  445. * Function Name : OSA_MutexUnlock
  446. * Description : This function is used to unlock a mutex.
  447. *
  448. *END**************************************************************************/
  449. osa_status_t OSA_MutexUnlock(osa_mutex_handle_t mutexHandle)
  450. {
  451. assert(mutexHandle);
  452. rt_mutex_t mutex = (rt_mutex_t)(void *)(uint32_t *)(*(uint32_t *)mutexHandle);
  453. rt_mutex_release(mutex);
  454. return KOSA_StatusSuccess;
  455. }
  456. /*FUNCTION**********************************************************************
  457. *
  458. * Function Name : OSA_MutexDestroy
  459. * Description : This function is used to destroy a mutex.
  460. * Return : KOSA_StatusSuccess if the lock object is destroyed successfully, otherwise return KOSA_StatusError.
  461. *
  462. *END**************************************************************************/
  463. osa_status_t OSA_MutexDestroy(osa_mutex_handle_t mutexHandle)
  464. {
  465. assert(mutexHandle);
  466. rt_mutex_t mutex = (rt_mutex_t)(void *)(uint32_t *)(*(uint32_t *)mutexHandle);
  467. rt_mutex_delete(mutex);
  468. return KOSA_StatusSuccess;
  469. }
  470. /*FUNCTION**********************************************************************
  471. *
  472. * Function Name : OSA_EventCreate
  473. * Description : This function is used to create a event object.
  474. * Return : Event handle of the new event, or NULL if failed.
  475. *
  476. *END**************************************************************************/
  477. osa_status_t OSA_EventCreate(osa_event_handle_t eventHandle, uint8_t autoClear)
  478. {
  479. assert(eventHandle);
  480. osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
  481. pEventStruct->handle = rt_event_create("osa_event", RT_IPC_FLAG_PRIO);
  482. if (RT_NULL != pEventStruct->handle)
  483. {
  484. pEventStruct->autoClear = autoClear;
  485. }
  486. else
  487. {
  488. return KOSA_StatusError;
  489. }
  490. return KOSA_StatusSuccess;
  491. }
  492. /*FUNCTION**********************************************************************
  493. *
  494. * Function Name : OSA_EventSet
  495. * Description : Set one or more event flags of an event object.
  496. * Return : KOSA_StatusSuccess if set successfully, KOSA_StatusError if failed.
  497. *
  498. *END**************************************************************************/
  499. osa_status_t OSA_EventSet(osa_event_handle_t eventHandle, osa_event_flags_t flagsToSet)
  500. {
  501. rt_err_t result;
  502. assert(eventHandle);
  503. osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
  504. if (RT_NULL == pEventStruct->handle)
  505. {
  506. return KOSA_StatusError;
  507. }
  508. rt_event_send(pEventStruct->handle, (rt_uint32_t)flagsToSet);
  509. (void)result;
  510. return KOSA_StatusSuccess;
  511. }
  512. /*FUNCTION**********************************************************************
  513. *
  514. * Function Name : OSA_EventClear
  515. * Description : Clear one or more event flags of an event object.
  516. * Return :KOSA_StatusSuccess if clear successfully, KOSA_StatusError if failed.
  517. *
  518. *END**************************************************************************/
  519. osa_status_t OSA_EventClear(osa_event_handle_t eventHandle, osa_event_flags_t flagsToClear)
  520. {
  521. assert(eventHandle);
  522. osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
  523. if (RT_NULL == pEventStruct->handle)
  524. {
  525. return KOSA_StatusError;
  526. }
  527. rt_uint32_t recved;
  528. rt_event_recv(pEventStruct->handle, (rt_uint32_t)flagsToClear, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, 0, &recved);
  529. return KOSA_StatusSuccess;
  530. }
  531. /*FUNCTION**********************************************************************
  532. *
  533. * Function Name : OSA_EventGet
  534. * Description : This function is used to get event's flags that specified by prameter
  535. * flagsMask, and the flags (user specified) are obatianed by parameter pFlagsOfEvent. So
  536. * you should pass the parameter 0xffffffff to specify you want to check all.
  537. * Return :KOSA_StatusSuccess if event flags were successfully got, KOSA_StatusError if failed.
  538. *
  539. *END**************************************************************************/
  540. osa_status_t OSA_EventGet(osa_event_handle_t eventHandle, osa_event_flags_t flagsMask, osa_event_flags_t *pFlagsOfEvent)
  541. {
  542. assert(eventHandle);
  543. osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
  544. rt_uint32_t eventFlags;
  545. if (RT_NULL == pEventStruct->handle)
  546. {
  547. return KOSA_StatusError;
  548. }
  549. if (RT_NULL == pFlagsOfEvent)
  550. {
  551. return KOSA_StatusError;
  552. }
  553. if (RT_EOK != rt_event_recv(pEventStruct->handle, (rt_uint32_t)flagsMask, RT_EVENT_FLAG_OR, 0, &eventFlags))
  554. {
  555. eventFlags = 0;
  556. }
  557. *pFlagsOfEvent = (osa_event_flags_t)eventFlags & flagsMask;
  558. return KOSA_StatusSuccess;
  559. }
  560. /*FUNCTION**********************************************************************
  561. *
  562. * Function Name : OSA_EventWait
  563. * Description : This function checks the event's status, if it meets the wait
  564. * condition, return KOSA_StatusSuccess, otherwise, timeout will be used for
  565. * wait. The parameter timeout indicates how long should wait in milliseconds.
  566. * Pass osaWaitForever_c to wait indefinitely, pass 0 will return the value
  567. * KOSA_StatusTimeout immediately if wait condition is not met. The event flags
  568. * will be cleared if the event is auto clear mode. Flags that wakeup waiting
  569. * task could be obtained from the parameter setFlags.
  570. * This function returns KOSA_StatusSuccess if wait condition is met, returns
  571. * KOSA_StatusTimeout if wait condition is not met within the specified
  572. * 'timeout', returns KOSA_StatusError if any errors occur during waiting.
  573. *
  574. *END**************************************************************************/
  575. osa_status_t OSA_EventWait(osa_event_handle_t eventHandle,
  576. osa_event_flags_t flagsToWait,
  577. uint8_t waitAll,
  578. uint32_t millisec,
  579. osa_event_flags_t *pSetFlags)
  580. {
  581. assert(eventHandle);
  582. rt_uint8_t option = 0;
  583. rt_uint32_t timeoutTicks;
  584. rt_uint32_t flagsSave;
  585. osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
  586. /* Clean FreeRTOS cotrol flags */
  587. flagsToWait = flagsToWait & 0x00FFFFFFU;
  588. if (RT_NULL == pEventStruct->handle)
  589. {
  590. return KOSA_StatusError;
  591. }
  592. /* Convert timeout from millisecond to tick. */
  593. if (millisec == osaWaitForever_c)
  594. {
  595. timeoutTicks = RT_WAITING_FOREVER;
  596. }
  597. else
  598. {
  599. timeoutTicks = rt_tick_from_millisecond(millisec);
  600. }
  601. if (pEventStruct->autoClear != 0U)
  602. {
  603. option |= RT_EVENT_FLAG_CLEAR;
  604. }
  605. option |= waitAll ? RT_EVENT_FLAG_AND : RT_EVENT_FLAG_OR;
  606. rt_err_t status = rt_event_recv(pEventStruct->handle, (rt_uint32_t)flagsToWait, option, timeoutTicks, &flagsSave);
  607. flagsSave &= (rt_uint32_t)flagsToWait;
  608. if (RT_NULL != pSetFlags)
  609. {
  610. *pSetFlags = (osa_event_flags_t)flagsSave;
  611. }
  612. if (RT_EOK != status)
  613. {
  614. return KOSA_StatusTimeout;
  615. }
  616. else
  617. {
  618. return KOSA_StatusSuccess;
  619. }
  620. }
  621. /*FUNCTION**********************************************************************
  622. *
  623. * Function Name : OSA_EventDestroy
  624. * Description : This function is used to destroy a event object. Return
  625. * KOSA_StatusSuccess if the event object is destroyed successfully, otherwise
  626. * return KOSA_StatusError.
  627. *
  628. *END**************************************************************************/
  629. osa_status_t OSA_EventDestroy(osa_event_handle_t eventHandle)
  630. {
  631. assert(eventHandle);
  632. osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
  633. if (RT_NULL == pEventStruct->handle)
  634. {
  635. return KOSA_StatusError;
  636. }
  637. rt_event_delete(pEventStruct->handle);
  638. return KOSA_StatusSuccess;
  639. }
  640. /*FUNCTION**********************************************************************
  641. *
  642. * Function Name : OSA_MsgQCreate
  643. * Description : This function is used to create a message queue.
  644. * Return : the handle to the message queue if create successfully, otherwise
  645. * return NULL.
  646. *
  647. *END**************************************************************************/
  648. osa_status_t OSA_MsgQCreate(osa_msgq_handle_t msgqHandle, uint32_t msgNo, uint32_t msgSize)
  649. {
  650. assert(sizeof(osa_msgq_handle_t) == OSA_MSGQ_HANDLE_SIZE);
  651. assert(msgqHandle);
  652. union
  653. {
  654. rt_mq_t msgq;
  655. uint32_t pmsgqHandle;
  656. } xMsgqHandle;
  657. /* Create the message queue where the number and size is specified by msgNo and msgSize */
  658. xMsgqHandle.msgq = rt_mq_create("osa_mq", msgSize, msgNo, RT_IPC_FLAG_PRIO);
  659. if (RT_NULL != xMsgqHandle.msgq)
  660. {
  661. *(uint32_t *)msgqHandle = xMsgqHandle.pmsgqHandle;
  662. return KOSA_StatusSuccess;
  663. }
  664. return KOSA_StatusError;
  665. }
  666. /*FUNCTION**********************************************************************
  667. *
  668. * Function Name : OSA_MsgQPut
  669. * Description : This function is used to put a message to a message queue.
  670. * Return : KOSA_StatusSuccess if the message is put successfully, otherwise return KOSA_StatusError.
  671. *
  672. *END**************************************************************************/
  673. osa_status_t OSA_MsgQPut(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage)
  674. {
  675. assert(msgqHandle);
  676. rt_mq_t handler = (rt_mq_t)(void *)(uint32_t *)(*(uint32_t *)msgqHandle);
  677. if (RT_EOK == rt_mq_send(handler, pMessage, handler->msg_size))
  678. {
  679. return KOSA_StatusSuccess;
  680. }
  681. else
  682. {
  683. return KOSA_StatusError;
  684. }
  685. }
  686. /*FUNCTION**********************************************************************
  687. *
  688. * Function Name : OSA_MsgQGet
  689. * Description : This function checks the queue's status, if it is not empty,
  690. * get message from it and return KOSA_StatusSuccess, otherwise, timeout will
  691. * be used for wait. The parameter timeout indicates how long should wait in
  692. * milliseconds. Pass osaWaitForever_c to wait indefinitely, pass 0 will return
  693. * KOSA_StatusTimeout immediately if queue is empty.
  694. * This function returns KOSA_StatusSuccess if message is got successfully,
  695. * returns KOSA_StatusTimeout if message queue is empty within the specified
  696. * 'timeout', returns KOSA_StatusError if any errors occur during waiting.
  697. *
  698. *END**************************************************************************/
  699. osa_status_t OSA_MsgQGet(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage, uint32_t millisec)
  700. {
  701. osa_status_t osaStatus;
  702. assert(msgqHandle);
  703. rt_mq_t handler = (rt_mq_t)(void *)(uint32_t *)(*(uint32_t *)msgqHandle);
  704. uint32_t timeoutTicks;
  705. if (millisec == osaWaitForever_c)
  706. {
  707. timeoutTicks = RT_WAITING_FOREVER;
  708. }
  709. else
  710. {
  711. timeoutTicks = rt_tick_from_millisecond(millisec);
  712. }
  713. if (RT_EOK != rt_mq_recv(handler, pMessage, handler->msg_size, timeoutTicks))
  714. {
  715. osaStatus = KOSA_StatusTimeout; /* not able to send it to the queue? */
  716. }
  717. else
  718. {
  719. osaStatus = KOSA_StatusSuccess;
  720. }
  721. return osaStatus;
  722. }
  723. /*FUNCTION**********************************************************************
  724. *
  725. * Function Name : OSA_MsgQDestroy
  726. * Description : This function is used to destroy the message queue.
  727. * Return : KOSA_StatusSuccess if the message queue is destroyed successfully, otherwise return KOSA_StatusError.
  728. *
  729. *END**************************************************************************/
  730. osa_status_t OSA_MsgQDestroy(osa_msgq_handle_t msgqHandle)
  731. {
  732. assert(msgqHandle);
  733. rt_mq_t handler = (rt_mq_t)(void *)(uint32_t *)(*(uint32_t *)msgqHandle);
  734. rt_mq_delete(handler);
  735. return KOSA_StatusSuccess;
  736. }
  737. /*FUNCTION**********************************************************************
  738. *
  739. * Function Name : OSA_InterruptEnable
  740. * Description : self explanatory.
  741. *
  742. *END**************************************************************************/
  743. void OSA_InterruptEnable(void)
  744. {
  745. rt_exit_critical();
  746. }
  747. /*FUNCTION**********************************************************************
  748. *
  749. * Function Name : OSA_InterruptDisable
  750. * Description : self explanatory.
  751. *
  752. *END**************************************************************************/
  753. void OSA_InterruptDisable(void)
  754. {
  755. rt_enter_critical();
  756. }
  757. /*FUNCTION**********************************************************************
  758. *
  759. * Function Name : OSA_EnableIRQGlobal
  760. * Description : enable interrupts using PRIMASK register.
  761. *
  762. *END**************************************************************************/
  763. void OSA_EnableIRQGlobal(void)
  764. {
  765. if (s_osaState.interruptDisableCount > 0U)
  766. {
  767. s_osaState.interruptDisableCount--;
  768. if (0U == s_osaState.interruptDisableCount)
  769. {
  770. __enable_irq();
  771. }
  772. /* call core API to enable the global interrupt*/
  773. }
  774. }
  775. /*FUNCTION**********************************************************************
  776. *
  777. * Function Name : OSA_DisableIRQGlobal
  778. * Description : disable interrupts using PRIMASK register.
  779. *
  780. *END**************************************************************************/
  781. void OSA_DisableIRQGlobal(void)
  782. {
  783. /* call core API to disable the global interrupt*/
  784. __disable_irq();
  785. /* update counter*/
  786. s_osaState.interruptDisableCount++;
  787. }
  788. /*FUNCTION**********************************************************************
  789. *
  790. * Function Name : OSA_InstallIntHandler
  791. * Description : This function is used to install interrupt handler.
  792. *
  793. *END**************************************************************************/
  794. void OSA_InstallIntHandler(uint32_t IRQNumber, void (*handler)(void))
  795. {
  796. #if defined(__IAR_SYSTEMS_ICC__)
  797. _Pragma("diag_suppress = Pm138")
  798. #endif
  799. #if defined(ENABLE_RAM_VECTOR_TABLE)
  800. (void) InstallIRQHandler((IRQn_Type)IRQNumber, (uint32_t) * (uint32_t *)&handler);
  801. #endif /* ENABLE_RAM_VECTOR_TABLE. */
  802. #if defined(__IAR_SYSTEMS_ICC__)
  803. _Pragma("diag_remark = PM138")
  804. #endif
  805. }
  806. /*!*********************************************************************************
  807. *************************************************************************************
  808. * Private functions
  809. *************************************************************************************
  810. ********************************************************************************** */
  811. #if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
  812. static OSA_TASK_DEFINE(startup_task, gMainThreadPriority_c, 1, gMainThreadStackSize_c, 0);
  813. int main(void)
  814. {
  815. extern void BOARD_InitHardware(void);
  816. /* Initialize MCU clock */
  817. BOARD_InitHardware();
  818. LIST_Init((&s_osaState.taskList), 0);
  819. s_osaState.basePriorityNesting = 0;
  820. s_osaState.interruptDisableCount = 0;
  821. (void)OSA_TaskCreate((osa_task_handle_t)s_osaState.mainTaskHandle, OSA_TASK(startup_task), NULL);
  822. vTaskStartScheduler();
  823. return 0;
  824. }
  825. #endif /* FSL_OSA_TASK_ENABLE */