rtx_evflags.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. /*
  2. * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * -----------------------------------------------------------------------------
  19. *
  20. * Project: CMSIS-RTOS RTX
  21. * Title: Event Flags functions
  22. *
  23. * -----------------------------------------------------------------------------
  24. */
  25. #include "rtx_lib.h"
  26. // OS Runtime Object Memory Usage
  27. #ifdef RTX_OBJ_MEM_USAGE
  28. osRtxObjectMemUsage_t osRtxEventFlagsMemUsage \
  29. __attribute__((section(".data.os.evflags.obj"))) =
  30. { 0U, 0U, 0U };
  31. #endif
  32. // ==== Helper functions ====
  33. /// Set Event Flags.
  34. /// \param[in] ef event flags object.
  35. /// \param[in] flags specifies the flags to set.
  36. /// \return event flags after setting.
  37. static uint32_t EventFlagsSet (os_event_flags_t *ef, uint32_t flags) {
  38. #if (EXCLUSIVE_ACCESS == 0)
  39. uint32_t primask = __get_PRIMASK();
  40. #endif
  41. uint32_t event_flags;
  42. #if (EXCLUSIVE_ACCESS == 0)
  43. __disable_irq();
  44. ef->event_flags |= flags;
  45. event_flags = ef->event_flags;
  46. if (primask == 0U) {
  47. __enable_irq();
  48. }
  49. #else
  50. event_flags = atomic_set32(&ef->event_flags, flags);
  51. #endif
  52. return event_flags;
  53. }
  54. /// Clear Event Flags.
  55. /// \param[in] ef event flags object.
  56. /// \param[in] flags specifies the flags to clear.
  57. /// \return event flags before clearing.
  58. static uint32_t EventFlagsClear (os_event_flags_t *ef, uint32_t flags) {
  59. #if (EXCLUSIVE_ACCESS == 0)
  60. uint32_t primask = __get_PRIMASK();
  61. #endif
  62. uint32_t event_flags;
  63. #if (EXCLUSIVE_ACCESS == 0)
  64. __disable_irq();
  65. event_flags = ef->event_flags;
  66. ef->event_flags &= ~flags;
  67. if (primask == 0U) {
  68. __enable_irq();
  69. }
  70. #else
  71. event_flags = atomic_clr32(&ef->event_flags, flags);
  72. #endif
  73. return event_flags;
  74. }
  75. /// Check Event Flags.
  76. /// \param[in] ef event flags object.
  77. /// \param[in] flags specifies the flags to check.
  78. /// \param[in] options specifies flags options (osFlagsXxxx).
  79. /// \return event flags before clearing or 0 if specified flags have not been set.
  80. static uint32_t EventFlagsCheck (os_event_flags_t *ef, uint32_t flags, uint32_t options) {
  81. #if (EXCLUSIVE_ACCESS == 0)
  82. uint32_t primask;
  83. #endif
  84. uint32_t event_flags;
  85. if ((options & osFlagsNoClear) == 0U) {
  86. #if (EXCLUSIVE_ACCESS == 0)
  87. primask = __get_PRIMASK();
  88. __disable_irq();
  89. event_flags = ef->event_flags;
  90. if ((((options & osFlagsWaitAll) != 0U) && ((event_flags & flags) != flags)) ||
  91. (((options & osFlagsWaitAll) == 0U) && ((event_flags & flags) == 0U))) {
  92. event_flags = 0U;
  93. } else {
  94. ef->event_flags &= ~flags;
  95. }
  96. if (primask == 0U) {
  97. __enable_irq();
  98. }
  99. #else
  100. if ((options & osFlagsWaitAll) != 0U) {
  101. event_flags = atomic_chk32_all(&ef->event_flags, flags);
  102. } else {
  103. event_flags = atomic_chk32_any(&ef->event_flags, flags);
  104. }
  105. #endif
  106. } else {
  107. event_flags = ef->event_flags;
  108. if ((((options & osFlagsWaitAll) != 0U) && ((event_flags & flags) != flags)) ||
  109. (((options & osFlagsWaitAll) == 0U) && ((event_flags & flags) == 0U))) {
  110. event_flags = 0U;
  111. }
  112. }
  113. return event_flags;
  114. }
  115. /// Verify that Event Flags object pointer is valid.
  116. /// \param[in] ef event flags object.
  117. /// \return true - valid, false - invalid.
  118. static bool_t IsEventFlagsPtrValid (const os_event_flags_t *ef) {
  119. #ifdef RTX_OBJ_PTR_CHECK
  120. //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
  121. uint32_t cb_start = (uint32_t)&__os_evflags_cb_start__;
  122. uint32_t cb_length = (uint32_t)&__os_evflags_cb_length__;
  123. // Check the section boundaries
  124. if (((uint32_t)ef - cb_start) >= cb_length) {
  125. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  126. return FALSE;
  127. }
  128. // Check the object alignment
  129. if ((((uint32_t)ef - cb_start) % sizeof(os_event_flags_t)) != 0U) {
  130. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  131. return FALSE;
  132. }
  133. #else
  134. // Check NULL pointer
  135. if (ef == NULL) {
  136. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  137. return FALSE;
  138. }
  139. #endif
  140. return TRUE;
  141. }
  142. // ==== Library functions ====
  143. /// Destroy an Event Flags object.
  144. /// \param[in] ef event flags object.
  145. static void osRtxEventFlagsDestroy (os_event_flags_t *ef) {
  146. // Mark object as invalid
  147. ef->id = osRtxIdInvalid;
  148. // Free object memory
  149. if ((ef->flags & osRtxFlagSystemObject) != 0U) {
  150. #ifdef RTX_OBJ_PTR_CHECK
  151. (void)osRtxMemoryPoolFree(osRtxInfo.mpi.event_flags, ef);
  152. #else
  153. if (osRtxInfo.mpi.event_flags != NULL) {
  154. (void)osRtxMemoryPoolFree(osRtxInfo.mpi.event_flags, ef);
  155. } else {
  156. (void)osRtxMemoryFree(osRtxInfo.mem.common, ef);
  157. }
  158. #endif
  159. #ifdef RTX_OBJ_MEM_USAGE
  160. osRtxEventFlagsMemUsage.cnt_free++;
  161. #endif
  162. }
  163. EvrRtxEventFlagsDestroyed(ef);
  164. }
  165. #ifdef RTX_SAFETY_CLASS
  166. /// Delete an Event Flags safety class.
  167. /// \param[in] safety_class safety class.
  168. /// \param[in] mode safety mode.
  169. void osRtxEventFlagsDeleteClass (uint32_t safety_class, uint32_t mode) {
  170. os_event_flags_t *ef;
  171. os_thread_t *thread;
  172. uint32_t length;
  173. //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
  174. ef = (os_event_flags_t *)(uint32_t)&__os_evflags_cb_start__;
  175. length = (uint32_t)&__os_evflags_cb_length__;
  176. while (length >= sizeof(os_event_flags_t)) {
  177. if ( (ef->id == osRtxIdEventFlags) &&
  178. ((((mode & osSafetyWithSameClass) != 0U) &&
  179. ((ef->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
  180. (((mode & osSafetyWithLowerClass) != 0U) &&
  181. ((ef->attr >> osRtxAttrClass_Pos) < (uint8_t)safety_class)))) {
  182. while (ef->thread_list != NULL) {
  183. thread = osRtxThreadListGet(osRtxObject(ef));
  184. osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE);
  185. }
  186. osRtxEventFlagsDestroy(ef);
  187. }
  188. length -= sizeof(os_event_flags_t);
  189. ef++;
  190. }
  191. }
  192. #endif
  193. // ==== Post ISR processing ====
  194. /// Event Flags post ISR processing.
  195. /// \param[in] ef event flags object.
  196. static void osRtxEventFlagsPostProcess (os_event_flags_t *ef) {
  197. os_thread_t *thread;
  198. os_thread_t *thread_next;
  199. uint32_t event_flags;
  200. // Check if Threads are waiting for Event Flags
  201. thread = ef->thread_list;
  202. while (thread != NULL) {
  203. thread_next = thread->thread_next;
  204. event_flags = EventFlagsCheck(ef, thread->wait_flags, thread->flags_options);
  205. if (event_flags != 0U) {
  206. osRtxThreadListRemove(thread);
  207. osRtxThreadWaitExit(thread, event_flags, FALSE);
  208. EvrRtxEventFlagsWaitCompleted(ef, thread->wait_flags, thread->flags_options, event_flags);
  209. }
  210. thread = thread_next;
  211. }
  212. }
  213. // ==== Service Calls ====
  214. /// Create and Initialize an Event Flags object.
  215. /// \note API identical to osEventFlagsNew
  216. static osEventFlagsId_t svcRtxEventFlagsNew (const osEventFlagsAttr_t *attr) {
  217. os_event_flags_t *ef;
  218. #ifdef RTX_SAFETY_CLASS
  219. const os_thread_t *thread = osRtxThreadGetRunning();
  220. uint32_t attr_bits;
  221. #endif
  222. uint8_t flags;
  223. const char *name;
  224. // Process attributes
  225. if (attr != NULL) {
  226. name = attr->name;
  227. #ifdef RTX_SAFETY_CLASS
  228. attr_bits = attr->attr_bits;
  229. #endif
  230. //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
  231. ef = attr->cb_mem;
  232. #ifdef RTX_SAFETY_CLASS
  233. if ((attr_bits & osSafetyClass_Valid) != 0U) {
  234. if ((thread != NULL) &&
  235. ((thread->attr >> osRtxAttrClass_Pos) <
  236. (uint8_t)((attr_bits & osSafetyClass_Msk) >> osSafetyClass_Pos))) {
  237. EvrRtxEventFlagsError(NULL, (int32_t)osErrorSafetyClass);
  238. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  239. return NULL;
  240. }
  241. }
  242. #endif
  243. if (ef != NULL) {
  244. if (!IsEventFlagsPtrValid(ef) || (attr->cb_size != sizeof(os_event_flags_t))) {
  245. EvrRtxEventFlagsError(NULL, osRtxErrorInvalidControlBlock);
  246. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  247. return NULL;
  248. }
  249. } else {
  250. if (attr->cb_size != 0U) {
  251. EvrRtxEventFlagsError(NULL, osRtxErrorInvalidControlBlock);
  252. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  253. return NULL;
  254. }
  255. }
  256. } else {
  257. name = NULL;
  258. #ifdef RTX_SAFETY_CLASS
  259. attr_bits = 0U;
  260. #endif
  261. ef = NULL;
  262. }
  263. // Allocate object memory if not provided
  264. if (ef == NULL) {
  265. if (osRtxInfo.mpi.event_flags != NULL) {
  266. //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
  267. ef = osRtxMemoryPoolAlloc(osRtxInfo.mpi.event_flags);
  268. #ifndef RTX_OBJ_PTR_CHECK
  269. } else {
  270. //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
  271. ef = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_event_flags_t), 1U);
  272. #endif
  273. }
  274. #ifdef RTX_OBJ_MEM_USAGE
  275. if (ef != NULL) {
  276. uint32_t used;
  277. osRtxEventFlagsMemUsage.cnt_alloc++;
  278. used = osRtxEventFlagsMemUsage.cnt_alloc - osRtxEventFlagsMemUsage.cnt_free;
  279. if (osRtxEventFlagsMemUsage.max_used < used) {
  280. osRtxEventFlagsMemUsage.max_used = used;
  281. }
  282. }
  283. #endif
  284. flags = osRtxFlagSystemObject;
  285. } else {
  286. flags = 0U;
  287. }
  288. if (ef != NULL) {
  289. // Initialize control block
  290. ef->id = osRtxIdEventFlags;
  291. ef->flags = flags;
  292. ef->attr = 0U;
  293. ef->name = name;
  294. ef->thread_list = NULL;
  295. ef->event_flags = 0U;
  296. #ifdef RTX_SAFETY_CLASS
  297. if ((attr_bits & osSafetyClass_Valid) != 0U) {
  298. ef->attr |= (uint8_t)((attr_bits & osSafetyClass_Msk) >>
  299. (osSafetyClass_Pos - osRtxAttrClass_Pos));
  300. } else {
  301. // Inherit safety class from the running thread
  302. if (thread != NULL) {
  303. ef->attr |= (uint8_t)(thread->attr & osRtxAttrClass_Msk);
  304. }
  305. }
  306. #endif
  307. // Register post ISR processing function
  308. osRtxInfo.post_process.event_flags = osRtxEventFlagsPostProcess;
  309. EvrRtxEventFlagsCreated(ef, ef->name);
  310. } else {
  311. EvrRtxEventFlagsError(NULL, (int32_t)osErrorNoMemory);
  312. }
  313. return ef;
  314. }
  315. /// Get name of an Event Flags object.
  316. /// \note API identical to osEventFlagsGetName
  317. static const char *svcRtxEventFlagsGetName (osEventFlagsId_t ef_id) {
  318. os_event_flags_t *ef = osRtxEventFlagsId(ef_id);
  319. // Check parameters
  320. if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags)) {
  321. EvrRtxEventFlagsGetName(ef, NULL);
  322. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  323. return NULL;
  324. }
  325. EvrRtxEventFlagsGetName(ef, ef->name);
  326. return ef->name;
  327. }
  328. /// Set the specified Event Flags.
  329. /// \note API identical to osEventFlagsSet
  330. static uint32_t svcRtxEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) {
  331. os_event_flags_t *ef = osRtxEventFlagsId(ef_id);
  332. os_thread_t *thread;
  333. os_thread_t *thread_next;
  334. uint32_t event_flags;
  335. uint32_t event_flags0;
  336. // Check parameters
  337. if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags) ||
  338. ((flags & ~(((uint32_t)1U << osRtxEventFlagsLimit) - 1U)) != 0U)) {
  339. EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter);
  340. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  341. return ((uint32_t)osErrorParameter);
  342. }
  343. #ifdef RTX_SAFETY_CLASS
  344. // Check running thread safety class
  345. thread = osRtxThreadGetRunning();
  346. if ((thread != NULL) &&
  347. ((thread->attr >> osRtxAttrClass_Pos) < (ef->attr >> osRtxAttrClass_Pos))) {
  348. EvrRtxEventFlagsError(ef, (int32_t)osErrorSafetyClass);
  349. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  350. return ((uint32_t)osErrorSafetyClass);
  351. }
  352. #endif
  353. // Set Event Flags
  354. event_flags = EventFlagsSet(ef, flags);
  355. // Check if Threads are waiting for Event Flags
  356. thread = ef->thread_list;
  357. while (thread != NULL) {
  358. thread_next = thread->thread_next;
  359. event_flags0 = EventFlagsCheck(ef, thread->wait_flags, thread->flags_options);
  360. if (event_flags0 != 0U) {
  361. if ((thread->flags_options & osFlagsNoClear) == 0U) {
  362. event_flags = event_flags0 & ~thread->wait_flags;
  363. } else {
  364. event_flags = event_flags0;
  365. }
  366. osRtxThreadListRemove(thread);
  367. osRtxThreadWaitExit(thread, event_flags0, FALSE);
  368. EvrRtxEventFlagsWaitCompleted(ef, thread->wait_flags, thread->flags_options, event_flags0);
  369. }
  370. thread = thread_next;
  371. }
  372. osRtxThreadDispatch(NULL);
  373. EvrRtxEventFlagsSetDone(ef, event_flags);
  374. return event_flags;
  375. }
  376. /// Clear the specified Event Flags.
  377. /// \note API identical to osEventFlagsClear
  378. static uint32_t svcRtxEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) {
  379. os_event_flags_t *ef = osRtxEventFlagsId(ef_id);
  380. #ifdef RTX_SAFETY_CLASS
  381. const os_thread_t *thread;
  382. #endif
  383. uint32_t event_flags;
  384. // Check parameters
  385. if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags) ||
  386. ((flags & ~(((uint32_t)1U << osRtxEventFlagsLimit) - 1U)) != 0U)) {
  387. EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter);
  388. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  389. return ((uint32_t)osErrorParameter);
  390. }
  391. #ifdef RTX_SAFETY_CLASS
  392. // Check running thread safety class
  393. thread = osRtxThreadGetRunning();
  394. if ((thread != NULL) &&
  395. ((thread->attr >> osRtxAttrClass_Pos) < (ef->attr >> osRtxAttrClass_Pos))) {
  396. EvrRtxEventFlagsError(ef, (int32_t)osErrorSafetyClass);
  397. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  398. return ((uint32_t)osErrorSafetyClass);
  399. }
  400. #endif
  401. // Clear Event Flags
  402. event_flags = EventFlagsClear(ef, flags);
  403. EvrRtxEventFlagsClearDone(ef, event_flags);
  404. return event_flags;
  405. }
  406. /// Get the current Event Flags.
  407. /// \note API identical to osEventFlagsGet
  408. static uint32_t svcRtxEventFlagsGet (osEventFlagsId_t ef_id) {
  409. os_event_flags_t *ef = osRtxEventFlagsId(ef_id);
  410. // Check parameters
  411. if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags)) {
  412. EvrRtxEventFlagsGet(ef, 0U);
  413. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  414. return 0U;
  415. }
  416. EvrRtxEventFlagsGet(ef, ef->event_flags);
  417. return ef->event_flags;
  418. }
  419. /// Wait for one or more Event Flags to become signaled.
  420. /// \note API identical to osEventFlagsWait
  421. static uint32_t svcRtxEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) {
  422. os_event_flags_t *ef = osRtxEventFlagsId(ef_id);
  423. os_thread_t *thread;
  424. uint32_t event_flags;
  425. // Check parameters
  426. if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags) ||
  427. ((flags & ~(((uint32_t)1U << osRtxEventFlagsLimit) - 1U)) != 0U)) {
  428. EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter);
  429. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  430. return ((uint32_t)osErrorParameter);
  431. }
  432. #ifdef RTX_SAFETY_CLASS
  433. // Check running thread safety class
  434. thread = osRtxThreadGetRunning();
  435. if ((thread != NULL) &&
  436. ((thread->attr >> osRtxAttrClass_Pos) < (ef->attr >> osRtxAttrClass_Pos))) {
  437. EvrRtxEventFlagsError(ef, (int32_t)osErrorSafetyClass);
  438. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  439. return ((uint32_t)osErrorSafetyClass);
  440. }
  441. #endif
  442. // Check Event Flags
  443. event_flags = EventFlagsCheck(ef, flags, options);
  444. if (event_flags != 0U) {
  445. EvrRtxEventFlagsWaitCompleted(ef, flags, options, event_flags);
  446. } else {
  447. // Check if timeout is specified
  448. if (timeout != 0U) {
  449. EvrRtxEventFlagsWaitPending(ef, flags, options, timeout);
  450. // Suspend current Thread
  451. if (osRtxThreadWaitEnter(osRtxThreadWaitingEventFlags, timeout)) {
  452. thread = osRtxThreadGetRunning();
  453. osRtxThreadListPut(osRtxObject(ef), thread);
  454. // Store waiting flags and options
  455. thread->wait_flags = flags;
  456. thread->flags_options = (uint8_t)options;
  457. } else {
  458. EvrRtxEventFlagsWaitTimeout(ef);
  459. }
  460. event_flags = (uint32_t)osErrorTimeout;
  461. } else {
  462. EvrRtxEventFlagsWaitNotCompleted(ef, flags, options);
  463. event_flags = (uint32_t)osErrorResource;
  464. }
  465. }
  466. return event_flags;
  467. }
  468. /// Delete an Event Flags object.
  469. /// \note API identical to osEventFlagsDelete
  470. static osStatus_t svcRtxEventFlagsDelete (osEventFlagsId_t ef_id) {
  471. os_event_flags_t *ef = osRtxEventFlagsId(ef_id);
  472. os_thread_t *thread;
  473. // Check parameters
  474. if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags)) {
  475. EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter);
  476. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  477. return osErrorParameter;
  478. }
  479. #ifdef RTX_SAFETY_CLASS
  480. // Check running thread safety class
  481. thread = osRtxThreadGetRunning();
  482. if ((thread != NULL) &&
  483. ((thread->attr >> osRtxAttrClass_Pos) < (ef->attr >> osRtxAttrClass_Pos))) {
  484. EvrRtxEventFlagsError(ef, (int32_t)osErrorSafetyClass);
  485. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  486. return osErrorSafetyClass;
  487. }
  488. #endif
  489. // Unblock waiting threads
  490. if (ef->thread_list != NULL) {
  491. do {
  492. thread = osRtxThreadListGet(osRtxObject(ef));
  493. osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE);
  494. } while (ef->thread_list != NULL);
  495. osRtxThreadDispatch(NULL);
  496. }
  497. osRtxEventFlagsDestroy(ef);
  498. return osOK;
  499. }
  500. // Service Calls definitions
  501. //lint ++flb "Library Begin" [MISRA Note 11]
  502. SVC0_1(EventFlagsNew, osEventFlagsId_t, const osEventFlagsAttr_t *)
  503. SVC0_1(EventFlagsGetName, const char *, osEventFlagsId_t)
  504. SVC0_2(EventFlagsSet, uint32_t, osEventFlagsId_t, uint32_t)
  505. SVC0_2(EventFlagsClear, uint32_t, osEventFlagsId_t, uint32_t)
  506. SVC0_1(EventFlagsGet, uint32_t, osEventFlagsId_t)
  507. SVC0_4(EventFlagsWait, uint32_t, osEventFlagsId_t, uint32_t, uint32_t, uint32_t)
  508. SVC0_1(EventFlagsDelete, osStatus_t, osEventFlagsId_t)
  509. //lint --flb "Library End"
  510. // ==== ISR Calls ====
  511. /// Set the specified Event Flags.
  512. /// \note API identical to osEventFlagsSet
  513. __STATIC_INLINE
  514. uint32_t isrRtxEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) {
  515. os_event_flags_t *ef = osRtxEventFlagsId(ef_id);
  516. uint32_t event_flags;
  517. // Check parameters
  518. if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags) ||
  519. ((flags & ~(((uint32_t)1U << osRtxEventFlagsLimit) - 1U)) != 0U)) {
  520. EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter);
  521. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  522. return ((uint32_t)osErrorParameter);
  523. }
  524. // Set Event Flags
  525. event_flags = EventFlagsSet(ef, flags);
  526. // Register post ISR processing
  527. osRtxPostProcess(osRtxObject(ef));
  528. EvrRtxEventFlagsSetDone(ef, event_flags);
  529. return event_flags;
  530. }
  531. /// Wait for one or more Event Flags to become signaled.
  532. /// \note API identical to osEventFlagsWait
  533. __STATIC_INLINE
  534. uint32_t isrRtxEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) {
  535. os_event_flags_t *ef = osRtxEventFlagsId(ef_id);
  536. uint32_t event_flags;
  537. // Check parameters
  538. if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags) || (timeout != 0U) ||
  539. ((flags & ~(((uint32_t)1U << osRtxEventFlagsLimit) - 1U)) != 0U)) {
  540. EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter);
  541. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  542. return ((uint32_t)osErrorParameter);
  543. }
  544. // Check Event Flags
  545. event_flags = EventFlagsCheck(ef, flags, options);
  546. if (event_flags != 0U) {
  547. EvrRtxEventFlagsWaitCompleted(ef, flags, options, event_flags);
  548. } else {
  549. EvrRtxEventFlagsWaitNotCompleted(ef, flags, options);
  550. event_flags = (uint32_t)osErrorResource;
  551. }
  552. return event_flags;
  553. }
  554. // ==== Public API ====
  555. /// Create and Initialize an Event Flags object.
  556. osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr) {
  557. osEventFlagsId_t ef_id;
  558. EvrRtxEventFlagsNew(attr);
  559. if (IsException() || IsIrqMasked()) {
  560. EvrRtxEventFlagsError(NULL, (int32_t)osErrorISR);
  561. ef_id = NULL;
  562. } else {
  563. ef_id = __svcEventFlagsNew(attr);
  564. }
  565. return ef_id;
  566. }
  567. /// Get name of an Event Flags object.
  568. const char *osEventFlagsGetName (osEventFlagsId_t ef_id) {
  569. const char *name;
  570. if (IsException() || IsIrqMasked()) {
  571. name = svcRtxEventFlagsGetName(ef_id);
  572. } else {
  573. name = __svcEventFlagsGetName(ef_id);
  574. }
  575. return name;
  576. }
  577. /// Set the specified Event Flags.
  578. uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) {
  579. uint32_t event_flags;
  580. EvrRtxEventFlagsSet(ef_id, flags);
  581. if (IsException() || IsIrqMasked()) {
  582. event_flags = isrRtxEventFlagsSet(ef_id, flags);
  583. } else {
  584. event_flags = __svcEventFlagsSet(ef_id, flags);
  585. }
  586. return event_flags;
  587. }
  588. /// Clear the specified Event Flags.
  589. uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) {
  590. uint32_t event_flags;
  591. EvrRtxEventFlagsClear(ef_id, flags);
  592. if (IsException() || IsIrqMasked()) {
  593. event_flags = svcRtxEventFlagsClear(ef_id, flags);
  594. } else {
  595. event_flags = __svcEventFlagsClear(ef_id, flags);
  596. }
  597. return event_flags;
  598. }
  599. /// Get the current Event Flags.
  600. uint32_t osEventFlagsGet (osEventFlagsId_t ef_id) {
  601. uint32_t event_flags;
  602. if (IsException() || IsIrqMasked()) {
  603. event_flags = svcRtxEventFlagsGet(ef_id);
  604. } else {
  605. event_flags = __svcEventFlagsGet(ef_id);
  606. }
  607. return event_flags;
  608. }
  609. /// Wait for one or more Event Flags to become signaled.
  610. uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) {
  611. uint32_t event_flags;
  612. EvrRtxEventFlagsWait(ef_id, flags, options, timeout);
  613. if (IsException() || IsIrqMasked()) {
  614. event_flags = isrRtxEventFlagsWait(ef_id, flags, options, timeout);
  615. } else {
  616. event_flags = __svcEventFlagsWait(ef_id, flags, options, timeout);
  617. }
  618. return event_flags;
  619. }
  620. /// Delete an Event Flags object.
  621. osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id) {
  622. osStatus_t status;
  623. EvrRtxEventFlagsDelete(ef_id);
  624. if (IsException() || IsIrqMasked()) {
  625. EvrRtxEventFlagsError(ef_id, (int32_t)osErrorISR);
  626. status = osErrorISR;
  627. } else {
  628. status = __svcEventFlagsDelete(ef_id);
  629. }
  630. return status;
  631. }