训练营PLSR题目
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

365 linhas
14 KiB

  1. /*
  2. ************************************************************************************************************************
  3. * uC/OS-III
  4. * The Real-Time Kernel
  5. *
  6. * (c) Copyright 2009-2014; Micrium, Inc.; Weston, FL
  7. * All rights reserved. Protected by international copyright laws.
  8. *
  9. * MESSAGE HANDLING SERVICES
  10. *
  11. * File : OS_MSG.C
  12. * By : JJL
  13. * Version : V3.04.04
  14. *
  15. * LICENSING TERMS:
  16. * ---------------
  17. * uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
  18. * for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
  19. * product then, you need to contact Micrium to properly license uC/OS-III for its use in your
  20. * application/product. We provide ALL the source code for your convenience and to help you
  21. * experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
  22. * it commercially without paying a licensing fee.
  23. *
  24. * Knowledge of the source code may NOT be used to develop a similar product.
  25. *
  26. * Please help us continue to provide the embedded community with the finest software available.
  27. * Your honesty is greatly appreciated.
  28. *
  29. * You can find our product's user manual, API reference, release notes and
  30. * more information at https://doc.micrium.com.
  31. * You can contact us at www.micrium.com.
  32. ************************************************************************************************************************
  33. */
  34. #define MICRIUM_SOURCE
  35. #include "os.h"
  36. #ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
  37. const CPU_CHAR *os_msg__c = "$Id: $";
  38. #endif
  39. #if OS_MSG_EN > 0u
  40. /*
  41. ************************************************************************************************************************
  42. * INITIALIZE THE POOL OF 'OS_MSG'
  43. *
  44. * Description: This function is called by OSInit() to initialize the free list of OS_MSGs.
  45. *
  46. * Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
  47. *
  48. * OS_ERR_MSG_POOL_NULL_PTR
  49. * OS_ERR_MSG_POOL_EMPTY
  50. * OS_ERR_NONE
  51. *
  52. * Returns : none
  53. *
  54. * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
  55. ************************************************************************************************************************
  56. */
  57. void OS_MsgPoolInit (OS_ERR *p_err)
  58. {
  59. OS_MSG *p_msg1;
  60. OS_MSG *p_msg2;
  61. OS_MSG_QTY i;
  62. OS_MSG_QTY loops;
  63. #ifdef OS_SAFETY_CRITICAL
  64. if (p_err == (OS_ERR *)0) {
  65. OS_SAFETY_CRITICAL_EXCEPTION();
  66. return;
  67. }
  68. #endif
  69. #if OS_CFG_ARG_CHK_EN > 0u
  70. if (OSCfg_MsgPoolBasePtr == (OS_MSG *)0) {
  71. *p_err = OS_ERR_MSG_POOL_NULL_PTR;
  72. return;
  73. }
  74. if (OSCfg_MsgPoolSize == (OS_MSG_QTY)0) {
  75. *p_err = OS_ERR_MSG_POOL_EMPTY;
  76. return;
  77. }
  78. #endif
  79. p_msg1 = OSCfg_MsgPoolBasePtr;
  80. p_msg2 = OSCfg_MsgPoolBasePtr;
  81. p_msg2++;
  82. loops = OSCfg_MsgPoolSize - 1u;
  83. for (i = 0u; i < loops; i++) { /* Init. list of free OS_MSGs */
  84. p_msg1->NextPtr = p_msg2;
  85. p_msg1->MsgPtr = (void *)0;
  86. p_msg1->MsgSize = (OS_MSG_SIZE)0u;
  87. p_msg1->MsgTS = (CPU_TS )0u;
  88. p_msg1++;
  89. p_msg2++;
  90. }
  91. p_msg1->NextPtr = (OS_MSG *)0; /* Last OS_MSG */
  92. p_msg1->MsgPtr = (void *)0;
  93. p_msg1->MsgSize = (OS_MSG_SIZE)0u;
  94. p_msg1->MsgTS = (CPU_TS )0u;
  95. OSMsgPool.NextPtr = OSCfg_MsgPoolBasePtr;
  96. OSMsgPool.NbrFree = OSCfg_MsgPoolSize;
  97. OSMsgPool.NbrUsed = (OS_MSG_QTY)0;
  98. #if OS_CFG_DBG_EN > 0u
  99. OSMsgPool.NbrUsedMax = (OS_MSG_QTY)0;
  100. #endif
  101. *p_err = OS_ERR_NONE;
  102. }
  103. /*
  104. ************************************************************************************************************************
  105. * RELEASE ALL MESSAGE IN MESSAGE QUEUE
  106. *
  107. * Description: This function returns all the messages in a message queue to the free list.
  108. *
  109. * Arguments : p_msg_q is a pointer to the OS_MSG_Q structure containing messages to free.
  110. * -------
  111. *
  112. * Returns : the number of OS_MSGs returned to the free list
  113. *
  114. * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
  115. ************************************************************************************************************************
  116. */
  117. OS_MSG_QTY OS_MsgQFreeAll (OS_MSG_Q *p_msg_q)
  118. {
  119. OS_MSG *p_msg;
  120. OS_MSG_QTY qty;
  121. qty = p_msg_q->NbrEntries; /* Get the number of OS_MSGs being freed */
  122. if (p_msg_q->NbrEntries > (OS_MSG_QTY)0) {
  123. p_msg = p_msg_q->InPtr; /* Point to end of message chain */
  124. p_msg->NextPtr = OSMsgPool.NextPtr;
  125. OSMsgPool.NextPtr = p_msg_q->OutPtr; /* Point to beginning of message chain */
  126. OSMsgPool.NbrUsed -= p_msg_q->NbrEntries; /* Update statistics for free list of messages */
  127. OSMsgPool.NbrFree += p_msg_q->NbrEntries;
  128. p_msg_q->NbrEntries = (OS_MSG_QTY)0; /* Flush the message queue */
  129. #if OS_CFG_DBG_EN > 0u
  130. p_msg_q->NbrEntriesMax = (OS_MSG_QTY)0;
  131. #endif
  132. p_msg_q->InPtr = (OS_MSG *)0;
  133. p_msg_q->OutPtr = (OS_MSG *)0;
  134. }
  135. return (qty);
  136. }
  137. /*
  138. ************************************************************************************************************************
  139. * INITIALIZE A MESSAGE QUEUE
  140. *
  141. * Description: This function is called to initialize a message queue
  142. *
  143. * Arguments : p_msg_q is a pointer to the message queue to initialize
  144. * -------
  145. *
  146. * max is the maximum number of entries that a message queue can have.
  147. *
  148. * Returns : none
  149. *
  150. * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
  151. ************************************************************************************************************************
  152. */
  153. void OS_MsgQInit (OS_MSG_Q *p_msg_q,
  154. OS_MSG_QTY size)
  155. {
  156. p_msg_q->NbrEntriesSize = (OS_MSG_QTY)size;
  157. p_msg_q->NbrEntries = (OS_MSG_QTY)0;
  158. #if OS_CFG_DBG_EN > 0u
  159. p_msg_q->NbrEntriesMax = (OS_MSG_QTY)0;
  160. #endif
  161. p_msg_q->InPtr = (OS_MSG *)0;
  162. p_msg_q->OutPtr = (OS_MSG *)0;
  163. }
  164. /*
  165. ************************************************************************************************************************
  166. * RETRIEVE MESSAGE FROM MESSAGE QUEUE
  167. *
  168. * Description: This function retrieves a message from a message queue
  169. *
  170. * Arguments : p_msg_q is a pointer to the message queue where we want to extract the message from
  171. * -------
  172. *
  173. * p_msg_size is a pointer to where the size (in bytes) of the message will be placed
  174. *
  175. * p_ts is a pointer to where the time stamp will be placed
  176. *
  177. * p_err is a pointer to an error code that will be returned from this call.
  178. *
  179. * OS_ERR_Q_EMPTY
  180. * OS_ERR_NONE
  181. *
  182. * Returns : The message (a pointer)
  183. *
  184. * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
  185. ************************************************************************************************************************
  186. */
  187. void *OS_MsgQGet (OS_MSG_Q *p_msg_q,
  188. OS_MSG_SIZE *p_msg_size,
  189. CPU_TS *p_ts,
  190. OS_ERR *p_err)
  191. {
  192. OS_MSG *p_msg;
  193. void *p_void;
  194. #ifdef OS_SAFETY_CRITICAL
  195. if (p_err == (OS_ERR *)0) {
  196. OS_SAFETY_CRITICAL_EXCEPTION();
  197. return ((void *)0);
  198. }
  199. #endif
  200. if (p_msg_q->NbrEntries == (OS_MSG_QTY)0) { /* Is the queue empty? */
  201. *p_msg_size = (OS_MSG_SIZE)0; /* Yes */
  202. if (p_ts != (CPU_TS *)0) {
  203. *p_ts = (CPU_TS )0;
  204. }
  205. *p_err = OS_ERR_Q_EMPTY;
  206. return ((void *)0);
  207. }
  208. p_msg = p_msg_q->OutPtr; /* No, get the next message to extract from the queue */
  209. p_void = p_msg->MsgPtr;
  210. *p_msg_size = p_msg->MsgSize;
  211. if (p_ts != (CPU_TS *)0) {
  212. *p_ts = p_msg->MsgTS;
  213. }
  214. p_msg_q->OutPtr = p_msg->NextPtr; /* Point to next message to extract */
  215. if (p_msg_q->OutPtr == (OS_MSG *)0) { /* Are there any more messages in the queue? */
  216. p_msg_q->InPtr = (OS_MSG *)0; /* No */
  217. p_msg_q->NbrEntries = (OS_MSG_QTY)0;
  218. } else {
  219. p_msg_q->NbrEntries--; /* Yes, One less message in the queue */
  220. }
  221. p_msg->NextPtr = OSMsgPool.NextPtr; /* Return message control block to free list */
  222. OSMsgPool.NextPtr = p_msg;
  223. OSMsgPool.NbrFree++;
  224. OSMsgPool.NbrUsed--;
  225. *p_err = OS_ERR_NONE;
  226. return (p_void);
  227. }
  228. /*
  229. ************************************************************************************************************************
  230. * DEPOSIT MESSAGE IN MESSAGE QUEUE
  231. *
  232. * Description: This function places a message in a message queue
  233. *
  234. * Arguments : p_msg_q is a pointer to the OS_TCB of the task to post the message to
  235. * -------
  236. *
  237. * p_void is a pointer to the message to send.
  238. *
  239. * msg_size is the size of the message (in bytes)
  240. *
  241. * opt specifies whether the message will be posted in FIFO or LIFO order
  242. *
  243. * OS_OPT_POST_FIFO
  244. * OS_OPT_POST_LIFO
  245. *
  246. * ts is a timestamp as to when the message was posted
  247. *
  248. * p_err is a pointer to a variable that will contain an error code returned by this function.
  249. *
  250. * OS_ERR_Q_MAX if the queue is full
  251. * OS_ERR_MSG_POOL_EMPTY if we no longer have any OS_MSG to use
  252. * OS_ERR_NONE the message was deposited in the queue
  253. *
  254. * Returns : none
  255. *
  256. * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
  257. ************************************************************************************************************************
  258. */
  259. void OS_MsgQPut (OS_MSG_Q *p_msg_q,
  260. void *p_void,
  261. OS_MSG_SIZE msg_size,
  262. OS_OPT opt,
  263. CPU_TS ts,
  264. OS_ERR *p_err)
  265. {
  266. OS_MSG *p_msg;
  267. OS_MSG *p_msg_in;
  268. #ifdef OS_SAFETY_CRITICAL
  269. if (p_err == (OS_ERR *)0) {
  270. OS_SAFETY_CRITICAL_EXCEPTION();
  271. return;
  272. }
  273. #endif
  274. if (p_msg_q->NbrEntries >= p_msg_q->NbrEntriesSize) {
  275. *p_err = OS_ERR_Q_MAX; /* Message queue cannot accept any more messages */
  276. return;
  277. }
  278. if (OSMsgPool.NbrFree == (OS_MSG_QTY)0) {
  279. *p_err = OS_ERR_MSG_POOL_EMPTY; /* No more OS_MSG to use */
  280. return;
  281. }
  282. p_msg = OSMsgPool.NextPtr; /* Remove message control block from free list */
  283. OSMsgPool.NextPtr = p_msg->NextPtr;
  284. OSMsgPool.NbrFree--;
  285. OSMsgPool.NbrUsed++;
  286. #if OS_CFG_DBG_EN > 0u
  287. if (OSMsgPool.NbrUsedMax < OSMsgPool.NbrUsed) {
  288. OSMsgPool.NbrUsedMax = OSMsgPool.NbrUsed;
  289. }
  290. #endif
  291. if (p_msg_q->NbrEntries == (OS_MSG_QTY)0) { /* Is this first message placed in the queue? */
  292. p_msg_q->InPtr = p_msg; /* Yes */
  293. p_msg_q->OutPtr = p_msg;
  294. p_msg_q->NbrEntries = (OS_MSG_QTY)1;
  295. p_msg->NextPtr = (OS_MSG *)0;
  296. } else { /* No */
  297. if ((opt & OS_OPT_POST_LIFO) == OS_OPT_POST_FIFO) { /* Is it FIFO or LIFO? */
  298. p_msg_in = p_msg_q->InPtr; /* FIFO, add to the head */
  299. p_msg_in->NextPtr = p_msg;
  300. p_msg_q->InPtr = p_msg;
  301. p_msg->NextPtr = (OS_MSG *)0;
  302. } else {
  303. p_msg->NextPtr = p_msg_q->OutPtr; /* LIFO, add to the tail */
  304. p_msg_q->OutPtr = p_msg;
  305. }
  306. p_msg_q->NbrEntries++;
  307. }
  308. #if OS_CFG_DBG_EN > 0u
  309. if (p_msg_q->NbrEntriesMax < p_msg_q->NbrEntries) {
  310. p_msg_q->NbrEntriesMax = p_msg_q->NbrEntries;
  311. }
  312. #endif
  313. p_msg->MsgPtr = p_void; /* Deposit message in the message queue entry */
  314. p_msg->MsgSize = msg_size;
  315. p_msg->MsgTS = ts;
  316. *p_err = OS_ERR_NONE;
  317. }
  318. #endif