cmsis_rtthread.c 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359
  1. /*
  2. * Copyright (c) 2006-2025, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-04-12 misonyo the first version
  9. * 2019-04-04 misonyo fix some bugs
  10. * 2025-08-18 wdfk_prog fix osDelay bug
  11. */
  12. #include <cmsis_os2.h>
  13. #include "cmsis_rtthread.h"
  14. #include <board.h>
  15. #include <os_tick.h>
  16. #include <rthw.h>
  17. #define KERNEL_Id "RT-Thread" ///< Kernel identification string
  18. #define DEFAULT_STACK_SIZE 512
  19. #define DEFAULT_TICK 5
  20. #define WAITING_THREAD_FLAGS 0x08
  21. #define MALLOC_CB 0x10
  22. #define MALLOC_STACK 0x04
  23. #define MALLOC_MEM 0x02
  24. static osKernelState_t kernel_state = osKernelInactive;
  25. static void thread_cleanup(rt_thread_t thread)
  26. {
  27. thread_cb_t *thread_cb;
  28. thread_cb = (thread_cb_t *)(thread->user_data);
  29. /* clear cleanup function */
  30. thread->cleanup = RT_NULL;
  31. if (thread_cb->flags & osThreadJoinable)
  32. {
  33. rt_sem_release(thread_cb->joinable_sem);
  34. }
  35. else
  36. {
  37. if (thread_cb->flags & MALLOC_STACK)
  38. rt_free(thread_cb->thread.stack_addr);
  39. if (thread_cb->flags & MALLOC_CB)
  40. rt_free(thread_cb);
  41. }
  42. }
  43. // ==== Kernel Management Functions ====
  44. // ==== Helper functions ====
  45. /// Block Kernel (disable: thread switching, time tick, post ISR processing).
  46. #ifdef SysTick
  47. static volatile uint8_t blocked; ///< Blocked
  48. static uint8_t pendSV; ///< Pending SV
  49. /// Get Pending SV (Service Call) Flag
  50. /// \return Pending SV Flag
  51. __STATIC_INLINE uint8_t GetPendSV (void)
  52. {
  53. return ((uint8_t)((SCB->ICSR & (SCB_ICSR_PENDSVSET_Msk)) >> 24));
  54. }
  55. /// Clear Pending SV (Service Call) Flag
  56. __STATIC_INLINE void ClrPendSV (void)
  57. {
  58. SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk;
  59. }
  60. /// Set Pending SV (Service Call) Flag
  61. __STATIC_INLINE void SetPendSV (void)
  62. {
  63. SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
  64. }
  65. /// Block Kernel (disable: thread switching, time tick, post ISR processing).
  66. static void KernelBlock (void)
  67. {
  68. OS_Tick_Disable();
  69. blocked = 1U;
  70. __DSB();
  71. if (GetPendSV() != 0U)
  72. {
  73. ClrPendSV();
  74. pendSV = 1U;
  75. }
  76. }
  77. /// Unblock Kernel
  78. static void KernelUnblock (void)
  79. {
  80. blocked = 0U;
  81. __DSB();
  82. if (pendSV != 0U)
  83. {
  84. pendSV = 0U;
  85. SetPendSV();
  86. }
  87. OS_Tick_Enable();
  88. }
  89. #endif
  90. /// Initialize the RTOS Kernel.
  91. /// \return status code that indicates the execution status of the function.
  92. osStatus_t osKernelInitialize(void)
  93. {
  94. kernel_state = osKernelReady;
  95. return osOK;
  96. }
  97. /// Get RTOS Kernel Information.
  98. /// \param[out] version pointer to buffer for retrieving version information.
  99. /// \param[out] id_buf pointer to buffer for retrieving kernel identification string.
  100. /// \param[in] id_size size of buffer for kernel identification string.
  101. /// \return status code that indicates the execution status of the function.
  102. osStatus_t osKernelGetInfo(osVersion_t *version, char *id_buf, uint32_t id_size)
  103. {
  104. if ((RT_NULL == version) || (RT_NULL == id_buf) || id_size < sizeof(KERNEL_Id))
  105. return osErrorParameter;
  106. version->api = KERNEL_VERSION;
  107. version->kernel = KERNEL_VERSION;
  108. id_size = sizeof(KERNEL_Id);
  109. rt_strncpy(id_buf, KERNEL_Id, id_size);
  110. return osOK;
  111. }
  112. /// Get the current RTOS Kernel state.
  113. /// \return current RTOS Kernel state.
  114. osKernelState_t osKernelGetState(void)
  115. {
  116. return kernel_state;
  117. }
  118. /// Start the RTOS Kernel scheduler.
  119. /// \return status code that indicates the execution status of the function.
  120. osStatus_t osKernelStart(void)
  121. {
  122. osStatus_t state;
  123. if (osKernelReady == kernel_state)
  124. {
  125. kernel_state = osKernelRunning;
  126. state = osOK;
  127. }
  128. else
  129. {
  130. state = osError;
  131. }
  132. return state;
  133. }
  134. /// Lock the RTOS Kernel scheduler.
  135. /// \return previous lock state (1 - locked, 0 - not locked, error code if negative).
  136. int32_t osKernelLock(void)
  137. {
  138. rt_uint16_t level;
  139. level = rt_critical_level();
  140. rt_enter_critical();
  141. kernel_state = osKernelLocked;
  142. if (level)
  143. {
  144. return 1;
  145. }
  146. else
  147. {
  148. return 0;
  149. }
  150. }
  151. /// Unlock the RTOS Kernel scheduler.
  152. /// \return previous lock state (1 - locked, 0 - not locked, error code if negative).
  153. int32_t osKernelUnlock(void)
  154. {
  155. rt_uint16_t level;
  156. level = rt_critical_level();
  157. if (0U == level)
  158. {
  159. return 0;
  160. }
  161. else
  162. {
  163. rt_exit_critical();
  164. if (1u == level)
  165. kernel_state = osKernelRunning;
  166. return 1;
  167. }
  168. }
  169. /// Restore the RTOS Kernel scheduler lock state.
  170. /// \param[in] lock lock state obtained by \ref osKernelLock or \ref osKernelUnlock.
  171. /// \return new lock state (1 - locked, 0 - not locked, error code if negative).
  172. int32_t osKernelRestoreLock(int32_t lock)
  173. {
  174. if (1u == lock)
  175. {
  176. osKernelLock();
  177. return 1;
  178. }
  179. else
  180. {
  181. osKernelUnlock();
  182. return 0;
  183. }
  184. }
  185. /// Get the RTOS kernel tick count.
  186. /// \return RTOS kernel current tick count.
  187. uint32_t osKernelGetTickCount(void)
  188. {
  189. return (uint32_t)rt_tick_get();
  190. }
  191. /// Get the RTOS kernel tick frequency.
  192. /// \return frequency of the kernel tick.
  193. uint32_t osKernelGetTickFreq(void)
  194. {
  195. return RT_TICK_PER_SECOND;
  196. }
  197. /// The function returns the current RTOS kernel system timer as a 32-bit value.
  198. /// \return RTOS kernel current system timer count as 32-bit value
  199. #ifdef SysTick
  200. uint32_t osKernelGetSysTimerCount(void)
  201. {
  202. uint32_t irqmask ;
  203. rt_tick_t ticks;
  204. uint32_t val;
  205. irqmask = rt_hw_interrupt_disable();
  206. ticks = rt_tick_get();
  207. val = OS_Tick_GetCount();
  208. if (OS_Tick_GetOverflow() != 0U)
  209. {
  210. val = OS_Tick_GetCount();
  211. ticks++;
  212. }
  213. val += ticks * OS_Tick_GetInterval();
  214. rt_hw_interrupt_enable(irqmask);
  215. return (val);
  216. }
  217. #endif /*SysTick*/
  218. /// Get the RTOS kernel system timer frequency.
  219. /// \return frequency of the system timer.
  220. uint32_t osKernelGetSysTimerFreq(void)
  221. {
  222. return RT_TICK_PER_SECOND;
  223. }
  224. /// Suspend the RTOS Kernel scheduler.
  225. /// \return time in ticks, for how long the system can sleep or power-down.
  226. #ifdef SysTick
  227. uint32_t osKernelSuspend (void)
  228. {
  229. rt_thread_t thread;
  230. rt_timer_t timer;
  231. struct rt_object_information *info_thread;
  232. struct rt_object_information *info_timer;
  233. struct rt_list_node *node;
  234. rt_uint8_t timer_index = 0;
  235. rt_tick_t min_tick = 0;
  236. rt_tick_t cur_tick = 0;
  237. rt_tick_t temp_tick = 0;
  238. if (kernel_state != osKernelRunning)
  239. {
  240. return 0U;
  241. }
  242. info_thread = rt_object_get_information(RT_Object_Class_Thread);
  243. info_timer = rt_object_get_information(RT_Object_Class_Timer);
  244. KernelBlock();
  245. min_tick = osWaitForever;
  246. cur_tick = rt_tick_get();
  247. /*check thread delay list*/
  248. if (info_thread != NULL)
  249. {
  250. for (node = info_thread->object_list.next; node != &(info_thread->object_list); node = node->next)
  251. {
  252. thread = thread_rt_list_entry(node, rt_thread);
  253. if (thread->thread_timer.parent.flag & RT_TIMER_FLAG_ACTIVATED)
  254. {
  255. temp_tick = thread->thread_timer.timeout_tick - cur_tick;
  256. if (temp_tick < min_tick)
  257. {
  258. min_tick = temp_tick;
  259. }
  260. }
  261. }
  262. }
  263. /*check active timer list*/
  264. if (info_timer != NULL)
  265. {
  266. for (node = info_timer->object_list.next; node != &(info_timer->object_list); node = node->next)
  267. {
  268. timer = rt_list_entry(node, struct rt_timer, row[timer_index++]);
  269. if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
  270. {
  271. temp_tick = timer->timeout_tick - cur_tick;
  272. if (temp_tick < min_tick)
  273. {
  274. min_tick = temp_tick;
  275. }
  276. }
  277. }
  278. }
  279. if (osWaitForever == min_tick)
  280. min_tick = 0U;
  281. kernel_state = osKernelSuspended;
  282. return (min_tick);
  283. }
  284. #endif /* SysTick */
  285. /// Resume the RTOS Kernel scheduler.
  286. /// \param[in] sleep_ticks time in ticks for how long the system was in sleep or power-down mode.
  287. #ifdef SysTick
  288. void osKernelResume (uint32_t sleep_ticks)
  289. {
  290. rt_tick_t delay_tick = 0;
  291. if (kernel_state != osKernelSuspended)
  292. {
  293. return;
  294. }
  295. delay_tick = (rt_tick_t)sleep_ticks;
  296. rt_enter_critical();
  297. while(delay_tick > 0)
  298. {
  299. rt_tick_increase(); /*Process Thread Delay list and Process Active Timer list*/
  300. delay_tick --;
  301. }
  302. rt_exit_critical();
  303. kernel_state = osKernelRunning;
  304. KernelUnblock();
  305. return;
  306. }
  307. #endif
  308. // ==== Thread Management Functions ====
  309. /// Create a thread and add it to Active Threads.
  310. /// \param[in] func thread function.
  311. /// \param[in] argument pointer that is passed to the thread function as start argument.
  312. /// \param[in] attr thread attributes; NULL: default values.
  313. /// \return thread ID for reference by other functions or NULL in case of error.
  314. osThreadId_t osThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr)
  315. {
  316. void *stack;
  317. rt_uint8_t rtt_prio;
  318. rt_uint32_t stack_size;
  319. thread_cb_t *thread_cb;
  320. char name[RT_NAME_MAX];
  321. static rt_uint16_t thread_number = 1U;
  322. /* Check parameters */
  323. if (RT_NULL == func)
  324. {
  325. return RT_NULL;
  326. }
  327. if ((RT_NULL == attr) || (RT_NULL == attr->cb_mem))
  328. {
  329. thread_cb = rt_malloc(sizeof(thread_cb_t));
  330. if (RT_NULL == thread_cb)
  331. return RT_NULL;
  332. rt_memset(thread_cb, 0, sizeof(thread_cb_t));
  333. thread_cb->flags |= MALLOC_CB;
  334. }
  335. else
  336. {
  337. if (attr->cb_size >= sizeof(thread_cb_t))
  338. {
  339. thread_cb = attr->cb_mem;
  340. thread_cb->flags = 0;
  341. }
  342. else
  343. return RT_NULL;
  344. }
  345. if ((RT_NULL == attr) || (RT_NULL == attr->name))
  346. rt_snprintf(name, sizeof(name), "th%02d", thread_number ++);
  347. else
  348. rt_snprintf(name, sizeof(name), "%s", attr->name);
  349. if ((RT_NULL == attr) || (osPriorityNone == attr->priority))
  350. {
  351. thread_cb->prio = osPriorityNormal;
  352. }
  353. else
  354. {
  355. if ((attr->priority < osPriorityIdle) || (attr->priority > osPriorityISR))
  356. return RT_NULL;
  357. thread_cb->prio = attr->priority;
  358. }
  359. if ((RT_NULL == attr) || (0U == attr->stack_size))
  360. stack_size = DEFAULT_STACK_SIZE;
  361. else
  362. stack_size = attr->stack_size;
  363. if ((RT_NULL == attr) || (RT_NULL == attr->stack_mem))
  364. {
  365. stack = rt_malloc(stack_size);
  366. if (RT_NULL == stack)
  367. {
  368. if (thread_cb->flags & MALLOC_CB)
  369. rt_free(thread_cb);
  370. return RT_NULL;
  371. }
  372. thread_cb->flags |= MALLOC_STACK;
  373. }
  374. else
  375. {
  376. stack = (void *)(attr->stack_mem);
  377. }
  378. if ((RT_NULL != attr) && (0 != attr->attr_bits))
  379. thread_cb->flags |= attr->attr_bits;
  380. rtt_prio = (osPriorityISR - thread_cb->prio) * RT_THREAD_PRIORITY_MAX / osPriorityISR;
  381. rt_thread_init(&(thread_cb->thread), name, func, argument, stack, stack_size, rtt_prio, DEFAULT_TICK);
  382. if (thread_cb->flags & osThreadJoinable)
  383. {
  384. thread_cb->joinable_sem = rt_sem_create(name, 0, RT_IPC_FLAG_FIFO);
  385. if (RT_NULL == thread_cb->joinable_sem)
  386. {
  387. if (thread_cb->flags & MALLOC_CB)
  388. rt_free(thread_cb);
  389. if (thread_cb->flags & MALLOC_STACK)
  390. rt_free(stack);
  391. return RT_NULL;
  392. }
  393. }
  394. else
  395. thread_cb->joinable_sem = RT_NULL;
  396. thread_cb->thread.cleanup = thread_cleanup;
  397. thread_cb->thread.user_data = (rt_uint32_t)thread_cb;
  398. rt_thread_startup(&(thread_cb->thread));
  399. return thread_cb;
  400. }
  401. /// Get name of a thread.
  402. /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
  403. /// \return name as NULL terminated string.
  404. const char *osThreadGetName(osThreadId_t thread_id)
  405. {
  406. thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
  407. /* Check parameters */
  408. if ((RT_NULL == thread_cb) || (rt_object_get_type((rt_object_t)(&thread_cb->thread)) != RT_Object_Class_Thread))
  409. {
  410. return RT_NULL;
  411. }
  412. return THREAD_NAME(thread_cb);
  413. }
  414. /// Return the thread ID of the current running thread.
  415. /// \return thread ID for reference by other functions or NULL in case of error.
  416. osThreadId_t osThreadGetId(void)
  417. {
  418. rt_thread_t thread;
  419. thread = rt_thread_self();
  420. return (osThreadId_t)(thread->user_data);
  421. }
  422. /// Get current thread state of a thread.
  423. /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
  424. /// \return current thread state of the specified thread.
  425. osThreadState_t osThreadGetState(osThreadId_t thread_id)
  426. {
  427. osThreadState_t state;
  428. thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
  429. /* Check parameters */
  430. if ((RT_NULL == thread_cb) || (rt_object_get_type((rt_object_t)(&thread_cb->thread)) != RT_Object_Class_Thread))
  431. {
  432. return osThreadError;
  433. }
  434. switch (CMSIS_RT_SCHED_CTX(thread_cb->thread).stat)
  435. {
  436. case RT_THREAD_INIT:
  437. state = osThreadInactive;
  438. break;
  439. case RT_THREAD_READY:
  440. state = osThreadReady;
  441. break;
  442. case RT_THREAD_SUSPEND:
  443. state = osThreadBlocked;
  444. break;
  445. case RT_THREAD_RUNNING:
  446. state = osThreadRunning;
  447. break;
  448. case RT_THREAD_CLOSE:
  449. state = osThreadTerminated;
  450. break;
  451. default:
  452. state = osThreadError;
  453. break;
  454. }
  455. return state;
  456. }
  457. /// Get stack size of a thread.
  458. /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
  459. /// \return stack size in bytes.
  460. uint32_t osThreadGetStackSize(osThreadId_t thread_id)
  461. {
  462. thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
  463. /* Check parameters */
  464. if ((RT_NULL == thread_cb) || (rt_object_get_type((rt_object_t)(&thread_cb->thread)) != RT_Object_Class_Thread))
  465. {
  466. return 0U;
  467. }
  468. return ((uint32_t)thread_cb->thread.stack_size);
  469. }
  470. /// Get available stack space of a thread based on stack watermark recording during execution.
  471. /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
  472. /// \return remaining stack space in bytes.
  473. uint32_t osThreadGetStackSpace(osThreadId_t thread_id)
  474. {
  475. rt_uint8_t *ptr;
  476. thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
  477. /* Check parameters */
  478. if ((RT_NULL == thread_cb) || (rt_object_get_type((rt_object_t)(&thread_cb->thread)) != RT_Object_Class_Thread))
  479. {
  480. return 0U;
  481. }
  482. ptr = (rt_uint8_t *)thread_cb->thread.stack_addr;
  483. while (*ptr == '#')ptr ++;
  484. return (ptr - (rt_uint8_t *)thread_cb->thread.stack_addr);
  485. }
  486. /// Change priority of a thread.
  487. /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
  488. /// \param[in] priority new priority value for the thread function.
  489. /// \return status code that indicates the execution status of the function.
  490. osStatus_t osThreadSetPriority(osThreadId_t thread_id, osPriority_t priority)
  491. {
  492. rt_uint8_t rt_priority;
  493. thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
  494. // Check parameters
  495. if ((RT_NULL == thread_cb) || (priority < osPriorityIdle) || (priority > osPriorityISR))
  496. {
  497. return osErrorParameter;
  498. }
  499. thread_cb->prio = priority;
  500. rt_priority = (osPriorityISR - thread_cb->prio) * RT_THREAD_PRIORITY_MAX / osPriorityISR;
  501. rt_thread_control(&(thread_cb->thread), RT_THREAD_CTRL_CHANGE_PRIORITY, &rt_priority);
  502. return osOK;
  503. }
  504. /// Get current priority of a thread.
  505. /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
  506. /// \return current priority value of the specified thread.
  507. osPriority_t osThreadGetPriority(osThreadId_t thread_id)
  508. {
  509. thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
  510. /* Check parameters */
  511. if ((RT_NULL == thread_cb) || (rt_object_get_type((rt_object_t)(&thread_cb->thread)) != RT_Object_Class_Thread))
  512. {
  513. return osPriorityError;
  514. }
  515. return (osPriority_t)thread_cb->prio;
  516. }
  517. /// Pass control to next thread that is in state \b READY.
  518. /// \return status code that indicates the execution status of the function.
  519. osStatus_t osThreadYield(void)
  520. {
  521. rt_thread_yield();
  522. return osOK;
  523. }
  524. /// Suspend execution of a thread.
  525. /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
  526. /// \return status code that indicates the execution status of the function.
  527. osStatus_t osThreadSuspend(osThreadId_t thread_id)
  528. {
  529. rt_err_t result;
  530. thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
  531. /* Check parameters */
  532. if (RT_NULL == thread_cb)
  533. {
  534. return osErrorParameter;
  535. }
  536. result = rt_thread_suspend(&(thread_cb->thread));
  537. if (RT_EOK == result)
  538. return osOK;
  539. else
  540. return osError;
  541. }
  542. /// Resume execution of a thread.
  543. /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
  544. /// \return status code that indicates the execution status of the function.
  545. osStatus_t osThreadResume(osThreadId_t thread_id)
  546. {
  547. rt_err_t result;
  548. thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
  549. /* Check parameters */
  550. if (RT_NULL == thread_cb)
  551. {
  552. return osErrorParameter;
  553. }
  554. result = rt_thread_resume(&(thread_cb->thread));
  555. if (RT_EOK == result)
  556. return osOK;
  557. else
  558. return osError;
  559. }
  560. /// Detach a thread (thread storage can be reclaimed when thread terminates).
  561. /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
  562. /// \return status code that indicates the execution status of the function.
  563. osStatus_t osThreadDetach(osThreadId_t thread_id)
  564. {
  565. thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
  566. /* Check parameters */
  567. if ((RT_NULL == thread_cb) || (rt_object_get_type((rt_object_t)(&thread_cb->thread)) != RT_Object_Class_Thread))
  568. {
  569. return osErrorParameter;
  570. }
  571. /* Check object attributes */
  572. /*
  573. if ((thread_cb->flags & osThreadJoinable) == 0)
  574. {
  575. return osErrorResource;
  576. }
  577. */
  578. if ((CMSIS_RT_SCHED_CTX(thread_cb->thread).stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE)
  579. {
  580. rt_thread_detach(&(thread_cb->thread));
  581. if (thread_cb->flags & osThreadJoinable)
  582. rt_sem_delete(thread_cb->joinable_sem);
  583. if (thread_cb->flags & MALLOC_STACK)
  584. rt_free(thread_cb->thread.stack_addr);
  585. if (thread_cb->flags & MALLOC_CB)
  586. rt_free(thread_cb);
  587. }
  588. else
  589. {
  590. rt_enter_critical();
  591. /* change to detach state */
  592. thread_cb->flags &= ~osThreadJoinable;
  593. /* delete joinable semaphore */
  594. if (RT_NULL != thread_cb->joinable_sem)
  595. {
  596. rt_sem_delete(thread_cb->joinable_sem);
  597. thread_cb->joinable_sem = RT_NULL;
  598. }
  599. /* detach thread object */
  600. rt_thread_detach(&thread_cb->thread);
  601. rt_exit_critical();
  602. }
  603. return osOK;
  604. }
  605. /// Wait for specified thread to terminate.
  606. /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
  607. /// \return status code that indicates the execution status of the function.
  608. osStatus_t osThreadJoin(osThreadId_t thread_id)
  609. {
  610. rt_err_t result;
  611. thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
  612. /* Check parameters */
  613. if (RT_NULL == thread_cb)
  614. {
  615. return osErrorParameter;
  616. }
  617. if (((&thread_cb->thread) == rt_thread_self()) ||
  618. (0 == (thread_cb->flags & osThreadJoinable)))
  619. {
  620. /* join self or join a detached thread*/
  621. return osErrorResource;
  622. }
  623. result = rt_sem_take(thread_cb->joinable_sem, RT_WAITING_FOREVER);
  624. if (RT_EOK == result)
  625. {
  626. /* release resource */
  627. if (thread_cb->flags & osThreadJoinable)
  628. rt_sem_delete(thread_cb->joinable_sem);
  629. if (thread_cb->flags & MALLOC_STACK)
  630. rt_free(thread_cb->thread.stack_addr);
  631. if (thread_cb->flags & MALLOC_CB)
  632. rt_free(thread_cb);
  633. return osOK;
  634. }
  635. else if (-RT_ETIMEOUT == result)
  636. {
  637. return osErrorTimeout;
  638. }
  639. else
  640. {
  641. return osError;
  642. }
  643. }
  644. /// Terminate execution of current running thread.
  645. __NO_RETURN void osThreadExit(void)
  646. {
  647. rt_thread_t self = rt_thread_self();
  648. rt_thread_control(self, RT_THREAD_CTRL_CLOSE, RT_NULL);
  649. RT_ASSERT(0);
  650. while(1);
  651. }
  652. /// Terminate execution of a thread.
  653. /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
  654. /// \return status code that indicates the execution status of the function.
  655. osStatus_t osThreadTerminate(osThreadId_t thread_id)
  656. {
  657. thread_cb_t *thread_cb;
  658. thread_cb = (thread_cb_t *)(rt_thread_self()->user_data);
  659. /* Check parameters */
  660. if (RT_NULL == thread_cb)
  661. {
  662. return osErrorParameter;
  663. }
  664. rt_thread_detach(&(thread_cb->thread));
  665. rt_schedule();
  666. return osOK;
  667. }
  668. /// Get number of active threads.
  669. /// \return number of active threads.
  670. uint32_t osThreadGetCount(void)
  671. {
  672. rt_uint32_t thread_count = 0U;
  673. struct rt_object_information *info;
  674. info = rt_object_get_information(RT_Object_Class_Thread);
  675. rt_enter_critical();
  676. thread_count = rt_list_len(&(info->object_list));
  677. rt_exit_critical();
  678. return thread_count;
  679. }
  680. /// Enumerate active threads.
  681. /// \param[out] thread_array pointer to array for retrieving thread IDs.
  682. /// \param[in] array_items maximum number of items in array for retrieving thread IDs.
  683. /// \return number of enumerated threads.
  684. uint32_t osThreadEnumerate(osThreadId_t *thread_array, uint32_t array_items)
  685. {
  686. rt_uint32_t thread_count = 0U;
  687. rt_thread_t thread;
  688. struct rt_object_information *info;
  689. struct rt_list_node *node;
  690. /* Check parameters */
  691. if ((RT_NULL == thread_array) || (0U == array_items))
  692. {
  693. return 0U;
  694. }
  695. info = rt_object_get_information(RT_Object_Class_Thread);
  696. rt_enter_critical();
  697. for (node = info->object_list.next; node != &(info->object_list); node = node->next)
  698. {
  699. thread = thread_rt_list_entry(node, rt_thread);
  700. thread_array[thread_count] = (osThreadId_t)thread;
  701. thread_count++;
  702. if (thread_count >= array_items)
  703. break;
  704. }
  705. rt_exit_critical();
  706. return thread_count;
  707. }
  708. // ==== Thread Flags Functions ====
  709. /// Set the specified Thread Flags of a thread.
  710. /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
  711. /// \param[in] flags specifies the flags of the thread that shall be set.
  712. /// \return thread flags after setting or error code if highest bit set.
  713. uint32_t osThreadFlagsSet(osThreadId_t thread_id, uint32_t flags)
  714. {
  715. register rt_base_t status;
  716. register rt_ubase_t level;
  717. rt_bool_t need_schedule = RT_FALSE;
  718. thread_cb_t *thread_cb;
  719. rt_uint32_t return_value;
  720. thread_cb = (thread_cb_t *)(thread_id);
  721. /* Check parameters */
  722. if ((RT_NULL == thread_cb) || (rt_object_get_type((rt_object_t)(&thread_cb->thread)) != RT_Object_Class_Thread))
  723. {
  724. return osFlagsErrorParameter;
  725. }
  726. level = rt_hw_interrupt_disable();
  727. thread_cb->flag_set |= flags;
  728. return_value = thread_cb->flag_set;
  729. /* Check if Thread is waiting for Thread Flags */
  730. if (thread_cb->thread.event_info & WAITING_THREAD_FLAGS)
  731. {
  732. status = -RT_ERROR;
  733. if (thread_cb->thread.event_info & osFlagsWaitAll)
  734. {
  735. if ((thread_cb->thread.event_set & thread_cb->flag_set) == thread_cb->thread.event_set)
  736. {
  737. /* received an AND event */
  738. status = RT_EOK;
  739. }
  740. }
  741. else
  742. {
  743. if (thread_cb->thread.event_set & thread_cb->flag_set)
  744. {
  745. /* save recieved event set */
  746. thread_cb->thread.event_set &= thread_cb->flag_set;
  747. /* received an OR event */
  748. status = RT_EOK;
  749. }
  750. }
  751. /* condition is satisfied, resume thread */
  752. if (RT_EOK == status)
  753. {
  754. thread_cb->thread.event_info &= ~WAITING_THREAD_FLAGS;
  755. /* clear event */
  756. if (!(thread_cb->thread.event_info & osFlagsNoClear))
  757. thread_cb->flag_set &= ~thread_cb->thread.event_set;
  758. /* resume thread, and thread list breaks out */
  759. rt_thread_resume(&(thread_cb->thread));
  760. need_schedule = RT_TRUE;
  761. }
  762. }
  763. rt_hw_interrupt_enable(level);
  764. if (need_schedule == RT_TRUE)
  765. rt_schedule();
  766. return return_value;
  767. }
  768. /// Clear the specified Thread Flags of current running thread.
  769. /// \param[in] flags specifies the flags of the thread that shall be cleared.
  770. /// \return thread flags before clearing or error code if highest bit set.
  771. uint32_t osThreadFlagsClear(uint32_t flags)
  772. {
  773. rt_thread_t thread = rt_thread_self();
  774. thread_cb_t *thread_cb;
  775. rt_uint32_t flag;
  776. /* Check parameters */
  777. if (RT_NULL == thread)
  778. {
  779. return osFlagsErrorParameter;
  780. }
  781. thread_cb = (thread_cb_t *)(thread->user_data);
  782. rt_enter_critical();
  783. flag = thread_cb->flag_set;
  784. thread_cb->flag_set &= ~flags;
  785. rt_exit_critical();
  786. return flag;
  787. }
  788. /// Get the current Thread Flags of current running thread.
  789. /// \return current thread flags.
  790. uint32_t osThreadFlagsGet(void)
  791. {
  792. rt_thread_t thread = rt_thread_self();
  793. thread_cb_t *thread_cb;
  794. /* Check parameters */
  795. if (RT_NULL == thread)
  796. {
  797. return osFlagsErrorParameter;
  798. }
  799. thread_cb = (thread_cb_t *)(thread->user_data);
  800. return thread_cb->flag_set;
  801. }
  802. /// Wait for one or more Thread Flags of the current running thread to become signaled.
  803. /// \param[in] flags specifies the flags to wait for.
  804. /// \param[in] options specifies flags options (osFlagsXxxx).
  805. /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
  806. /// \return thread flags before clearing or error code if highest bit set.
  807. uint32_t osThreadFlagsWait(uint32_t flags, uint32_t options, uint32_t timeout)
  808. {
  809. rt_uint32_t return_value;
  810. register rt_ubase_t level;
  811. register rt_base_t status = -RT_ERROR;
  812. rt_thread_t thread = rt_thread_self();
  813. thread_cb_t *thread_cb;
  814. /* Check parameters */
  815. if (RT_NULL == thread)
  816. {
  817. return osFlagsErrorParameter;
  818. }
  819. thread->error = RT_EOK;
  820. thread_cb = (thread_cb_t *)(thread->user_data);
  821. level = rt_hw_interrupt_disable();
  822. if (options & osFlagsWaitAll)
  823. {
  824. if ((thread_cb->flag_set & flags) == flags)
  825. status = RT_EOK;
  826. }
  827. else
  828. {
  829. if (thread_cb->flag_set & flags)
  830. status = RT_EOK;
  831. }
  832. if (RT_EOK == status)
  833. {
  834. return_value = thread_cb->flag_set & flags;
  835. if (!(options & osFlagsNoClear))
  836. thread_cb->flag_set &= ~flags;
  837. }
  838. else if (0U == timeout)
  839. {
  840. rt_hw_interrupt_enable(level);
  841. return osFlagsErrorResource;
  842. }
  843. else
  844. {
  845. thread->event_set = flags;
  846. thread->event_info = options | WAITING_THREAD_FLAGS;
  847. rt_thread_suspend(thread);
  848. /* if there is a waiting timeout, active thread timer */
  849. if ((timeout > 0U) && (timeout != osWaitForever))
  850. {
  851. /* reset the timeout of thread timer and start it */
  852. rt_timer_control(&(thread->thread_timer),
  853. RT_TIMER_CTRL_SET_TIME,
  854. &timeout);
  855. rt_timer_start(&(thread->thread_timer));
  856. }
  857. rt_hw_interrupt_enable(level);
  858. rt_schedule();
  859. if (thread->error != RT_EOK)
  860. {
  861. return thread->error;
  862. }
  863. level = rt_hw_interrupt_disable();
  864. return_value = thread->event_set;
  865. }
  866. rt_hw_interrupt_enable(level);
  867. return return_value;
  868. }
  869. // ==== Generic Wait Functions ====
  870. /// Wait for Timeout (Time Delay).
  871. /// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value
  872. /// \return status code that indicates the execution status of the function.
  873. osStatus_t osDelay(uint32_t ticks)
  874. {
  875. if (rt_interrupt_get_nest() != 0)
  876. {
  877. return osErrorISR;
  878. }
  879. else
  880. {
  881. if(rt_thread_delay(ticks) != RT_EOK)
  882. {
  883. return osError;
  884. }
  885. else
  886. {
  887. return osOK;
  888. }
  889. }
  890. }
  891. /// Wait until specified time.
  892. /// \param[in] ticks absolute time in ticks
  893. /// \return status code that indicates the execution status of the function.
  894. osStatus_t osDelayUntil(uint32_t ticks)
  895. {
  896. uint64_t cur_ticks;
  897. cur_ticks = rt_tick_get();
  898. if (ticks == cur_ticks)
  899. {
  900. }
  901. else if (ticks > cur_ticks)
  902. {
  903. rt_thread_delay(ticks - cur_ticks);
  904. }
  905. else
  906. {
  907. rt_thread_delay(((rt_uint32_t) - 1) - cur_ticks + ticks);
  908. }
  909. return osOK;
  910. }
  911. // ==== Timer Management Functions ====
  912. /// Create and Initialize a timer.
  913. /// \param[in] func start address of a timer call back function.
  914. /// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
  915. /// \param[in] argument argument to the timer call back function.
  916. /// \param[in] attr timer attributes; NULL: default values.
  917. /// \return timer ID for reference by other functions or NULL in case of error.
  918. osTimerId_t osTimerNew(osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr)
  919. {
  920. timer_cb_t *timer_cb;
  921. char name[RT_NAME_MAX];
  922. static rt_uint16_t timer_number = 0U;
  923. rt_uint8_t flag = RT_TIMER_FLAG_SOFT_TIMER;
  924. /* Check parameters */
  925. if ((RT_NULL == func) || ((type != osTimerOnce) && (type != osTimerPeriodic)))
  926. {
  927. return RT_NULL;
  928. }
  929. /* RT-Thread object's name can't be NULL */
  930. if ((RT_NULL == attr) || (RT_NULL == attr->name))
  931. rt_snprintf(name, sizeof(name), "timer%02d", timer_number++);
  932. else
  933. rt_snprintf(name, sizeof(name), "%s", attr->name);
  934. if ((RT_NULL == attr) || (RT_NULL == attr->cb_mem))
  935. {
  936. timer_cb = rt_malloc(sizeof(timer_cb_t));
  937. if (RT_NULL == timer_cb)
  938. return RT_NULL;
  939. rt_memset(timer_cb, 0, sizeof(timer_cb_t));
  940. timer_cb->flags |= MALLOC_CB;
  941. }
  942. else
  943. {
  944. if (attr->cb_size >= sizeof(timer_cb_t))
  945. {
  946. timer_cb = attr->cb_mem;
  947. timer_cb->flags = 0;
  948. }
  949. else
  950. return RT_NULL;
  951. }
  952. if (osTimerPeriodic == type)
  953. {
  954. flag |= RT_TIMER_FLAG_PERIODIC;
  955. }
  956. rt_timer_init(&(timer_cb->timer), name, func, argument, 0, flag);
  957. return timer_cb;
  958. }
  959. /// Get name of a timer.
  960. /// \param[in] timer_id timer ID obtained by \ref osTimerNew.
  961. /// \return name as NULL terminated string.
  962. const char *osTimerGetName(osTimerId_t timer_id)
  963. {
  964. timer_cb_t *timer_cb;
  965. timer_cb = (timer_cb_t *)timer_id;
  966. /* Check parameters */
  967. if ((RT_NULL == timer_cb) || (rt_object_get_type(&timer_cb->timer.parent) != RT_Object_Class_Timer))
  968. {
  969. return RT_NULL;
  970. }
  971. return timer_cb->timer.parent.name;
  972. }
  973. /// Start or restart a timer.
  974. /// \param[in] timer_id timer ID obtained by \ref osTimerNew.
  975. /// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer.
  976. /// \return status code that indicates the execution status of the function.
  977. osStatus_t osTimerStart(osTimerId_t timer_id, uint32_t ticks)
  978. {
  979. rt_err_t result;
  980. timer_cb_t *timer_cb;
  981. timer_cb = (timer_cb_t *)timer_id;
  982. /* Check parameters */
  983. if ((RT_NULL == timer_cb) || (ticks == 0))
  984. {
  985. return osErrorParameter;
  986. }
  987. rt_timer_control(&(timer_cb->timer), RT_TIMER_CTRL_SET_TIME, &ticks);
  988. result = rt_timer_start(&(timer_cb->timer));
  989. if (RT_EOK == result)
  990. return osOK;
  991. else
  992. return osError;
  993. }
  994. /// Stop a timer.
  995. /// \param[in] timer_id timer ID obtained by \ref osTimerNew.
  996. /// \return status code that indicates the execution status of the function.
  997. osStatus_t osTimerStop(osTimerId_t timer_id)
  998. {
  999. rt_err_t result;
  1000. timer_cb_t *timer_cb;
  1001. timer_cb = (timer_cb_t *)timer_id;
  1002. /* Check parameters */
  1003. if (RT_NULL == timer_cb)
  1004. {
  1005. return osErrorParameter;
  1006. }
  1007. result = rt_timer_stop(&(timer_cb->timer));
  1008. if (RT_EOK == result)
  1009. return osOK;
  1010. else
  1011. return osError;
  1012. }
  1013. /// Check if a timer is running.
  1014. /// \param[in] timer_id timer ID obtained by \ref osTimerNew.
  1015. /// \return 0 not running, 1 running.
  1016. uint32_t osTimerIsRunning(osTimerId_t timer_id)
  1017. {
  1018. timer_cb_t *timer_cb;
  1019. timer_cb = (timer_cb_t *)timer_id;
  1020. /* Check parameters */
  1021. if ((RT_NULL == timer_cb) || (rt_object_get_type(&timer_cb->timer.parent) != RT_Object_Class_Timer))
  1022. {
  1023. return 0U;
  1024. }
  1025. if ((timer_cb->timer.parent.flag & RT_TIMER_FLAG_ACTIVATED) == 1u)
  1026. {
  1027. return 1;
  1028. }
  1029. else
  1030. return 0U;
  1031. }
  1032. /// Delete a timer.
  1033. /// \param[in] timer_id timer ID obtained by \ref osTimerNew.
  1034. /// \return status code that indicates the execution status of the function.
  1035. osStatus_t osTimerDelete(osTimerId_t timer_id)
  1036. {
  1037. timer_cb_t *timer_cb;
  1038. timer_cb = (timer_cb_t *)timer_id;
  1039. /* Check parameters */
  1040. if (RT_NULL == timer_cb)
  1041. {
  1042. return osErrorParameter;
  1043. }
  1044. rt_timer_detach(&(timer_cb->timer));
  1045. if (timer_cb->flags & MALLOC_CB)
  1046. rt_free(timer_cb);
  1047. return osOK;
  1048. }
  1049. #ifdef RT_USING_EVENT
  1050. // ==== Event Flags Management Functions ====
  1051. /// Create and Initialize an Event Flags object.
  1052. /// \param[in] attr event flags attributes; NULL: default values.
  1053. /// \return event flags ID for reference by other functions or NULL in case of error.
  1054. osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t *attr)
  1055. {
  1056. char name[RT_NAME_MAX];
  1057. event_cb_t *event_cb;
  1058. static rt_uint16_t event_number = 0U;
  1059. if ((RT_NULL == attr) || (RT_NULL == attr->name))
  1060. {
  1061. rt_snprintf(name, sizeof(name), "event%02d", event_number++);
  1062. }
  1063. else
  1064. rt_snprintf(name, sizeof(name), "%s", attr->name);
  1065. if ((RT_NULL == attr) || (RT_NULL == attr->cb_mem))
  1066. {
  1067. event_cb = rt_malloc(sizeof(event_cb_t));
  1068. if (RT_NULL == event_cb)
  1069. return RT_NULL;
  1070. rt_memset(event_cb, 0, sizeof(event_cb_t));
  1071. event_cb->flags |= MALLOC_CB;
  1072. }
  1073. else
  1074. {
  1075. if (attr->cb_size >= sizeof(event_cb_t))
  1076. {
  1077. event_cb = attr->cb_mem;
  1078. event_cb->flags = 0;
  1079. }
  1080. else
  1081. return RT_NULL;
  1082. }
  1083. rt_event_init(&(event_cb->event), name, RT_IPC_FLAG_FIFO);
  1084. return event_cb;
  1085. }
  1086. /// Get name of an Event Flags object.
  1087. /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
  1088. /// \return name as NULL terminated string.
  1089. const char *osEventFlagsGetName(osEventFlagsId_t ef_id)
  1090. {
  1091. event_cb_t *event_cb = (event_cb_t *)ef_id;
  1092. /* Check parameters */
  1093. if ((RT_NULL == event_cb) || (rt_object_get_type(&event_cb->event.parent.parent) != RT_Object_Class_Event))
  1094. {
  1095. return RT_NULL;
  1096. }
  1097. return event_cb->event.parent.parent.name;
  1098. }
  1099. /// Set the specified Event Flags.
  1100. /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
  1101. /// \param[in] flags specifies the flags that shall be set.
  1102. /// \return event flags after setting or error code if highest bit set.
  1103. uint32_t osEventFlagsSet(osEventFlagsId_t ef_id, uint32_t flags)
  1104. {
  1105. rt_err_t result;
  1106. rt_uint32_t set_flags;
  1107. event_cb_t *event_cb = (event_cb_t *)ef_id;
  1108. /* Check parameters */
  1109. if ((RT_NULL == event_cb) || (rt_object_get_type(&event_cb->event.parent.parent) != RT_Object_Class_Event))
  1110. {
  1111. return ((uint32_t)osFlagsErrorParameter);
  1112. }
  1113. set_flags = event_cb->event.set |= flags;
  1114. result = rt_event_send(&(event_cb->event), flags);
  1115. if (RT_EOK == result)
  1116. return set_flags;
  1117. else
  1118. return osFlagsError;
  1119. }
  1120. /// Clear the specified Event Flags.
  1121. /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
  1122. /// \param[in] flags specifies the flags that shall be cleared.
  1123. /// \return event flags before clearing or error code if highest bit set.
  1124. uint32_t osEventFlagsClear(osEventFlagsId_t ef_id, uint32_t flags)
  1125. {
  1126. rt_uint32_t set_flags;
  1127. register rt_ubase_t level;
  1128. event_cb_t *event_cb = (event_cb_t *)ef_id;
  1129. /* Check parameters */
  1130. if ((RT_NULL == event_cb) || (rt_object_get_type(&event_cb->event.parent.parent) != RT_Object_Class_Event))
  1131. {
  1132. return ((uint32_t)osFlagsErrorParameter);
  1133. }
  1134. set_flags = event_cb->event.set;
  1135. level = rt_hw_interrupt_disable();
  1136. event_cb->event.set &= ~flags;
  1137. rt_hw_interrupt_enable(level);
  1138. return set_flags;
  1139. }
  1140. /// Get the current Event Flags.
  1141. /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
  1142. /// \return current event flags.
  1143. uint32_t osEventFlagsGet(osEventFlagsId_t ef_id)
  1144. {
  1145. event_cb_t *event_cb = (event_cb_t *)ef_id;
  1146. /* Check parameters */
  1147. if ((RT_NULL == event_cb) || (rt_object_get_type(&event_cb->event.parent.parent) != RT_Object_Class_Event))
  1148. {
  1149. return 0U;
  1150. }
  1151. return event_cb->event.set;
  1152. }
  1153. /// Wait for one or more Event Flags to become signaled.
  1154. /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
  1155. /// \param[in] flags specifies the flags to wait for.
  1156. /// \param[in] options specifies flags options (osFlagsXxxx).
  1157. /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
  1158. /// \return event flags before clearing or error code if highest bit set.
  1159. uint32_t osEventFlagsWait(osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout)
  1160. {
  1161. rt_err_t result;
  1162. rt_uint32_t rt_recv;
  1163. rt_uint8_t rt_options = 0U;
  1164. event_cb_t *event_cb = (event_cb_t *)ef_id;
  1165. /* Check parameters */
  1166. if (RT_NULL == event_cb)
  1167. {
  1168. return ((uint32_t)osFlagsErrorParameter);
  1169. }
  1170. if (options & osFlagsWaitAll)
  1171. {
  1172. rt_options |= RT_EVENT_FLAG_AND;
  1173. }
  1174. else
  1175. {
  1176. rt_options |= RT_EVENT_FLAG_OR;
  1177. }
  1178. if (!(options & osFlagsNoClear))
  1179. {
  1180. rt_options |= RT_EVENT_FLAG_CLEAR;
  1181. }
  1182. if(timeout == osWaitForever)
  1183. {
  1184. timeout = RT_WAITING_FOREVER;
  1185. }
  1186. result = rt_event_recv(&(event_cb->event), flags, (rt_uint8_t)rt_options, timeout, &rt_recv);
  1187. if (RT_EOK == result)
  1188. return rt_recv;
  1189. else if (-RT_ETIMEOUT == result)
  1190. {
  1191. if (0U == timeout)
  1192. return osFlagsErrorResource;
  1193. else
  1194. return osFlagsErrorTimeout;
  1195. }
  1196. else
  1197. return osFlagsErrorUnknown;
  1198. }
  1199. /// Delete an Event Flags object.
  1200. /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
  1201. /// \return status code that indicates the execution status of the function.
  1202. osStatus_t osEventFlagsDelete(osEventFlagsId_t ef_id)
  1203. {
  1204. event_cb_t *event_cb = (event_cb_t *)ef_id;
  1205. /* Check parameters */
  1206. if (RT_NULL == event_cb)
  1207. {
  1208. return osErrorParameter;
  1209. }
  1210. rt_event_detach(&(event_cb->event));
  1211. if (event_cb->flags & MALLOC_CB)
  1212. rt_free(event_cb);
  1213. return osOK;
  1214. }
  1215. #endif
  1216. #ifdef RT_USING_MUTEX
  1217. // ==== Mutex Management Functions ====
  1218. /// Create and Initialize a Mutex object.
  1219. /// \param[in] attr mutex attributes; NULL: default values.
  1220. /// \return mutex ID for reference by other functions or NULL in case of error.
  1221. osMutexId_t osMutexNew(const osMutexAttr_t *attr)
  1222. {
  1223. char name[RT_NAME_MAX];
  1224. mutex_cb_t *mutex_cb;
  1225. static rt_uint16_t mutex_number = 0U;
  1226. if ((RT_NULL == attr) || (RT_NULL == attr->name))
  1227. {
  1228. rt_snprintf(name, sizeof(name), "mutex%02d", mutex_number++);
  1229. }
  1230. else
  1231. rt_snprintf(name, sizeof(name), "%s", attr->name);
  1232. if ((RT_NULL == attr) || (RT_NULL == attr->cb_mem))
  1233. {
  1234. mutex_cb = rt_malloc(sizeof(mutex_cb_t));
  1235. if (RT_NULL == mutex_cb)
  1236. return RT_NULL;
  1237. rt_memset(mutex_cb, 0, sizeof(mutex_cb_t));
  1238. mutex_cb->flags |= MALLOC_CB;
  1239. }
  1240. else
  1241. {
  1242. if (attr->cb_size >= sizeof(mutex_cb_t))
  1243. {
  1244. mutex_cb = attr->cb_mem;
  1245. mutex_cb->flags = 0;
  1246. }
  1247. else
  1248. return RT_NULL;
  1249. }
  1250. if ((RT_NULL == attr) || (0 == attr->attr_bits))
  1251. {
  1252. mutex_cb->flags |= osMutexRecursive;
  1253. }
  1254. else
  1255. mutex_cb->flags |= attr->attr_bits;
  1256. rt_mutex_init(&(mutex_cb->mutex), name, RT_IPC_FLAG_FIFO);
  1257. return mutex_cb;
  1258. }
  1259. /// Get name of a Mutex object.
  1260. /// \param[in] mutex_id mutex ID obtained by \ref osMutexNew.
  1261. /// \return name as NULL terminated string.
  1262. const char *osMutexGetName(osMutexId_t mutex_id)
  1263. {
  1264. mutex_cb_t *mutex_cb = (mutex_cb_t *)mutex_id;
  1265. /* Check parameters */
  1266. if ((RT_NULL == mutex_cb) || (rt_object_get_type(&mutex_cb->mutex.parent.parent) != RT_Object_Class_Mutex))
  1267. {
  1268. return RT_NULL;
  1269. }
  1270. return mutex_cb->mutex.parent.parent.name;
  1271. }
  1272. /// Acquire a Mutex or timeout if it is locked.
  1273. /// \param[in] mutex_id mutex ID obtained by \ref osMutexNew.
  1274. /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
  1275. /// \return status code that indicates the execution status of the function.
  1276. osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout)
  1277. {
  1278. rt_err_t result;
  1279. mutex_cb_t *mutex_cb = (mutex_cb_t *)mutex_id;
  1280. /* Check parameters */
  1281. if (RT_NULL == mutex_cb)
  1282. {
  1283. return osErrorParameter;
  1284. }
  1285. rt_enter_critical();
  1286. if ((mutex_cb->mutex.owner == rt_thread_self()) && !(mutex_cb->flags & osMutexRecursive))
  1287. {
  1288. rt_exit_critical();
  1289. return osError;
  1290. }
  1291. rt_exit_critical();
  1292. if(timeout == osWaitForever)
  1293. {
  1294. timeout = RT_WAITING_FOREVER;
  1295. }
  1296. result = rt_mutex_take(&(mutex_cb->mutex), timeout);
  1297. if (RT_EOK == result)
  1298. return osOK;
  1299. else if (-RT_ETIMEOUT == result)
  1300. {
  1301. if (0U == timeout)
  1302. return osErrorResource;
  1303. else
  1304. return osErrorTimeout;
  1305. }
  1306. else
  1307. return osError;
  1308. }
  1309. /// Release a Mutex that was acquired by \ref osMutexAcquire.
  1310. /// \param[in] mutex_id mutex ID obtained by \ref osMutexNew.
  1311. /// \return status code that indicates the execution status of the function.
  1312. osStatus_t osMutexRelease(osMutexId_t mutex_id)
  1313. {
  1314. rt_err_t result;
  1315. mutex_cb_t *mutex_cb = (mutex_cb_t *)mutex_id;
  1316. /* Check parameters */
  1317. if (RT_NULL == mutex_cb)
  1318. {
  1319. return osErrorParameter;
  1320. }
  1321. result = rt_mutex_release(&(mutex_cb->mutex));
  1322. if (RT_EOK == result)
  1323. return osOK;
  1324. else
  1325. return osErrorResource;
  1326. }
  1327. /// Get Thread which owns a Mutex object.
  1328. /// \param[in] mutex_id mutex ID obtained by \ref osMutexNew.
  1329. /// \return thread ID of owner thread or NULL when mutex was not acquired.
  1330. osThreadId_t osMutexGetOwner(osMutexId_t mutex_id)
  1331. {
  1332. mutex_cb_t *mutex_cb = (mutex_cb_t *)mutex_id;
  1333. /* Check parameters */
  1334. if ((RT_NULL == mutex_cb) || (rt_object_get_type(&mutex_cb->mutex.parent.parent) != RT_Object_Class_Mutex))
  1335. {
  1336. return RT_NULL;
  1337. }
  1338. return mutex_cb->mutex.owner;
  1339. }
  1340. /// Delete a Mutex object.
  1341. /// \param[in] mutex_id mutex ID obtained by \ref osMutexNew.
  1342. /// \return status code that indicates the execution status of the function.
  1343. osStatus_t osMutexDelete(osMutexId_t mutex_id)
  1344. {
  1345. mutex_cb_t *mutex_cb = (mutex_cb_t *)mutex_id;
  1346. /* Check parameters */
  1347. if (RT_NULL == mutex_cb)
  1348. {
  1349. return osErrorParameter;
  1350. }
  1351. rt_mutex_detach(&(mutex_cb->mutex));
  1352. if (mutex_cb->flags & MALLOC_CB)
  1353. rt_free(mutex_cb);
  1354. return osOK;
  1355. }
  1356. #endif
  1357. #ifdef RT_USING_SEMAPHORE
  1358. osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr)
  1359. {
  1360. char name[RT_NAME_MAX];
  1361. sem_cb_t *sem_cb;
  1362. static rt_uint16_t semaphore_number = 0U;
  1363. /* Check parameters */
  1364. if ((0U == max_count) || (initial_count > max_count))
  1365. {
  1366. return RT_NULL;
  1367. }
  1368. if ((RT_NULL == attr) || (RT_NULL == attr->name))
  1369. {
  1370. rt_snprintf(name, sizeof(name), "sem%02d", semaphore_number++);
  1371. }
  1372. else
  1373. rt_snprintf(name, sizeof(name), "%s", attr->name);
  1374. if ((RT_NULL == attr) || (RT_NULL == attr->cb_mem))
  1375. {
  1376. sem_cb = rt_malloc(sizeof(sem_cb_t));
  1377. if (RT_NULL == sem_cb)
  1378. return RT_NULL;
  1379. rt_memset(sem_cb, 0, sizeof(sem_cb_t));
  1380. sem_cb->flags |= MALLOC_CB;
  1381. }
  1382. else
  1383. {
  1384. if (attr->cb_size >= sizeof(sem_cb_t))
  1385. {
  1386. sem_cb = attr->cb_mem;
  1387. sem_cb->flags = 0;
  1388. }
  1389. else
  1390. return RT_NULL;
  1391. }
  1392. rt_sem_init(&(sem_cb->sem), name, initial_count, RT_IPC_FLAG_FIFO);
  1393. return sem_cb;
  1394. }
  1395. /// Get name of a Semaphore object.
  1396. /// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
  1397. /// \return name as NULL terminated string.
  1398. const char *osSemaphoreGetName(osSemaphoreId_t semaphore_id)
  1399. {
  1400. sem_cb_t *sem_cb = (sem_cb_t *)semaphore_id;
  1401. /* Check parameters */
  1402. if ((RT_NULL == sem_cb) || (rt_object_get_type(&sem_cb->sem.parent.parent) != RT_Object_Class_Semaphore))
  1403. {
  1404. return RT_NULL;
  1405. }
  1406. return sem_cb->sem.parent.parent.name;
  1407. }
  1408. /// Acquire a Semaphore token or timeout if no tokens are available.
  1409. /// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
  1410. /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
  1411. /// \return status code that indicates the execution status of the function.
  1412. osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout)
  1413. {
  1414. rt_err_t result;
  1415. sem_cb_t *sem_cb = (sem_cb_t *)semaphore_id;
  1416. /* Check parameters */
  1417. if (RT_NULL == sem_cb)
  1418. {
  1419. return osErrorParameter;
  1420. }
  1421. if(timeout == osWaitForever)
  1422. {
  1423. timeout = RT_WAITING_FOREVER;
  1424. }
  1425. result = rt_sem_take(&(sem_cb->sem), timeout);
  1426. if (RT_EOK == result)
  1427. return osOK;
  1428. else if (-RT_ETIMEOUT == result)
  1429. {
  1430. if (0U == timeout)
  1431. return osErrorResource;
  1432. else
  1433. return osErrorTimeout;
  1434. }
  1435. else
  1436. return osError;
  1437. }
  1438. /// Release a Semaphore token that was acquired by \ref osSemaphoreAcquire.
  1439. /// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
  1440. /// \return status code that indicates the execution status of the function.
  1441. osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id)
  1442. {
  1443. rt_err_t result;
  1444. sem_cb_t *sem_cb = (sem_cb_t *)semaphore_id;
  1445. /* Check parameters */
  1446. if (RT_NULL == sem_cb)
  1447. {
  1448. return osErrorParameter;
  1449. }
  1450. result = rt_sem_release(&(sem_cb->sem));
  1451. if (RT_EOK == result)
  1452. return osOK;
  1453. else
  1454. return osError;
  1455. }
  1456. /// Get current Semaphore token count.
  1457. /// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
  1458. /// \return number of tokens available.
  1459. uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id)
  1460. {
  1461. sem_cb_t *sem_cb = (sem_cb_t *)semaphore_id;
  1462. /* Check parameters */
  1463. if ((RT_NULL == sem_cb) || (rt_object_get_type(&sem_cb->sem.parent.parent) != RT_Object_Class_Semaphore))
  1464. {
  1465. return 0U;
  1466. }
  1467. return sem_cb->sem.value;
  1468. }
  1469. /// Delete a Semaphore object.
  1470. /// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
  1471. /// \return status code that indicates the execution status of the function.
  1472. osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id)
  1473. {
  1474. sem_cb_t *sem_cb = (sem_cb_t *)semaphore_id;
  1475. /* Check parameters */
  1476. if (RT_NULL == sem_cb)
  1477. {
  1478. return osErrorParameter;
  1479. }
  1480. rt_sem_detach(&(sem_cb->sem));
  1481. if (sem_cb->flags & MALLOC_CB)
  1482. rt_free(sem_cb);
  1483. return osOK;
  1484. }
  1485. #endif
  1486. #ifdef RT_USING_MEMPOOL
  1487. // ==== Memory Pool Management Functions ====
  1488. /// Create and Initialize a Memory Pool object.
  1489. /// \param[in] block_count maximum number of memory blocks in memory pool.
  1490. /// \param[in] block_size memory block size in bytes.
  1491. /// \param[in] attr memory pool attributes; NULL: default values.
  1492. /// \return memory pool ID for reference by other functions or NULL in case of error.
  1493. osMemoryPoolId_t osMemoryPoolNew(uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr)
  1494. {
  1495. char name[RT_NAME_MAX];
  1496. void *mp_addr;
  1497. rt_uint32_t mp_size;
  1498. mempool_cb_t *mempool_cb;
  1499. static rt_uint16_t memory_pool_number = 0U;
  1500. /* Check parameters */
  1501. if ((0U == block_count) || (0U == block_size))
  1502. {
  1503. return RT_NULL;
  1504. }
  1505. if ((RT_NULL == attr) || (RT_NULL == attr->name))
  1506. {
  1507. rt_snprintf(name, sizeof(name), "mp%02d", memory_pool_number++);
  1508. }
  1509. else
  1510. rt_snprintf(name, sizeof(name), "%s", attr->name);
  1511. if ((RT_NULL == attr) || (RT_NULL == attr->cb_mem))
  1512. {
  1513. mempool_cb = rt_malloc(sizeof(mempool_cb_t));
  1514. if (RT_NULL == mempool_cb)
  1515. return RT_NULL;
  1516. rt_memset(mempool_cb, 0, sizeof(mempool_cb_t));
  1517. mempool_cb->flags |= MALLOC_CB;
  1518. }
  1519. else
  1520. {
  1521. if (attr->cb_size >= sizeof(mempool_cb_t))
  1522. {
  1523. mempool_cb = attr->cb_mem;
  1524. mempool_cb->flags = 0;
  1525. }
  1526. else
  1527. return RT_NULL;
  1528. }
  1529. if ((RT_NULL == attr) || (RT_NULL == attr->mp_mem))
  1530. {
  1531. block_size = RT_ALIGN(block_size, RT_ALIGN_SIZE);
  1532. mp_size = (block_size + sizeof(rt_uint8_t *)) * block_count;
  1533. mp_addr = rt_malloc((block_size + sizeof(rt_uint8_t *)) * block_count);
  1534. if (RT_NULL == mp_addr)
  1535. {
  1536. if (mempool_cb->flags & MALLOC_CB)
  1537. rt_free(mempool_cb);
  1538. return RT_NULL;
  1539. }
  1540. mempool_cb->flags |= MALLOC_MEM;
  1541. }
  1542. else
  1543. {
  1544. mp_addr = (void *)(attr->mp_mem);
  1545. mp_size = attr->mp_size;
  1546. }
  1547. rt_mp_init(&(mempool_cb->mp), name, mp_addr, mp_size, block_size);
  1548. return mempool_cb;
  1549. }
  1550. /// Get name of a Memory Pool object.
  1551. /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
  1552. /// \return name as NULL terminated string.
  1553. const char *osMemoryPoolGetName(osMemoryPoolId_t mp_id)
  1554. {
  1555. mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
  1556. /* Check parameters */
  1557. if ((RT_NULL == mempool_cb) || (rt_object_get_type(&mempool_cb->mp.parent) != RT_Object_Class_MemPool))
  1558. {
  1559. return RT_NULL;
  1560. }
  1561. return mempool_cb->mp.parent.name;
  1562. }
  1563. /// Allocate a memory block from a Memory Pool.
  1564. /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
  1565. /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
  1566. /// \return address of the allocated memory block or NULL in case of no memory is available.
  1567. void *osMemoryPoolAlloc(osMemoryPoolId_t mp_id, uint32_t timeout)
  1568. {
  1569. mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
  1570. /* Check parameters */
  1571. if (RT_NULL == mempool_cb)
  1572. {
  1573. return RT_NULL;
  1574. }
  1575. if(timeout == osWaitForever)
  1576. {
  1577. timeout = RT_WAITING_FOREVER;
  1578. }
  1579. return rt_mp_alloc(&(mempool_cb->mp), timeout);
  1580. }
  1581. /// Return an allocated memory block back to a Memory Pool.
  1582. /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
  1583. /// \param[in] block address of the allocated memory block to be returned to the memory pool.
  1584. /// \return status code that indicates the execution status of the function.
  1585. osStatus_t osMemoryPoolFree(osMemoryPoolId_t mp_id, void *block)
  1586. {
  1587. mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
  1588. /* Check parameters */
  1589. if (RT_NULL == mempool_cb)
  1590. {
  1591. return osErrorParameter;
  1592. }
  1593. rt_mp_free(block);
  1594. return osOK;
  1595. }
  1596. /// Get maximum number of memory blocks in a Memory Pool.
  1597. /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
  1598. /// \return maximum number of memory blocks.
  1599. uint32_t osMemoryPoolGetCapacity(osMemoryPoolId_t mp_id)
  1600. {
  1601. mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
  1602. /* Check parameters */
  1603. if ((RT_NULL == mempool_cb) || (rt_object_get_type(&mempool_cb->mp.parent) != RT_Object_Class_MemPool))
  1604. {
  1605. return 0U;
  1606. }
  1607. return mempool_cb->mp.block_total_count;
  1608. }
  1609. /// Get memory block size in a Memory Pool.
  1610. /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
  1611. /// \return memory block size in bytes.
  1612. uint32_t osMemoryPoolGetBlockSize(osMemoryPoolId_t mp_id)
  1613. {
  1614. mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
  1615. /* Check parameters */
  1616. if ((RT_NULL == mempool_cb) || (rt_object_get_type(&mempool_cb->mp.parent) != RT_Object_Class_MemPool))
  1617. {
  1618. return 0U;
  1619. }
  1620. return mempool_cb->mp.block_size;
  1621. }
  1622. /// Get number of memory blocks used in a Memory Pool.
  1623. /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
  1624. /// \return number of memory blocks used.
  1625. uint32_t osMemoryPoolGetCount(osMemoryPoolId_t mp_id)
  1626. {
  1627. rt_size_t used_blocks;
  1628. mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
  1629. /* Check parameters */
  1630. if ((RT_NULL == mempool_cb) || (rt_object_get_type(&mempool_cb->mp.parent) != RT_Object_Class_MemPool))
  1631. {
  1632. return 0U;
  1633. }
  1634. used_blocks = mempool_cb->mp.block_total_count - mempool_cb->mp.block_free_count;
  1635. return (uint32_t)used_blocks;
  1636. }
  1637. /// Get number of memory blocks available in a Memory Pool.
  1638. /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
  1639. /// \return number of memory blocks available.
  1640. uint32_t osMemoryPoolGetSpace(osMemoryPoolId_t mp_id)
  1641. {
  1642. mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
  1643. /* Check parameters */
  1644. if ((RT_NULL == mempool_cb) || (rt_object_get_type(&mempool_cb->mp.parent) != RT_Object_Class_MemPool))
  1645. {
  1646. return 0U;
  1647. }
  1648. return mempool_cb->mp.block_free_count;
  1649. }
  1650. /// Delete a Memory Pool object.
  1651. /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
  1652. /// \return status code that indicates the execution status of the function.
  1653. osStatus_t osMemoryPoolDelete(osMemoryPoolId_t mp_id)
  1654. {
  1655. mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
  1656. /* Check parameters */
  1657. if (RT_NULL == mempool_cb)
  1658. {
  1659. return osErrorParameter;
  1660. }
  1661. rt_mp_detach(&(mempool_cb->mp));
  1662. if (mempool_cb->flags & MALLOC_CB)
  1663. rt_free(mempool_cb);
  1664. if (mempool_cb->flags & MALLOC_MEM)
  1665. rt_free(mempool_cb->mp.start_address);
  1666. return osOK;
  1667. }
  1668. #endif
  1669. #ifdef RT_USING_MESSAGEQUEUE
  1670. // ==== Message Queue Management Functions ====
  1671. /// Create and Initialize a Message Queue object.
  1672. /// \param[in] msg_count maximum number of messages in queue.
  1673. /// \param[in] msg_size maximum message size in bytes.
  1674. /// \param[in] attr message queue attributes; NULL: default values.
  1675. /// \return message queue ID for reference by other functions or NULL in case of error.
  1676. osMessageQueueId_t osMessageQueueNew(uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr)
  1677. {
  1678. char name[RT_NAME_MAX];
  1679. mq_cb_t *mq_cb;
  1680. void *mq_addr;
  1681. rt_uint32_t mq_size;
  1682. static rt_uint16_t mq_number = 0U;
  1683. /* Check parameters */
  1684. if ((0U == msg_count) || (0U == msg_size))
  1685. {
  1686. return RT_NULL;
  1687. }
  1688. if ((RT_NULL == attr) || (RT_NULL == attr->name))
  1689. {
  1690. rt_snprintf(name, sizeof(name), "mq%02d", mq_number++);
  1691. }
  1692. else
  1693. rt_snprintf(name, sizeof(name), "%s", attr->name);
  1694. if ((RT_NULL == attr) || (RT_NULL == attr->cb_mem))
  1695. {
  1696. mq_cb = rt_malloc(sizeof(mq_cb_t));
  1697. if (RT_NULL == mq_cb)
  1698. return RT_NULL;
  1699. rt_memset(mq_cb, 0, sizeof(mq_cb_t));
  1700. mq_cb->flags |= MALLOC_CB;
  1701. }
  1702. else
  1703. {
  1704. if (attr->cb_size >= sizeof(mq_cb_t))
  1705. {
  1706. mq_cb = attr->cb_mem;
  1707. mq_cb->flags = 0;
  1708. }
  1709. else
  1710. return RT_NULL;
  1711. }
  1712. mq_cb->init_msg_size = msg_size;
  1713. if ((RT_NULL == attr) || (RT_NULL == attr->mq_mem))
  1714. {
  1715. register rt_size_t msg_align_size;
  1716. /* get correct message size */
  1717. msg_align_size = RT_ALIGN(msg_size, RT_ALIGN_SIZE);
  1718. mq_size = (msg_align_size + sizeof(struct rt_mq_message)) * msg_count;
  1719. mq_addr = rt_malloc(mq_size);
  1720. if (RT_NULL == mq_addr)
  1721. {
  1722. if (mq_cb->flags & MALLOC_CB)
  1723. rt_free(mq_cb);
  1724. return RT_NULL;
  1725. }
  1726. rt_memset(mq_addr, 0, sizeof(mq_size));
  1727. mq_cb->flags |= MALLOC_MEM;
  1728. }
  1729. else
  1730. {
  1731. mq_addr = (void *)(attr->mq_mem);
  1732. mq_size = attr->mq_size;
  1733. }
  1734. rt_mq_init(&(mq_cb->mq), name, mq_addr, msg_size, mq_size, RT_IPC_FLAG_FIFO);
  1735. return mq_cb;
  1736. }
  1737. /// Get name of a Message Queue object.
  1738. /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
  1739. /// \return name as NULL terminated string.
  1740. const char *osMessageQueueGetName(osMessageQueueId_t mq_id)
  1741. {
  1742. mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
  1743. /* Check parameters */
  1744. if ((RT_NULL == mq_cb) || (rt_object_get_type(&mq_cb->mq.parent.parent) != RT_Object_Class_MessageQueue))
  1745. {
  1746. return RT_NULL;
  1747. }
  1748. return mq_cb->mq.parent.parent.name;
  1749. }
  1750. /// Put a Message into a Queue or timeout if Queue is full.
  1751. /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
  1752. /// \param[in] msg_ptr pointer to buffer with message to put into a queue.
  1753. /// \param[in] msg_prio message priority.
  1754. /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
  1755. /// \return status code that indicates the execution status of the function.
  1756. osStatus_t osMessageQueuePut(osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout)
  1757. {
  1758. rt_err_t result;
  1759. mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
  1760. /* Check parameters */
  1761. if (RT_NULL == mq_cb || (RT_NULL == msg_ptr))
  1762. {
  1763. return osErrorParameter;
  1764. }
  1765. if(timeout == osWaitForever)
  1766. {
  1767. timeout = RT_WAITING_FOREVER;
  1768. }
  1769. result = rt_mq_send_wait(&(mq_cb->mq), (void *)msg_ptr, mq_cb->init_msg_size, timeout);
  1770. if (RT_EOK == result)
  1771. return osOK;
  1772. else if (-RT_EFULL == result)
  1773. return osErrorResource;
  1774. else if (-RT_ETIMEOUT == result)
  1775. {
  1776. return osErrorTimeout;
  1777. }
  1778. else
  1779. {
  1780. return osError;
  1781. }
  1782. }
  1783. /// Get a Message from a Queue or timeout if Queue is empty.
  1784. /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
  1785. /// \param[out] msg_ptr pointer to buffer for message to get from a queue.
  1786. /// \param[out] msg_prio pointer to buffer for message priority or NULL.
  1787. /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
  1788. /// \return status code that indicates the execution status of the function.
  1789. #if defined(RT_VERSION_CHECK) && (RTTHREAD_VERSION >= RT_VERSION_CHECK(5, 0, 1))
  1790. osStatus_t osMessageQueueGet(osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout)
  1791. {
  1792. rt_ssize_t result = 0;
  1793. mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
  1794. /* Check parameters */
  1795. if (RT_NULL == mq_cb || (RT_NULL == msg_ptr))
  1796. {
  1797. return osErrorParameter;
  1798. }
  1799. if(timeout == osWaitForever)
  1800. {
  1801. timeout = RT_WAITING_FOREVER;
  1802. }
  1803. result = rt_mq_recv(&(mq_cb->mq), msg_ptr, mq_cb->init_msg_size, timeout);
  1804. if (result > 0)
  1805. {
  1806. return osOK;
  1807. }
  1808. else if (-RT_ETIMEOUT == result)
  1809. {
  1810. if (0U == timeout)
  1811. return osErrorResource;
  1812. return osErrorTimeout;
  1813. }
  1814. else
  1815. return osError;
  1816. }
  1817. #else /* legacy version macros (<5.0.1) */
  1818. osStatus_t osMessageQueueGet(osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout)
  1819. {
  1820. rt_err_t result;
  1821. mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
  1822. /* Check parameters */
  1823. if (RT_NULL == mq_cb || (RT_NULL == msg_ptr))
  1824. {
  1825. return osErrorParameter;
  1826. }
  1827. if(timeout == osWaitForever)
  1828. {
  1829. timeout = RT_WAITING_FOREVER;
  1830. }
  1831. result = rt_mq_recv(&(mq_cb->mq), msg_ptr, mq_cb->init_msg_size, timeout);
  1832. if (RT_EOK == result)
  1833. return osOK;
  1834. else if (-RT_ETIMEOUT == result)
  1835. {
  1836. if (0U == timeout)
  1837. return osErrorResource;
  1838. return osErrorTimeout;
  1839. }
  1840. else
  1841. return osError;
  1842. }
  1843. #endif
  1844. /// Get maximum number of messages in a Message Queue.
  1845. /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
  1846. /// \return maximum number of messages.
  1847. uint32_t osMessageQueueGetCapacity(osMessageQueueId_t mq_id)
  1848. {
  1849. mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
  1850. /* Check parameters */
  1851. if ((RT_NULL == mq_cb) || (rt_object_get_type(&mq_cb->mq.parent.parent) != RT_Object_Class_MessageQueue))
  1852. {
  1853. return 0U;
  1854. }
  1855. return mq_cb->mq.max_msgs;
  1856. }
  1857. /// Get maximum message size in a Memory Pool.
  1858. /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
  1859. /// \return maximum message size in bytes.
  1860. uint32_t osMessageQueueGetMsgSize(osMessageQueueId_t mq_id)
  1861. {
  1862. mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
  1863. /* Check parameters */;
  1864. if ((RT_NULL == mq_cb) || (rt_object_get_type(&mq_cb->mq.parent.parent) != RT_Object_Class_MessageQueue))
  1865. {
  1866. return 0U;
  1867. }
  1868. return mq_cb->mq.msg_size;
  1869. }
  1870. /// Get number of queued messages in a Message Queue.
  1871. /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
  1872. /// \return number of queued messages.
  1873. uint32_t osMessageQueueGetCount(osMessageQueueId_t mq_id)
  1874. {
  1875. mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
  1876. /* Check parameters */;
  1877. if ((RT_NULL == mq_cb) || (rt_object_get_type(&mq_cb->mq.parent.parent) != RT_Object_Class_MessageQueue))
  1878. {
  1879. return 0U;
  1880. }
  1881. return mq_cb->mq.entry;
  1882. }
  1883. /// Get number of available slots for messages in a Message Queue.
  1884. /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
  1885. /// \return number of available slots for messages.
  1886. uint32_t osMessageQueueGetSpace(osMessageQueueId_t mq_id)
  1887. {
  1888. mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
  1889. /* Check parameters */;
  1890. if ((RT_NULL == mq_cb) || (rt_object_get_type(&mq_cb->mq.parent.parent) != RT_Object_Class_MessageQueue))
  1891. {
  1892. return 0U;
  1893. }
  1894. return (mq_cb->mq.max_msgs - mq_cb->mq.entry);
  1895. }
  1896. /// Reset a Message Queue to initial empty state.
  1897. /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
  1898. /// \return status code that indicates the execution status of the function.
  1899. osStatus_t osMessageQueueReset(osMessageQueueId_t mq_id)
  1900. {
  1901. rt_err_t result;
  1902. mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
  1903. /* Check parameters */;
  1904. if (RT_NULL == mq_cb)
  1905. {
  1906. return osErrorParameter;
  1907. }
  1908. result = rt_mq_control(&(mq_cb->mq), RT_IPC_CMD_RESET, RT_NULL);
  1909. if (RT_EOK == result)
  1910. return osOK;
  1911. else
  1912. return osError;
  1913. }
  1914. /// Delete a Message Queue object.
  1915. /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
  1916. /// \return status code that indicates the execution status of the function.
  1917. osStatus_t osMessageQueueDelete(osMessageQueueId_t mq_id)
  1918. {
  1919. mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
  1920. /* Check parameters */;
  1921. if (RT_NULL == mq_cb)
  1922. {
  1923. return osErrorParameter;
  1924. }
  1925. rt_mq_detach(&(mq_cb->mq));
  1926. if (mq_cb->flags & MALLOC_CB)
  1927. rt_free(mq_cb);
  1928. if (mq_cb->flags & MALLOC_MEM)
  1929. rt_free(mq_cb->mq.msg_pool);
  1930. return osOK;
  1931. }
  1932. #endif