os_mbox.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /*
  2. * Copyright (c) 2021, Meco Jianting Man <jiantingman@foxmail.com>
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-11-27 Meco Man first version
  9. */
  10. /*
  11. *********************************************************************************************************
  12. * uC/OS-II
  13. * The Real-Time Kernel
  14. *
  15. * Copyright 1992-2020 Silicon Laboratories Inc. www.silabs.com
  16. *
  17. * SPDX-License-Identifier: APACHE-2.0
  18. *
  19. * This software is subject to an open source license and is distributed by
  20. * Silicon Laboratories Inc. pursuant to the terms of the Apache License,
  21. * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
  22. *
  23. *********************************************************************************************************
  24. */
  25. /*
  26. *********************************************************************************************************
  27. *
  28. * MESSAGE MAILBOX MANAGEMENT
  29. *
  30. * Filename : os_mbox.c
  31. * Version : V2.93.00
  32. *********************************************************************************************************
  33. */
  34. #include <ucos_ii.h>
  35. #if OS_MBOX_EN > 0u
  36. /*
  37. *********************************************************************************************************
  38. * ACCEPT MESSAGE FROM MAILBOX
  39. *
  40. * Description: This function checks the mailbox to see if a message is available. Unlike OSMboxPend(),
  41. * OSMboxAccept() does not suspend the calling task if a message is not available.
  42. *
  43. * Arguments : pevent is a pointer to the event control block
  44. *
  45. * Returns : != (void *)0 is the message in the mailbox if one is available. The mailbox is cleared
  46. * so the next time OSMboxAccept() is called, the mailbox will be empty.
  47. * == (void *)0 if the mailbox is empty or,
  48. * if 'pevent' is a NULL pointer or,
  49. * if you didn't pass the proper event pointer.
  50. *********************************************************************************************************
  51. */
  52. #if OS_MBOX_ACCEPT_EN > 0u
  53. void *OSMboxAccept (OS_EVENT *pevent)
  54. {
  55. INT8U err;
  56. return OSQAccept(pevent, &err);
  57. }
  58. #endif
  59. /*
  60. *********************************************************************************************************
  61. * CREATE A MESSAGE MAILBOX
  62. *
  63. * Description: This function creates a message mailbox if free event control blocks are available.
  64. *
  65. * Arguments : pmsg is a pointer to a message that you wish to deposit in the mailbox. If
  66. * you set this value to the NULL pointer (i.e. (void *)0) then the mailbox
  67. * will be considered empty.
  68. *
  69. * Returns : != (OS_EVENT *)0 is a pointer to the event control clock (OS_EVENT) associated with the
  70. * created mailbox
  71. * == (OS_EVENT *)0 if no event control blocks were available
  72. *********************************************************************************************************
  73. */
  74. OS_EVENT *OSMboxCreate (void *pmsg)
  75. {
  76. OS_EVENT *pevent;
  77. pevent = OSQCreate(RT_NULL, 1);
  78. if(pmsg && pevent) {
  79. OSQPost(pevent, pmsg);
  80. }
  81. return pevent;
  82. }
  83. /*
  84. *********************************************************************************************************
  85. * DELETE A MAIBOX
  86. *
  87. * Description: This function deletes a mailbox and readies all tasks pending on the mailbox.
  88. *
  89. * Arguments : pevent is a pointer to the event control block associated with the desired
  90. * mailbox.
  91. *
  92. * opt determines delete options as follows:
  93. * opt == OS_DEL_NO_PEND Delete the mailbox ONLY if no task pending
  94. * opt == OS_DEL_ALWAYS Deletes the mailbox even if tasks are waiting.
  95. * In this case, all the tasks pending will be readied.
  96. *
  97. * perr is a pointer to an error code that can contain one of the following values:
  98. * OS_ERR_NONE The call was successful and the mailbox was deleted
  99. * OS_ERR_DEL_ISR If you attempted to delete the mailbox from an ISR
  100. * OS_ERR_INVALID_OPT An invalid option was specified
  101. * OS_ERR_ILLEGAL_DEL_RUN_TIME If you tried to delete a mailbox after safety
  102. * critical operation started.
  103. * OS_ERR_TASK_WAITING One or more tasks were waiting on the mailbox
  104. * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mailbox
  105. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
  106. *
  107. * Returns : pevent upon error
  108. * (OS_EVENT *)0 if the mailbox was successfully deleted.
  109. *
  110. * Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
  111. * the mailbox MUST check the return code of OSMboxPend().
  112. * 2) OSMboxAccept() callers will not know that the intended mailbox has been deleted!
  113. * 3) This call can potentially disable interrupts for a long time. The interrupt disable
  114. * time is directly proportional to the number of tasks waiting on the mailbox.
  115. * 4) Because ALL tasks pending on the mailbox will be readied, you MUST be careful in
  116. * applications where the mailbox is used for mutual exclusion because the resource(s)
  117. * will no longer be guarded by the mailbox.
  118. * 5) All tasks that were waiting for the mailbox will be readied and returned an
  119. * OS_ERR_PEND_ABORT if OSMboxDel() was called with OS_DEL_ALWAYS
  120. *********************************************************************************************************
  121. */
  122. #if OS_MBOX_DEL_EN > 0u
  123. OS_EVENT *OSMboxDel (OS_EVENT *pevent,
  124. INT8U opt,
  125. INT8U *perr)
  126. {
  127. return OSQDel(pevent, opt, perr);
  128. }
  129. #endif
  130. /*
  131. *********************************************************************************************************
  132. * PEND ON MAILBOX FOR A MESSAGE
  133. *
  134. * Description: This function waits for a message to be sent to a mailbox
  135. *
  136. * Arguments : pevent is a pointer to the event control block associated with the desired mailbox
  137. *
  138. * timeout is an optional timeout period (in clock ticks). If non-zero, your task will
  139. * wait for a message to arrive at the mailbox up to the amount of time
  140. * specified by this argument. If you specify 0, however, your task will wait
  141. * forever at the specified mailbox or, until a message arrives.
  142. *
  143. * perr is a pointer to where an error message will be deposited. Possible error
  144. * messages are:
  145. *
  146. * OS_ERR_NONE The call was successful and your task received a
  147. * message.
  148. * OS_ERR_TIMEOUT A message was not received within the specified 'timeout'.
  149. * OS_ERR_PEND_ABORT The wait on the mailbox was aborted.
  150. * OS_ERR_EVENT_TYPE Invalid event type
  151. * OS_ERR_PEND_ISR If you called this function from an ISR and the result
  152. * would lead to a suspension.
  153. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
  154. * OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked
  155. *
  156. * Returns : != (void *)0 is a pointer to the message received
  157. * == (void *)0 if no message was received or,
  158. * if 'pevent' is a NULL pointer or,
  159. * if you didn't pass the proper pointer to the event control block.
  160. *********************************************************************************************************
  161. */
  162. void *OSMboxPend (OS_EVENT *pevent,
  163. INT32U timeout,
  164. INT8U *perr)
  165. {
  166. return OSQPend(pevent, timeout, perr);
  167. }
  168. /*
  169. *********************************************************************************************************
  170. * ABORT WAITING ON A MESSAGE MAILBOX
  171. *
  172. * Description: This function aborts & readies any tasks currently waiting on a mailbox. This function
  173. * should be used to fault-abort the wait on the mailbox, rather than to normally signal
  174. * the mailbox via OSMboxPost() or OSMboxPostOpt().
  175. *
  176. * Arguments : pevent is a pointer to the event control block associated with the desired mailbox.
  177. *
  178. * opt determines the type of ABORT performed:
  179. * OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the
  180. * mailbox
  181. * OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the
  182. * mailbox
  183. *
  184. * perr is a pointer to where an error message will be deposited. Possible error
  185. * messages are:
  186. *
  187. * OS_ERR_NONE No tasks were waiting on the mailbox.
  188. * OS_ERR_PEND_ABORT At least one task waiting on the mailbox was readied
  189. * and informed of the aborted wait; check return value
  190. * for the number of tasks whose wait on the mailbox
  191. * was aborted.
  192. * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mailbox.
  193. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
  194. *
  195. * Returns : == 0 if no tasks were waiting on the mailbox, or upon error.
  196. * > 0 if one or more tasks waiting on the mailbox are now readied and informed.
  197. *********************************************************************************************************
  198. */
  199. #if OS_MBOX_PEND_ABORT_EN > 0u
  200. INT8U OSMboxPendAbort (OS_EVENT *pevent,
  201. INT8U opt,
  202. INT8U *perr)
  203. {
  204. return OSQPendAbort(pevent, opt, perr);
  205. }
  206. #endif
  207. /*
  208. *********************************************************************************************************
  209. * POST MESSAGE TO A MAILBOX
  210. *
  211. * Description: This function sends a message to a mailbox
  212. *
  213. * Arguments : pevent is a pointer to the event control block associated with the desired mailbox
  214. *
  215. * pmsg is a pointer to the message to send. You MUST NOT send a NULL pointer.
  216. *
  217. * Returns : OS_ERR_NONE The call was successful and the message was sent
  218. * OS_ERR_MBOX_FULL If the mailbox already contains a message. You can can only send one
  219. * message at a time and thus, the message MUST be consumed before you
  220. * are allowed to send another one.
  221. * OS_ERR_EVENT_TYPE If you are attempting to post to a non mailbox.
  222. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
  223. * OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer
  224. *
  225. * Note(s) : 1) HPT means Highest Priority Task
  226. *********************************************************************************************************
  227. */
  228. #if OS_MBOX_POST_EN > 0u
  229. INT8U OSMboxPost (OS_EVENT *pevent,
  230. void *pmsg)
  231. {
  232. return OSQPost(pevent, pmsg);
  233. }
  234. #endif
  235. /*
  236. *********************************************************************************************************
  237. * POST MESSAGE TO A MAILBOX
  238. *
  239. * Description: This function sends a message to a mailbox
  240. *
  241. * Arguments : pevent is a pointer to the event control block associated with the desired mailbox
  242. *
  243. * pmsg is a pointer to the message to send. You MUST NOT send a NULL pointer.
  244. *
  245. * opt determines the type of POST performed:
  246. * OS_POST_OPT_NONE POST to a single waiting task
  247. * (Identical to OSMboxPost())
  248. * OS_POST_OPT_BROADCAST POST to ALL tasks that are waiting on the mailbox
  249. *
  250. * OS_POST_OPT_NO_SCHED Indicates that the scheduler will NOT be invoked
  251. *
  252. * Returns : OS_ERR_NONE The call was successful and the message was sent
  253. * OS_ERR_MBOX_FULL If the mailbox already contains a message. You can can only send one
  254. * message at a time and thus, the message MUST be consumed before you
  255. * are allowed to send another one.
  256. * OS_ERR_EVENT_TYPE If you are attempting to post to a non mailbox.
  257. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
  258. * OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer
  259. *
  260. * Note(s) : 1) HPT means Highest Priority Task
  261. *
  262. * Warning : Interrupts can be disabled for a long time if you do a 'broadcast'. In fact, the
  263. * interrupt disable time is proportional to the number of tasks waiting on the mailbox.
  264. *********************************************************************************************************
  265. */
  266. #if OS_MBOX_POST_OPT_EN > 0u
  267. INT8U OSMboxPostOpt (OS_EVENT *pevent,
  268. void *pmsg,
  269. INT8U opt)
  270. {
  271. return OSQPostOpt(pevent, pmsg, opt);
  272. }
  273. #endif
  274. /*
  275. *********************************************************************************************************
  276. * QUERY A MESSAGE MAILBOX
  277. *
  278. * Description: This function obtains information about a message mailbox.
  279. *
  280. * Arguments : pevent is a pointer to the event control block associated with the desired mailbox
  281. *
  282. * p_mbox_data is a pointer to a structure that will contain information about the message
  283. * mailbox.
  284. *
  285. * Returns : OS_ERR_NONE The call was successful and the message was sent
  286. * OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non mailbox.
  287. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
  288. * OS_ERR_PDATA_NULL If 'p_mbox_data' is a NULL pointer
  289. *********************************************************************************************************
  290. */
  291. #if OS_MBOX_QUERY_EN > 0u
  292. INT8U OSMboxQuery (OS_EVENT *pevent,
  293. OS_MBOX_DATA *p_mbox_data)
  294. {
  295. INT8U err;
  296. OS_Q_DATA q_data;
  297. err = OSQQuery(pevent, &q_data);
  298. p_mbox_data->OSMsg = q_data.OSMsg;
  299. return err;
  300. }
  301. #endif /* OS_MBOX_QUERY_EN */
  302. #endif /* OS_MBOX_EN */