LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
os_msg.c
Go to the documentation of this file.
1 /*
2 ************************************************************************************************************************
3 * uC/OS-III
4 * The Real-Time Kernel
5 *
6 * (c) Copyright 2009-2012; 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.03.00
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 contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
30 ************************************************************************************************************************
31 */
32 
33 #define MICRIUM_SOURCE
34 #include <os.h>
35 
36 #ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
37 const CPU_CHAR *os_msg__c = "$Id: $";
38 #endif
39 
40 
41 #if OS_MSG_EN > 0u
42 /*$PAGE*/
43 /*
44 ************************************************************************************************************************
45 * CREATE A LINKED LIST OF 'OS_MSG'
46 *
47 * Description: This function is called to create a singly linked list of OS_MSGs which is used as a pool of available
48 * OS_MSGs to be used for sending messages.
49 *
50 * Arguments : p_msg is a pointer to the base address of an array of OS_MSG and should be declared as follows:
51 * -----
52 * OS_MSG MyMsgTbl[size];
53 *
54 * size is the size of the above array
55 *
56 * Returns : none
57 *
58 * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
59 ************************************************************************************************************************
60 */
61 
62 void OS_MsgPoolCreate (OS_MSG *p_msg,
63  OS_MSG_QTY size)
64 {
65  OS_MSG *p_msg1;
66  OS_MSG *p_msg2;
67  OS_MSG_QTY i;
68  OS_MSG_QTY loops;
69 
70 
71 
72  p_msg1 = p_msg;
73  p_msg2 = p_msg;
74  p_msg2++;
75  loops = size - 1u;
76  for (i = 0u; i < loops; i++) { /* Init. list of free OS_MSGs */
77  p_msg1->NextPtr = p_msg2;
78  p_msg1->MsgPtr = (void *)0;
79  p_msg1->MsgSize = (OS_MSG_SIZE)0u;
80  p_msg1->MsgTS = (CPU_TS )0u;
81  p_msg1++;
82  p_msg2++;
83  }
84  p_msg1->NextPtr = (OS_MSG *)0; /* Last OS_MSG */
85  p_msg1->MsgPtr = (void *)0;
86  p_msg1->MsgSize = (OS_MSG_SIZE)0u;
87  p_msg1->MsgTS = (CPU_TS )0u;
88 }
89 
90 /*$PAGE*/
91 /*
92 ************************************************************************************************************************
93 * INITIALIZE THE POOL OF 'OS_MSG'
94 *
95 * Description: This function is called by OSInit() to initialize the free list of OS_MSGs.
96 *
97 * Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
98 *
99 * OS_ERR_MSG_POOL_NULL_PTR
100 * OS_ERR_MSG_POOL_EMPTY
101 * OS_ERR_NONE
102 *
103 * Returns : none
104 *
105 * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
106 ************************************************************************************************************************
107 */
108 
109 void OS_MsgPoolInit (OS_ERR *p_err)
110 {
111 #ifdef OS_SAFETY_CRITICAL
112  if (p_err == (OS_ERR *)0) {
113  OS_SAFETY_CRITICAL_EXCEPTION();
114  return;
115  }
116 #endif
117 
118 #if OS_CFG_ARG_CHK_EN > 0u
119  if (OSCfg_MsgPoolBasePtr == (OS_MSG *)0) {
120  *p_err = OS_ERR_MSG_POOL_NULL_PTR;
121  return;
122  }
123  if (OSCfg_MsgPoolSize == (OS_MSG_QTY)0) {
124  *p_err = OS_ERR_MSG_POOL_EMPTY;
125  return;
126  }
127 #endif
128 
131  OSMsgPool.NextPtr = OSCfg_MsgPoolBasePtr;
132  OSMsgPool.NbrFree = OSCfg_MsgPoolSize;
133  OSMsgPool.NbrUsed = (OS_MSG_QTY)0;
134  OSMsgPool.NbrUsedMax = (OS_MSG_QTY)0;
135  *p_err = OS_ERR_NONE;
136 }
137 
138 /*$PAGE*/
139 /*
140 ************************************************************************************************************************
141 * RELEASE ALL MESSAGE IN MESSAGE QUEUE
142 *
143 * Description: This function returns all the messages in a message queue to the free list.
144 *
145 * Arguments : p_msg_q is a pointer to the OS_MSG_Q structure containing messages to free.
146 * -------
147 *
148 * Returns : the number of OS_MSGs returned to the free list
149 *
150 * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
151 ************************************************************************************************************************
152 */
153 
154 OS_MSG_QTY OS_MsgQFreeAll (OS_MSG_Q *p_msg_q)
155 {
156  OS_MSG *p_msg;
157  OS_MSG_QTY qty;
158 
159 
160 
161  qty = p_msg_q->NbrEntries; /* Get the number of OS_MSGs being freed */
162  if (p_msg_q->NbrEntries > (OS_MSG_QTY)0) {
163  p_msg = p_msg_q->InPtr; /* Point to end of message chain */
164  p_msg->NextPtr = OSMsgPool.NextPtr;
165  OSMsgPool.NextPtr = p_msg_q->OutPtr; /* Point to beginning of message chain */
166  OSMsgPool.NbrUsed -= p_msg_q->NbrEntries; /* Update statistics for free list of messages */
167  OSMsgPool.NbrFree += p_msg_q->NbrEntries;
168  p_msg_q->NbrEntries = (OS_MSG_QTY)0; /* Flush the message queue */
169  p_msg_q->NbrEntriesMax = (OS_MSG_QTY)0;
170  p_msg_q->InPtr = (OS_MSG *)0;
171  p_msg_q->OutPtr = (OS_MSG *)0;
172  }
173  return (qty);
174 }
175 
176 /*$PAGE*/
177 /*
178 ************************************************************************************************************************
179 * INITIALIZE A MESSAGE QUEUE
180 *
181 * Description: This function is called to initialize a message queue
182 *
183 * Arguments : p_msg_q is a pointer to the message queue to initialize
184 * -------
185 *
186 * max is the maximum number of entries that a message queue can have.
187 *
188 * Returns : none
189 *
190 * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
191 ************************************************************************************************************************
192 */
193 
194 void OS_MsgQInit (OS_MSG_Q *p_msg_q,
195  OS_MSG_QTY size)
196 {
197  p_msg_q->NbrEntriesSize = (OS_MSG_QTY)size;
198  p_msg_q->NbrEntries = (OS_MSG_QTY)0;
199  p_msg_q->NbrEntriesMax = (OS_MSG_QTY)0;
200  p_msg_q->InPtr = (OS_MSG *)0;
201  p_msg_q->OutPtr = (OS_MSG *)0;
202 }
203 
204 /*$PAGE*/
205 /*
206 ************************************************************************************************************************
207 * RETRIEVE MESSAGE FROM MESSAGE QUEUE
208 *
209 * Description: This function retrieves a message from a message queue
210 *
211 * Arguments : p_msg_q is a pointer to the message queue where we want to extract the message from
212 * -------
213 *
214 * p_msg_size is a pointer to where the size (in bytes) of the message will be placed
215 *
216 * p_ts is a pointer to where the time stamp will be placed
217 *
218 * p_err is a pointer to an error code that will be returned from this call.
219 *
220 * OS_ERR_Q_EMPTY
221 * OS_ERR_NONE
222 *
223 * Returns : The message (a pointer)
224 *
225 * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
226 ************************************************************************************************************************
227 */
228 
229 void *OS_MsgQGet (OS_MSG_Q *p_msg_q,
230  OS_MSG_SIZE *p_msg_size,
231  CPU_TS *p_ts,
232  OS_ERR *p_err)
233 {
234  OS_MSG *p_msg;
235  void *p_void;
236 
237 
238 
239 #ifdef OS_SAFETY_CRITICAL
240  if (p_err == (OS_ERR *)0) {
241  OS_SAFETY_CRITICAL_EXCEPTION();
242  return ((void *)0);
243  }
244 #endif
245 
246  if (p_msg_q->NbrEntries == (OS_MSG_QTY)0) {
247  *p_msg_size = (OS_MSG_SIZE)0;
248  if (p_ts != (CPU_TS *)0) {
249  *p_ts = (CPU_TS )0;
250  }
251  *p_err = OS_ERR_Q_EMPTY;
252  return ((void *)0);
253  }
254 
255  p_msg = p_msg_q->OutPtr;
256  p_void = p_msg->MsgPtr;
257  *p_msg_size = p_msg->MsgSize;
258  if (p_ts != (CPU_TS *)0) {
259  *p_ts = p_msg->MsgTS;
260  }
261  p_msg_q->OutPtr = p_msg->NextPtr;
262  if (p_msg_q->OutPtr == (OS_MSG *)0) {
263  p_msg_q->InPtr = (OS_MSG *)0;
264  p_msg_q->NbrEntries = (OS_MSG_QTY)0;
265  } else {
266  p_msg_q->NbrEntries--;
267  }
268  p_msg->NextPtr = OSMsgPool.NextPtr; /* Return message control block to free list */
269  OSMsgPool.NextPtr = p_msg;
270  OSMsgPool.NbrFree++;
271  OSMsgPool.NbrUsed--;
272  *p_err = OS_ERR_NONE;
273  return (p_void);
274 }
275 
276 /*$PAGE*/
277 /*
278 ************************************************************************************************************************
279 * DEPOSIT MESSAGE IN MESSAGE QUEUE
280 *
281 * Description: This function places a message in a message queue
282 *
283 * Arguments : p_msg_q is a pointer to the OS_TCB of the task to post the message to
284 * -------
285 *
286 * p_void is a pointer to the message to send.
287 *
288 * msg_size is the size of the message (in bytes)
289 *
290 * opt specifies whether the message will be posted in FIFO or LIFO order
291 *
292 * OS_OPT_POST_FIFO
293 * OS_OPT_POST_LIFO
294 *
295 * ts is a timestamp as to when the message was posted
296 *
297 * p_err is a pointer to a variable that will contain an error code returned by this function.
298 *
299 * OS_ERR_Q_MAX if the queue is full
300 * OS_ERR_MSG_POOL_EMPTY if we no longer have any OS_MSG to use
301 * OS_ERR_NONE the message was deposited in the queue
302 *
303 * Returns : none
304 *
305 * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
306 ************************************************************************************************************************
307 */
308 
309 void OS_MsgQPut (OS_MSG_Q *p_msg_q,
310  void *p_void,
311  OS_MSG_SIZE msg_size,
312  OS_OPT opt,
313  CPU_TS ts,
314  OS_ERR *p_err)
315 {
316  OS_MSG *p_msg;
317  OS_MSG *p_msg_in;
318 
319 
320 
321 #ifdef OS_SAFETY_CRITICAL
322  if (p_err == (OS_ERR *)0) {
323  OS_SAFETY_CRITICAL_EXCEPTION();
324  return;
325  }
326 #endif
327 
328  if (p_msg_q->NbrEntries >= p_msg_q->NbrEntriesSize) {
329  *p_err = OS_ERR_Q_MAX; /* Message queue cannot accept any more messages */
330  return;
331  }
332 
333  if (OSMsgPool.NbrFree == (OS_MSG_QTY)0) {
334  *p_err = OS_ERR_MSG_POOL_EMPTY; /* No more OS_MSG to use */
335  return;
336  }
337 
338  p_msg = OSMsgPool.NextPtr; /* Remove message control block from free list */
339  OSMsgPool.NextPtr = p_msg->NextPtr;
340  OSMsgPool.NbrFree--;
341  OSMsgPool.NbrUsed++;
342  if (OSMsgPool.NbrUsedMax < OSMsgPool.NbrUsed) {
343  OSMsgPool.NbrUsedMax = OSMsgPool.NbrUsed;
344  }
345  if (p_msg_q->NbrEntries == (OS_MSG_QTY)0) { /* Is this first message placed in the queue? */
346  p_msg_q->InPtr = p_msg; /* Yes */
347  p_msg_q->OutPtr = p_msg;
348  p_msg_q->NbrEntries = (OS_MSG_QTY)1;
349  } else {
350  if ((opt & OS_OPT_POST_LIFO) == OS_OPT_POST_FIFO) { /* Assume FIFO if not LIFO */
351  p_msg_in = p_msg_q->InPtr; /* FIFO */
352  p_msg_in->NextPtr = p_msg;
353  p_msg->NextPtr = (OS_MSG *)0;
354  p_msg_q->InPtr = p_msg;
355  } else {
356  p_msg->NextPtr = p_msg_q->OutPtr; /* LIFO */
357  p_msg_q->OutPtr = p_msg;
358  }
359  p_msg_q->NbrEntries++;
360  }
361  if (p_msg_q->NbrEntriesMax < p_msg_q->NbrEntries) {
362  p_msg_q->NbrEntriesMax = p_msg_q->NbrEntries;
363  }
364  p_msg->MsgPtr = p_void; /* Deposit message in the message queue entry */
365  p_msg->MsgSize = msg_size;
366  p_msg->MsgTS = ts;
367  *p_err = OS_ERR_NONE;
368 }
369 #endif