rtx_msgqueue.c 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103
  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: Message Queue functions
  22. *
  23. * -----------------------------------------------------------------------------
  24. */
  25. #include "rtx_lib.h"
  26. // OS Runtime Object Memory Usage
  27. #ifdef RTX_OBJ_MEM_USAGE
  28. osRtxObjectMemUsage_t osRtxMessageQueueMemUsage \
  29. __attribute__((section(".data.os.msgqueue.obj"))) =
  30. { 0U, 0U, 0U };
  31. #endif
  32. // ==== Helper functions ====
  33. /// Put a Message into Queue sorted by Priority (Highest at Head).
  34. /// \param[in] mq message queue object.
  35. /// \param[in] msg message object.
  36. static void MessageQueuePut (os_message_queue_t *mq, os_message_t *msg) {
  37. #if (EXCLUSIVE_ACCESS == 0)
  38. uint32_t primask = __get_PRIMASK();
  39. #endif
  40. os_message_t *prev, *next;
  41. if (mq->msg_last != NULL) {
  42. prev = mq->msg_last;
  43. next = NULL;
  44. while ((prev != NULL) && (prev->priority < msg->priority)) {
  45. next = prev;
  46. prev = prev->prev;
  47. }
  48. msg->prev = prev;
  49. msg->next = next;
  50. if (prev != NULL) {
  51. prev->next = msg;
  52. } else {
  53. mq->msg_first = msg;
  54. }
  55. if (next != NULL) {
  56. next->prev = msg;
  57. } else {
  58. mq->msg_last = msg;
  59. }
  60. } else {
  61. msg->prev = NULL;
  62. msg->next = NULL;
  63. mq->msg_first= msg;
  64. mq->msg_last = msg;
  65. }
  66. #if (EXCLUSIVE_ACCESS == 0)
  67. __disable_irq();
  68. mq->msg_count++;
  69. if (primask == 0U) {
  70. __enable_irq();
  71. }
  72. #else
  73. (void)atomic_inc32(&mq->msg_count);
  74. #endif
  75. }
  76. /// Get a Message from Queue with Highest Priority.
  77. /// \param[in] mq message queue object.
  78. /// \return message object or NULL.
  79. static os_message_t *MessageQueueGet (os_message_queue_t *mq) {
  80. #if (EXCLUSIVE_ACCESS == 0)
  81. uint32_t primask = __get_PRIMASK();
  82. #endif
  83. os_message_t *msg;
  84. uint32_t count;
  85. uint8_t flags;
  86. #if (EXCLUSIVE_ACCESS == 0)
  87. __disable_irq();
  88. count = mq->msg_count;
  89. if (count != 0U) {
  90. mq->msg_count--;
  91. }
  92. if (primask == 0U) {
  93. __enable_irq();
  94. }
  95. #else
  96. count = atomic_dec32_nz(&mq->msg_count);
  97. #endif
  98. if (count != 0U) {
  99. msg = mq->msg_first;
  100. while (msg != NULL) {
  101. #if (EXCLUSIVE_ACCESS == 0)
  102. __disable_irq();
  103. flags = msg->flags;
  104. msg->flags = 1U;
  105. if (primask == 0U) {
  106. __enable_irq();
  107. }
  108. #else
  109. flags = atomic_wr8(&msg->flags, 1U);
  110. #endif
  111. if (flags == 0U) {
  112. break;
  113. }
  114. msg = msg->next;
  115. }
  116. } else {
  117. msg = NULL;
  118. }
  119. return msg;
  120. }
  121. /// Remove a Message from Queue
  122. /// \param[in] mq message queue object.
  123. /// \param[in] msg message object.
  124. static void MessageQueueRemove (os_message_queue_t *mq, const os_message_t *msg) {
  125. if (msg->prev != NULL) {
  126. msg->prev->next = msg->next;
  127. } else {
  128. mq->msg_first = msg->next;
  129. }
  130. if (msg->next != NULL) {
  131. msg->next->prev = msg->prev;
  132. } else {
  133. mq->msg_last = msg->prev;
  134. }
  135. }
  136. /// Verify that Message Queue object pointer is valid.
  137. /// \param[in] mq message queue object.
  138. /// \return true - valid, false - invalid.
  139. static bool_t IsMessageQueuePtrValid (const os_message_queue_t *mq) {
  140. #ifdef RTX_OBJ_PTR_CHECK
  141. //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
  142. uint32_t cb_start = (uint32_t)&__os_msgqueue_cb_start__;
  143. uint32_t cb_length = (uint32_t)&__os_msgqueue_cb_length__;
  144. // Check the section boundaries
  145. if (((uint32_t)mq - cb_start) >= cb_length) {
  146. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  147. return FALSE;
  148. }
  149. // Check the object alignment
  150. if ((((uint32_t)mq - cb_start) % sizeof(os_message_queue_t)) != 0U) {
  151. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  152. return FALSE;
  153. }
  154. #else
  155. // Check NULL pointer
  156. if (mq == NULL) {
  157. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  158. return FALSE;
  159. }
  160. #endif
  161. return TRUE;
  162. }
  163. // ==== Library functions ====
  164. /// Destroy a Message Queue object.
  165. /// \param[in] mq message queue object.
  166. static void osRtxMessageQueueDestroy (os_message_queue_t *mq) {
  167. // Mark object as invalid
  168. mq->id = osRtxIdInvalid;
  169. // Free data memory
  170. if ((mq->flags & osRtxFlagSystemMemory) != 0U) {
  171. (void)osRtxMemoryFree(osRtxInfo.mem.mq_data, mq->mp_info.block_base);
  172. }
  173. // Free object memory
  174. if ((mq->flags & osRtxFlagSystemObject) != 0U) {
  175. #ifdef RTX_OBJ_PTR_CHECK
  176. (void)osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq);
  177. #else
  178. if (osRtxInfo.mpi.message_queue != NULL) {
  179. (void)osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq);
  180. } else {
  181. (void)osRtxMemoryFree(osRtxInfo.mem.common, mq);
  182. }
  183. #endif
  184. #ifdef RTX_OBJ_MEM_USAGE
  185. osRtxMessageQueueMemUsage.cnt_free++;
  186. #endif
  187. }
  188. EvrRtxMessageQueueDestroyed(mq);
  189. }
  190. #ifdef RTX_SAFETY_CLASS
  191. /// Delete a Message Queue safety class.
  192. /// \param[in] safety_class safety class.
  193. /// \param[in] mode safety mode.
  194. void osRtxMessageQueueDeleteClass (uint32_t safety_class, uint32_t mode) {
  195. os_message_queue_t *mq;
  196. os_thread_t *thread;
  197. uint32_t length;
  198. //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
  199. mq = (os_message_queue_t *)(uint32_t)&__os_msgqueue_cb_start__;
  200. length = (uint32_t)&__os_msgqueue_cb_length__;
  201. while (length >= sizeof(os_message_queue_t)) {
  202. if ( (mq->id == osRtxIdMessageQueue) &&
  203. ((((mode & osSafetyWithSameClass) != 0U) &&
  204. ((mq->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
  205. (((mode & osSafetyWithLowerClass) != 0U) &&
  206. ((mq->attr >> osRtxAttrClass_Pos) < (uint8_t)safety_class)))) {
  207. while (mq->thread_list != NULL) {
  208. thread = osRtxThreadListGet(osRtxObject(mq));
  209. osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE);
  210. }
  211. osRtxMessageQueueDestroy(mq);
  212. }
  213. length -= sizeof(os_message_queue_t);
  214. mq++;
  215. }
  216. }
  217. #endif
  218. // ==== Post ISR processing ====
  219. /// Message Queue post ISR processing.
  220. /// \param[in] msg message object.
  221. static void osRtxMessageQueuePostProcess (os_message_t *msg) {
  222. //lint --e{954} "Pointer variable 'reg' is not pointing to const"
  223. os_message_queue_t *mq;
  224. os_message_t *msg0;
  225. os_thread_t *thread;
  226. uint32_t *reg;
  227. const void *ptr_src;
  228. void *ptr_dst;
  229. if (msg->flags != 0U) {
  230. // Remove Message
  231. //lint -e{9079} -e{9087} "cast between pointers to different object types"
  232. mq = *((os_message_queue_t **)(void *)&msg[1]);
  233. MessageQueueRemove(mq, msg);
  234. // Free memory
  235. msg->id = osRtxIdInvalid;
  236. (void)osRtxMemoryPoolFree(&mq->mp_info, msg);
  237. // Check if Thread is waiting to send a Message
  238. if (mq->thread_list != NULL) {
  239. // Try to allocate memory
  240. //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
  241. msg0 = osRtxMemoryPoolAlloc(&mq->mp_info);
  242. if (msg0 != NULL) {
  243. // Wakeup waiting Thread with highest Priority
  244. thread = osRtxThreadListGet(osRtxObject(mq));
  245. osRtxThreadWaitExit(thread, (uint32_t)osOK, FALSE);
  246. // Copy Message (R1: const void *msg_ptr, R2: uint8_t msg_prio)
  247. reg = osRtxThreadRegPtr(thread);
  248. //lint -e{923} "cast from unsigned int to pointer"
  249. ptr_src = (const void *)reg[1];
  250. (void)memcpy(&msg0[1], ptr_src, mq->msg_size);
  251. // Store Message into Queue
  252. msg0->id = osRtxIdMessage;
  253. msg0->flags = 0U;
  254. msg0->priority = (uint8_t)reg[2];
  255. MessageQueuePut(mq, msg0);
  256. EvrRtxMessageQueueInserted(mq, ptr_src);
  257. }
  258. }
  259. } else {
  260. // New Message
  261. //lint -e{9079} -e{9087} "cast between pointers to different object types"
  262. mq = (void *)msg->next;
  263. //lint -e{9087} "cast between pointers to different object types"
  264. ptr_src = (const void *)msg->prev;
  265. // Check if Thread is waiting to receive a Message
  266. if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessageGet)) {
  267. EvrRtxMessageQueueInserted(mq, ptr_src);
  268. // Wakeup waiting Thread with highest Priority
  269. thread = osRtxThreadListGet(osRtxObject(mq));
  270. osRtxThreadWaitExit(thread, (uint32_t)osOK, FALSE);
  271. // Copy Message (R1: void *msg_ptr, R2: uint8_t *msg_prio)
  272. reg = osRtxThreadRegPtr(thread);
  273. //lint -e{923} "cast from unsigned int to pointer"
  274. ptr_dst = (void *)reg[1];
  275. (void)memcpy(ptr_dst, &msg[1], mq->msg_size);
  276. if (reg[2] != 0U) {
  277. //lint -e{923} -e{9078} "cast from unsigned int to pointer"
  278. *((uint8_t *)reg[2]) = msg->priority;
  279. }
  280. EvrRtxMessageQueueRetrieved(mq, ptr_dst);
  281. // Free memory
  282. msg->id = osRtxIdInvalid;
  283. (void)osRtxMemoryPoolFree(&mq->mp_info, msg);
  284. } else {
  285. EvrRtxMessageQueueInserted(mq, ptr_src);
  286. MessageQueuePut(mq, msg);
  287. }
  288. }
  289. }
  290. // ==== Service Calls ====
  291. /// Create and Initialize a Message Queue object.
  292. /// \note API identical to osMessageQueueNew
  293. static osMessageQueueId_t svcRtxMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) {
  294. os_message_queue_t *mq;
  295. #ifdef RTX_SAFETY_CLASS
  296. const os_thread_t *thread = osRtxThreadGetRunning();
  297. uint32_t attr_bits;
  298. #endif
  299. void *mq_mem;
  300. uint32_t mq_size;
  301. uint32_t block_size;
  302. uint32_t size;
  303. uint8_t flags;
  304. const char *name;
  305. // Check parameters
  306. if ((msg_count == 0U) || (msg_size == 0U) ||
  307. ((__CLZ(msg_count) + __CLZ(msg_size)) < 32U)) {
  308. EvrRtxMessageQueueError(NULL, (int32_t)osErrorParameter);
  309. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  310. return NULL;
  311. }
  312. block_size = ((msg_size + 3U) & ~3UL) + sizeof(os_message_t);
  313. size = msg_count * block_size;
  314. // Process attributes
  315. if (attr != NULL) {
  316. name = attr->name;
  317. #ifdef RTX_SAFETY_CLASS
  318. attr_bits = attr->attr_bits;
  319. #endif
  320. //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
  321. mq = attr->cb_mem;
  322. //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
  323. mq_mem = attr->mq_mem;
  324. mq_size = attr->mq_size;
  325. #ifdef RTX_SAFETY_CLASS
  326. if ((attr_bits & osSafetyClass_Valid) != 0U) {
  327. if ((thread != NULL) &&
  328. ((thread->attr >> osRtxAttrClass_Pos) <
  329. (uint8_t)((attr_bits & osSafetyClass_Msk) >> osSafetyClass_Pos))) {
  330. EvrRtxMessageQueueError(NULL, (int32_t)osErrorSafetyClass);
  331. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  332. return NULL;
  333. }
  334. }
  335. #endif
  336. if (mq != NULL) {
  337. if (!IsMessageQueuePtrValid(mq) || (attr->cb_size != sizeof(os_message_queue_t))) {
  338. EvrRtxMessageQueueError(NULL, osRtxErrorInvalidControlBlock);
  339. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  340. return NULL;
  341. }
  342. } else {
  343. if (attr->cb_size != 0U) {
  344. EvrRtxMessageQueueError(NULL, osRtxErrorInvalidControlBlock);
  345. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  346. return NULL;
  347. }
  348. }
  349. if (mq_mem != NULL) {
  350. //lint -e{923} "cast from pointer to unsigned int" [MISRA Note 7]
  351. if ((((uint32_t)mq_mem & 3U) != 0U) || (mq_size < size)) {
  352. EvrRtxMessageQueueError(NULL, osRtxErrorInvalidDataMemory);
  353. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  354. return NULL;
  355. }
  356. } else {
  357. if (mq_size != 0U) {
  358. EvrRtxMessageQueueError(NULL, osRtxErrorInvalidDataMemory);
  359. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  360. return NULL;
  361. }
  362. }
  363. } else {
  364. name = NULL;
  365. #ifdef RTX_SAFETY_CLASS
  366. attr_bits = 0U;
  367. #endif
  368. mq = NULL;
  369. mq_mem = NULL;
  370. }
  371. // Allocate object memory if not provided
  372. if (mq == NULL) {
  373. if (osRtxInfo.mpi.message_queue != NULL) {
  374. //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
  375. mq = osRtxMemoryPoolAlloc(osRtxInfo.mpi.message_queue);
  376. #ifndef RTX_OBJ_PTR_CHECK
  377. } else {
  378. //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
  379. mq = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_message_queue_t), 1U);
  380. #endif
  381. }
  382. #ifdef RTX_OBJ_MEM_USAGE
  383. if (mq != NULL) {
  384. uint32_t used;
  385. osRtxMessageQueueMemUsage.cnt_alloc++;
  386. used = osRtxMessageQueueMemUsage.cnt_alloc - osRtxMessageQueueMemUsage.cnt_free;
  387. if (osRtxMessageQueueMemUsage.max_used < used) {
  388. osRtxMessageQueueMemUsage.max_used = used;
  389. }
  390. }
  391. #endif
  392. flags = osRtxFlagSystemObject;
  393. } else {
  394. flags = 0U;
  395. }
  396. // Allocate data memory if not provided
  397. if ((mq != NULL) && (mq_mem == NULL)) {
  398. //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
  399. mq_mem = osRtxMemoryAlloc(osRtxInfo.mem.mq_data, size, 0U);
  400. if (mq_mem == NULL) {
  401. if ((flags & osRtxFlagSystemObject) != 0U) {
  402. #ifdef RTX_OBJ_PTR_CHECK
  403. (void)osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq);
  404. #else
  405. if (osRtxInfo.mpi.message_queue != NULL) {
  406. (void)osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq);
  407. } else {
  408. (void)osRtxMemoryFree(osRtxInfo.mem.common, mq);
  409. }
  410. #endif
  411. #ifdef RTX_OBJ_MEM_USAGE
  412. osRtxMessageQueueMemUsage.cnt_free++;
  413. #endif
  414. }
  415. mq = NULL;
  416. } else {
  417. (void)memset(mq_mem, 0, size);
  418. }
  419. flags |= osRtxFlagSystemMemory;
  420. }
  421. if (mq != NULL) {
  422. // Initialize control block
  423. mq->id = osRtxIdMessageQueue;
  424. mq->flags = flags;
  425. mq->attr = 0U;
  426. mq->name = name;
  427. mq->thread_list = NULL;
  428. mq->msg_size = msg_size;
  429. mq->msg_count = 0U;
  430. mq->msg_first = NULL;
  431. mq->msg_last = NULL;
  432. #ifdef RTX_SAFETY_CLASS
  433. if ((attr_bits & osSafetyClass_Valid) != 0U) {
  434. mq->attr |= (uint8_t)((attr_bits & osSafetyClass_Msk) >>
  435. (osSafetyClass_Pos - osRtxAttrClass_Pos));
  436. } else {
  437. // Inherit safety class from the running thread
  438. if (thread != NULL) {
  439. mq->attr |= (uint8_t)(thread->attr & osRtxAttrClass_Msk);
  440. }
  441. }
  442. #endif
  443. (void)osRtxMemoryPoolInit(&mq->mp_info, msg_count, block_size, mq_mem);
  444. // Register post ISR processing function
  445. osRtxInfo.post_process.message = osRtxMessageQueuePostProcess;
  446. EvrRtxMessageQueueCreated(mq, mq->name);
  447. } else {
  448. EvrRtxMessageQueueError(NULL, (int32_t)osErrorNoMemory);
  449. }
  450. return mq;
  451. }
  452. /// Get name of a Message Queue object.
  453. /// \note API identical to osMessageQueueGetName
  454. static const char *svcRtxMessageQueueGetName (osMessageQueueId_t mq_id) {
  455. os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
  456. // Check parameters
  457. if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue)) {
  458. EvrRtxMessageQueueGetName(mq, NULL);
  459. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  460. return NULL;
  461. }
  462. EvrRtxMessageQueueGetName(mq, mq->name);
  463. return mq->name;
  464. }
  465. /// Put a Message into a Queue or timeout if Queue is full.
  466. /// \note API identical to osMessageQueuePut
  467. static osStatus_t svcRtxMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) {
  468. //lint --e{954} "Pointer variable 'reg' is not pointing to const"
  469. os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
  470. os_message_t *msg;
  471. os_thread_t *thread;
  472. uint32_t *reg;
  473. void *ptr;
  474. osStatus_t status;
  475. // Check parameters
  476. if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL)) {
  477. EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter);
  478. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  479. return osErrorParameter;
  480. }
  481. #ifdef RTX_SAFETY_CLASS
  482. // Check running thread safety class
  483. thread = osRtxThreadGetRunning();
  484. if ((thread != NULL) &&
  485. ((thread->attr >> osRtxAttrClass_Pos) < (mq->attr >> osRtxAttrClass_Pos))) {
  486. EvrRtxMessageQueueError(mq, (int32_t)osErrorSafetyClass);
  487. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  488. return osErrorSafetyClass;
  489. }
  490. #endif
  491. // Check if Thread is waiting to receive a Message
  492. if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessageGet)) {
  493. EvrRtxMessageQueueInserted(mq, msg_ptr);
  494. // Wakeup waiting Thread with highest Priority
  495. thread = osRtxThreadListGet(osRtxObject(mq));
  496. osRtxThreadWaitExit(thread, (uint32_t)osOK, TRUE);
  497. // Copy Message (R1: void *msg_ptr, R2: uint8_t *msg_prio)
  498. reg = osRtxThreadRegPtr(thread);
  499. //lint -e{923} "cast from unsigned int to pointer"
  500. ptr = (void *)reg[1];
  501. (void)memcpy(ptr, msg_ptr, mq->msg_size);
  502. if (reg[2] != 0U) {
  503. //lint -e{923} -e{9078} "cast from unsigned int to pointer"
  504. *((uint8_t *)reg[2]) = msg_prio;
  505. }
  506. EvrRtxMessageQueueRetrieved(mq, ptr);
  507. status = osOK;
  508. } else {
  509. // Try to allocate memory
  510. //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
  511. msg = osRtxMemoryPoolAlloc(&mq->mp_info);
  512. if (msg != NULL) {
  513. // Copy Message
  514. (void)memcpy(&msg[1], msg_ptr, mq->msg_size);
  515. // Put Message into Queue
  516. msg->id = osRtxIdMessage;
  517. msg->flags = 0U;
  518. msg->priority = msg_prio;
  519. MessageQueuePut(mq, msg);
  520. EvrRtxMessageQueueInserted(mq, msg_ptr);
  521. status = osOK;
  522. } else {
  523. // No memory available
  524. if (timeout != 0U) {
  525. EvrRtxMessageQueuePutPending(mq, msg_ptr, timeout);
  526. // Suspend current Thread
  527. if (osRtxThreadWaitEnter(osRtxThreadWaitingMessagePut, timeout)) {
  528. osRtxThreadListPut(osRtxObject(mq), osRtxThreadGetRunning());
  529. } else {
  530. EvrRtxMessageQueuePutTimeout(mq);
  531. }
  532. status = osErrorTimeout;
  533. } else {
  534. EvrRtxMessageQueueNotInserted(mq, msg_ptr);
  535. status = osErrorResource;
  536. }
  537. }
  538. }
  539. return status;
  540. }
  541. /// Get a Message from a Queue or timeout if Queue is empty.
  542. /// \note API identical to osMessageQueueGet
  543. static osStatus_t svcRtxMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) {
  544. os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
  545. os_message_t *msg;
  546. os_thread_t *thread;
  547. const uint32_t *reg;
  548. const void *ptr;
  549. osStatus_t status;
  550. // Check parameters
  551. if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL)) {
  552. EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter);
  553. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  554. return osErrorParameter;
  555. }
  556. #ifdef RTX_SAFETY_CLASS
  557. // Check running thread safety class
  558. thread = osRtxThreadGetRunning();
  559. if ((thread != NULL) &&
  560. ((thread->attr >> osRtxAttrClass_Pos) < (mq->attr >> osRtxAttrClass_Pos))) {
  561. EvrRtxMessageQueueError(mq, (int32_t)osErrorSafetyClass);
  562. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  563. return osErrorSafetyClass;
  564. }
  565. #endif
  566. // Get Message from Queue
  567. msg = MessageQueueGet(mq);
  568. if (msg != NULL) {
  569. MessageQueueRemove(mq, msg);
  570. // Copy Message
  571. (void)memcpy(msg_ptr, &msg[1], mq->msg_size);
  572. if (msg_prio != NULL) {
  573. *msg_prio = msg->priority;
  574. }
  575. EvrRtxMessageQueueRetrieved(mq, msg_ptr);
  576. // Free memory
  577. msg->id = osRtxIdInvalid;
  578. (void)osRtxMemoryPoolFree(&mq->mp_info, msg);
  579. // Check if Thread is waiting to send a Message
  580. if (mq->thread_list != NULL) {
  581. // Try to allocate memory
  582. //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
  583. msg = osRtxMemoryPoolAlloc(&mq->mp_info);
  584. if (msg != NULL) {
  585. // Wakeup waiting Thread with highest Priority
  586. thread = osRtxThreadListGet(osRtxObject(mq));
  587. osRtxThreadWaitExit(thread, (uint32_t)osOK, TRUE);
  588. // Copy Message (R1: const void *msg_ptr, R2: uint8_t msg_prio)
  589. reg = osRtxThreadRegPtr(thread);
  590. //lint -e{923} "cast from unsigned int to pointer"
  591. ptr = (const void *)reg[1];
  592. (void)memcpy(&msg[1], ptr, mq->msg_size);
  593. // Store Message into Queue
  594. msg->id = osRtxIdMessage;
  595. msg->flags = 0U;
  596. msg->priority = (uint8_t)reg[2];
  597. MessageQueuePut(mq, msg);
  598. EvrRtxMessageQueueInserted(mq, ptr);
  599. }
  600. }
  601. status = osOK;
  602. } else {
  603. // No Message available
  604. if (timeout != 0U) {
  605. EvrRtxMessageQueueGetPending(mq, msg_ptr, timeout);
  606. // Suspend current Thread
  607. if (osRtxThreadWaitEnter(osRtxThreadWaitingMessageGet, timeout)) {
  608. osRtxThreadListPut(osRtxObject(mq), osRtxThreadGetRunning());
  609. } else {
  610. EvrRtxMessageQueueGetTimeout(mq);
  611. }
  612. status = osErrorTimeout;
  613. } else {
  614. EvrRtxMessageQueueNotRetrieved(mq, msg_ptr);
  615. status = osErrorResource;
  616. }
  617. }
  618. return status;
  619. }
  620. /// Get maximum number of messages in a Message Queue.
  621. /// \note API identical to osMessageQueueGetCapacity
  622. static uint32_t svcRtxMessageQueueGetCapacity (osMessageQueueId_t mq_id) {
  623. os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
  624. // Check parameters
  625. if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue)) {
  626. EvrRtxMessageQueueGetCapacity(mq, 0U);
  627. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  628. return 0U;
  629. }
  630. EvrRtxMessageQueueGetCapacity(mq, mq->mp_info.max_blocks);
  631. return mq->mp_info.max_blocks;
  632. }
  633. /// Get maximum message size in a Memory Pool.
  634. /// \note API identical to osMessageQueueGetMsgSize
  635. static uint32_t svcRtxMessageQueueGetMsgSize (osMessageQueueId_t mq_id) {
  636. os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
  637. // Check parameters
  638. if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue)) {
  639. EvrRtxMessageQueueGetMsgSize(mq, 0U);
  640. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  641. return 0U;
  642. }
  643. EvrRtxMessageQueueGetMsgSize(mq, mq->msg_size);
  644. return mq->msg_size;
  645. }
  646. /// Get number of queued messages in a Message Queue.
  647. /// \note API identical to osMessageQueueGetCount
  648. static uint32_t svcRtxMessageQueueGetCount (osMessageQueueId_t mq_id) {
  649. os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
  650. // Check parameters
  651. if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue)) {
  652. EvrRtxMessageQueueGetCount(mq, 0U);
  653. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  654. return 0U;
  655. }
  656. EvrRtxMessageQueueGetCount(mq, mq->msg_count);
  657. return mq->msg_count;
  658. }
  659. /// Get number of available slots for messages in a Message Queue.
  660. /// \note API identical to osMessageQueueGetSpace
  661. static uint32_t svcRtxMessageQueueGetSpace (osMessageQueueId_t mq_id) {
  662. os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
  663. // Check parameters
  664. if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue)) {
  665. EvrRtxMessageQueueGetSpace(mq, 0U);
  666. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  667. return 0U;
  668. }
  669. EvrRtxMessageQueueGetSpace(mq, mq->mp_info.max_blocks - mq->msg_count);
  670. return (mq->mp_info.max_blocks - mq->msg_count);
  671. }
  672. /// Reset a Message Queue to initial empty state.
  673. /// \note API identical to osMessageQueueReset
  674. static osStatus_t svcRtxMessageQueueReset (osMessageQueueId_t mq_id) {
  675. os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
  676. os_message_t *msg;
  677. os_thread_t *thread;
  678. const uint32_t *reg;
  679. const void *ptr;
  680. // Check parameters
  681. if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue)) {
  682. EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter);
  683. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  684. return osErrorParameter;
  685. }
  686. #ifdef RTX_SAFETY_CLASS
  687. // Check running thread safety class
  688. thread = osRtxThreadGetRunning();
  689. if ((thread != NULL) &&
  690. ((thread->attr >> osRtxAttrClass_Pos) < (mq->attr >> osRtxAttrClass_Pos))) {
  691. EvrRtxMessageQueueError(mq, (int32_t)osErrorSafetyClass);
  692. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  693. return osErrorSafetyClass;
  694. }
  695. #endif
  696. // Remove Messages from Queue
  697. for (;;) {
  698. // Get Message from Queue
  699. msg = MessageQueueGet(mq);
  700. if (msg == NULL) {
  701. break;
  702. }
  703. MessageQueueRemove(mq, msg);
  704. EvrRtxMessageQueueRetrieved(mq, NULL);
  705. // Free memory
  706. msg->id = osRtxIdInvalid;
  707. (void)osRtxMemoryPoolFree(&mq->mp_info, msg);
  708. }
  709. // Check if Threads are waiting to send Messages
  710. if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessagePut)) {
  711. do {
  712. // Try to allocate memory
  713. //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
  714. msg = osRtxMemoryPoolAlloc(&mq->mp_info);
  715. if (msg != NULL) {
  716. // Wakeup waiting Thread with highest Priority
  717. thread = osRtxThreadListGet(osRtxObject(mq));
  718. osRtxThreadWaitExit(thread, (uint32_t)osOK, FALSE);
  719. // Copy Message (R1: const void *msg_ptr, R2: uint8_t msg_prio)
  720. reg = osRtxThreadRegPtr(thread);
  721. //lint -e{923} "cast from unsigned int to pointer"
  722. ptr = (const void *)reg[1];
  723. (void)memcpy(&msg[1], ptr, mq->msg_size);
  724. // Store Message into Queue
  725. msg->id = osRtxIdMessage;
  726. msg->flags = 0U;
  727. msg->priority = (uint8_t)reg[2];
  728. MessageQueuePut(mq, msg);
  729. EvrRtxMessageQueueInserted(mq, ptr);
  730. }
  731. } while ((msg != NULL) && (mq->thread_list != NULL));
  732. osRtxThreadDispatch(NULL);
  733. }
  734. EvrRtxMessageQueueResetDone(mq);
  735. return osOK;
  736. }
  737. /// Delete a Message Queue object.
  738. /// \note API identical to osMessageQueueDelete
  739. static osStatus_t svcRtxMessageQueueDelete (osMessageQueueId_t mq_id) {
  740. os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
  741. os_thread_t *thread;
  742. // Check parameters
  743. if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue)) {
  744. EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter);
  745. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  746. return osErrorParameter;
  747. }
  748. #ifdef RTX_SAFETY_CLASS
  749. // Check running thread safety class
  750. thread = osRtxThreadGetRunning();
  751. if ((thread != NULL) &&
  752. ((thread->attr >> osRtxAttrClass_Pos) < (mq->attr >> osRtxAttrClass_Pos))) {
  753. EvrRtxMessageQueueError(mq, (int32_t)osErrorSafetyClass);
  754. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  755. return osErrorSafetyClass;
  756. }
  757. #endif
  758. // Unblock waiting threads
  759. if (mq->thread_list != NULL) {
  760. do {
  761. thread = osRtxThreadListGet(osRtxObject(mq));
  762. osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE);
  763. } while (mq->thread_list != NULL);
  764. osRtxThreadDispatch(NULL);
  765. }
  766. osRtxMessageQueueDestroy(mq);
  767. return osOK;
  768. }
  769. // Service Calls definitions
  770. //lint ++flb "Library Begin" [MISRA Note 11]
  771. SVC0_3(MessageQueueNew, osMessageQueueId_t, uint32_t, uint32_t, const osMessageQueueAttr_t *)
  772. SVC0_1(MessageQueueGetName, const char *, osMessageQueueId_t)
  773. SVC0_4(MessageQueuePut, osStatus_t, osMessageQueueId_t, const void *, uint8_t, uint32_t)
  774. SVC0_4(MessageQueueGet, osStatus_t, osMessageQueueId_t, void *, uint8_t *, uint32_t)
  775. SVC0_1(MessageQueueGetCapacity, uint32_t, osMessageQueueId_t)
  776. SVC0_1(MessageQueueGetMsgSize, uint32_t, osMessageQueueId_t)
  777. SVC0_1(MessageQueueGetCount, uint32_t, osMessageQueueId_t)
  778. SVC0_1(MessageQueueGetSpace, uint32_t, osMessageQueueId_t)
  779. SVC0_1(MessageQueueReset, osStatus_t, osMessageQueueId_t)
  780. SVC0_1(MessageQueueDelete, osStatus_t, osMessageQueueId_t)
  781. //lint --flb "Library End"
  782. // ==== ISR Calls ====
  783. /// Put a Message into a Queue or timeout if Queue is full.
  784. /// \note API identical to osMessageQueuePut
  785. __STATIC_INLINE
  786. osStatus_t isrRtxMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) {
  787. os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
  788. os_message_t *msg;
  789. osStatus_t status;
  790. // Check parameters
  791. if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL) || (timeout != 0U)) {
  792. EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter);
  793. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  794. return osErrorParameter;
  795. }
  796. // Try to allocate memory
  797. //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
  798. msg = osRtxMemoryPoolAlloc(&mq->mp_info);
  799. if (msg != NULL) {
  800. // Copy Message
  801. (void)memcpy(&msg[1], msg_ptr, mq->msg_size);
  802. msg->id = osRtxIdMessage;
  803. msg->flags = 0U;
  804. msg->priority = msg_prio;
  805. // Register post ISR processing
  806. //lint -e{9079} -e{9087} "cast between pointers to different object types"
  807. *((const void **)(void *)&msg->prev) = msg_ptr;
  808. //lint -e{9079} -e{9087} "cast between pointers to different object types"
  809. *( (void **) &msg->next) = mq;
  810. osRtxPostProcess(osRtxObject(msg));
  811. EvrRtxMessageQueueInsertPending(mq, msg_ptr);
  812. status = osOK;
  813. } else {
  814. // No memory available
  815. EvrRtxMessageQueueNotInserted(mq, msg_ptr);
  816. status = osErrorResource;
  817. }
  818. return status;
  819. }
  820. /// Get a Message from a Queue or timeout if Queue is empty.
  821. /// \note API identical to osMessageQueueGet
  822. __STATIC_INLINE
  823. osStatus_t isrRtxMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) {
  824. os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
  825. os_message_t *msg;
  826. osStatus_t status;
  827. // Check parameters
  828. if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL) || (timeout != 0U)) {
  829. EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter);
  830. //lint -e{904} "Return statement before end of function" [MISRA Note 1]
  831. return osErrorParameter;
  832. }
  833. // Get Message from Queue
  834. msg = MessageQueueGet(mq);
  835. if (msg != NULL) {
  836. // Copy Message
  837. memcpy(msg_ptr, &msg[1], mq->msg_size);
  838. if (msg_prio != NULL) {
  839. *msg_prio = msg->priority;
  840. }
  841. // Register post ISR processing
  842. //lint -e{9079} -e{9087} "cast between pointers to different object types"
  843. *((os_message_queue_t **)(void *)&msg[1]) = mq;
  844. osRtxPostProcess(osRtxObject(msg));
  845. EvrRtxMessageQueueRetrieved(mq, msg_ptr);
  846. status = osOK;
  847. } else {
  848. // No Message available
  849. EvrRtxMessageQueueNotRetrieved(mq, msg_ptr);
  850. status = osErrorResource;
  851. }
  852. return status;
  853. }
  854. // ==== Library functions ====
  855. /// Create a Message Queue for the Timer Thread.
  856. int32_t osRtxMessageQueueTimerSetup (void) {
  857. int32_t ret = -1;
  858. osRtxInfo.timer.mq = osRtxMessageQueueId(
  859. svcRtxMessageQueueNew(osRtxConfig.timer_mq_mcnt, sizeof(os_timer_finfo_t), osRtxConfig.timer_mq_attr)
  860. );
  861. if (osRtxInfo.timer.mq != NULL) {
  862. ret = 0;
  863. }
  864. return ret;
  865. }
  866. // ==== Public API ====
  867. /// Create and Initialize a Message Queue object.
  868. osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) {
  869. osMessageQueueId_t mq_id;
  870. EvrRtxMessageQueueNew(msg_count, msg_size, attr);
  871. if (IsException() || IsIrqMasked()) {
  872. EvrRtxMessageQueueError(NULL, (int32_t)osErrorISR);
  873. mq_id = NULL;
  874. } else {
  875. mq_id = __svcMessageQueueNew(msg_count, msg_size, attr);
  876. }
  877. return mq_id;
  878. }
  879. /// Get name of a Message Queue object.
  880. const char *osMessageQueueGetName (osMessageQueueId_t mq_id) {
  881. const char *name;
  882. if (IsException() || IsIrqMasked()) {
  883. name = svcRtxMessageQueueGetName(mq_id);
  884. } else {
  885. name = __svcMessageQueueGetName(mq_id);
  886. }
  887. return name;
  888. }
  889. /// Put a Message into a Queue or timeout if Queue is full.
  890. osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) {
  891. osStatus_t status;
  892. EvrRtxMessageQueuePut(mq_id, msg_ptr, msg_prio, timeout);
  893. if (IsException() || IsIrqMasked()) {
  894. status = isrRtxMessageQueuePut(mq_id, msg_ptr, msg_prio, timeout);
  895. } else {
  896. status = __svcMessageQueuePut(mq_id, msg_ptr, msg_prio, timeout);
  897. }
  898. return status;
  899. }
  900. /// Get a Message from a Queue or timeout if Queue is empty.
  901. osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) {
  902. osStatus_t status;
  903. EvrRtxMessageQueueGet(mq_id, msg_ptr, msg_prio, timeout);
  904. if (IsException() || IsIrqMasked()) {
  905. status = isrRtxMessageQueueGet(mq_id, msg_ptr, msg_prio, timeout);
  906. } else {
  907. status = __svcMessageQueueGet(mq_id, msg_ptr, msg_prio, timeout);
  908. }
  909. return status;
  910. }
  911. /// Get maximum number of messages in a Message Queue.
  912. uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id) {
  913. uint32_t capacity;
  914. if (IsException() || IsIrqMasked()) {
  915. capacity = svcRtxMessageQueueGetCapacity(mq_id);
  916. } else {
  917. capacity = __svcMessageQueueGetCapacity(mq_id);
  918. }
  919. return capacity;
  920. }
  921. /// Get maximum message size in a Memory Pool.
  922. uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id) {
  923. uint32_t msg_size;
  924. if (IsException() || IsIrqMasked()) {
  925. msg_size = svcRtxMessageQueueGetMsgSize(mq_id);
  926. } else {
  927. msg_size = __svcMessageQueueGetMsgSize(mq_id);
  928. }
  929. return msg_size;
  930. }
  931. /// Get number of queued messages in a Message Queue.
  932. uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) {
  933. uint32_t count;
  934. if (IsException() || IsIrqMasked()) {
  935. count = svcRtxMessageQueueGetCount(mq_id);
  936. } else {
  937. count = __svcMessageQueueGetCount(mq_id);
  938. }
  939. return count;
  940. }
  941. /// Get number of available slots for messages in a Message Queue.
  942. uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) {
  943. uint32_t space;
  944. if (IsException() || IsIrqMasked()) {
  945. space = svcRtxMessageQueueGetSpace(mq_id);
  946. } else {
  947. space = __svcMessageQueueGetSpace(mq_id);
  948. }
  949. return space;
  950. }
  951. /// Reset a Message Queue to initial empty state.
  952. osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id) {
  953. osStatus_t status;
  954. EvrRtxMessageQueueReset(mq_id);
  955. if (IsException() || IsIrqMasked()) {
  956. EvrRtxMessageQueueError(mq_id, (int32_t)osErrorISR);
  957. status = osErrorISR;
  958. } else {
  959. status = __svcMessageQueueReset(mq_id);
  960. }
  961. return status;
  962. }
  963. /// Delete a Message Queue object.
  964. osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) {
  965. osStatus_t status;
  966. EvrRtxMessageQueueDelete(mq_id);
  967. if (IsException() || IsIrqMasked()) {
  968. EvrRtxMessageQueueError(mq_id, (int32_t)osErrorISR);
  969. status = osErrorISR;
  970. } else {
  971. status = __svcMessageQueueDelete(mq_id);
  972. }
  973. return status;
  974. }