| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

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
129 OS_MsgPoolCreate(OSCfg_MsgPoolBasePtr,
130 OSCfg_MsgPoolSize);
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