forked from weston-embedded/uC-OS3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathos_msg.c
349 lines (306 loc) · 12.9 KB
/
os_msg.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
/*
*********************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* Copyright 2009-2021 Silicon Laboratories Inc. www.silabs.com
*
* SPDX-License-Identifier: APACHE-2.0
*
* This software is subject to an open source license and is distributed by
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
*
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MESSAGE HANDLING SERVICES
*
* File : os_msg.c
* Version : V3.08.01
*********************************************************************************************************
*/
#define MICRIUM_SOURCE
#include "os.h"
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_msg__c = "$Id: $";
#endif
#if (OS_MSG_EN > 0u)
/*
************************************************************************************************************************
* INITIALIZE THE POOL OF 'OS_MSG'
*
* Description: This function is called by OSInit() to initialize the free list of OS_MSGs.
*
* Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_MSG_POOL_NULL_PTR
* OS_ERR_MSG_POOL_EMPTY
* OS_ERR_NONE
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_MsgPoolInit (OS_ERR *p_err)
{
OS_MSG *p_msg1;
OS_MSG *p_msg2;
OS_MSG_QTY i;
OS_MSG_QTY loops;
#if (OS_CFG_ARG_CHK_EN > 0u)
if (OSCfg_MsgPoolBasePtr == (OS_MSG *)0) {
*p_err = OS_ERR_MSG_POOL_NULL_PTR;
return;
}
if (OSCfg_MsgPoolSize == 0u) {
*p_err = OS_ERR_MSG_POOL_EMPTY;
return;
}
#endif
p_msg1 = OSCfg_MsgPoolBasePtr;
p_msg2 = OSCfg_MsgPoolBasePtr;
p_msg2++;
loops = OSCfg_MsgPoolSize - 1u;
for (i = 0u; i < loops; i++) { /* Init. list of free OS_MSGs */
p_msg1->NextPtr = p_msg2;
p_msg1->MsgPtr = (void *)0;
p_msg1->MsgSize = 0u;
#if (OS_CFG_TS_EN > 0u)
p_msg1->MsgTS = 0u;
#endif
p_msg1++;
p_msg2++;
}
p_msg1->NextPtr = (OS_MSG *)0; /* Last OS_MSG */
p_msg1->MsgPtr = (void *)0;
p_msg1->MsgSize = 0u;
#if (OS_CFG_TS_EN > 0u)
p_msg1->MsgTS = 0u;
#endif
OSMsgPool.NextPtr = OSCfg_MsgPoolBasePtr;
OSMsgPool.NbrFree = OSCfg_MsgPoolSize;
OSMsgPool.NbrUsed = 0u;
#if (OS_CFG_DBG_EN > 0u)
OSMsgPool.NbrUsedMax = 0u;
#endif
*p_err = OS_ERR_NONE;
}
/*
************************************************************************************************************************
* RELEASE ALL MESSAGE IN MESSAGE QUEUE
*
* Description: This function returns all the messages in a message queue to the free list.
*
* Arguments : p_msg_q is a pointer to the OS_MSG_Q structure containing messages to free.
* -------
*
* Returns : the number of OS_MSGs returned to the free list
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
OS_MSG_QTY OS_MsgQFreeAll (OS_MSG_Q *p_msg_q)
{
OS_MSG *p_msg;
OS_MSG_QTY qty;
qty = p_msg_q->NbrEntries; /* Get the number of OS_MSGs being freed */
if (p_msg_q->NbrEntries > 0u) {
p_msg = p_msg_q->InPtr; /* Point to end of message chain */
p_msg->NextPtr = OSMsgPool.NextPtr;
OSMsgPool.NextPtr = p_msg_q->OutPtr; /* Point to beginning of message chain */
OSMsgPool.NbrUsed -= p_msg_q->NbrEntries; /* Update statistics for free list of messages */
OSMsgPool.NbrFree += p_msg_q->NbrEntries;
p_msg_q->NbrEntries = 0u; /* Flush the message queue */
#if (OS_CFG_DBG_EN > 0u)
p_msg_q->NbrEntriesMax = 0u;
#endif
p_msg_q->InPtr = (OS_MSG *)0;
p_msg_q->OutPtr = (OS_MSG *)0;
}
return (qty);
}
/*
************************************************************************************************************************
* INITIALIZE A MESSAGE QUEUE
*
* Description: This function is called to initialize a message queue
*
* Arguments : p_msg_q is a pointer to the message queue to initialize
* -------
*
* size is the maximum number of entries that a message queue can have.
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_MsgQInit (OS_MSG_Q *p_msg_q,
OS_MSG_QTY size)
{
p_msg_q->NbrEntriesSize = size;
p_msg_q->NbrEntries = 0u;
#if (OS_CFG_DBG_EN > 0u)
p_msg_q->NbrEntriesMax = 0u;
#endif
p_msg_q->InPtr = (OS_MSG *)0;
p_msg_q->OutPtr = (OS_MSG *)0;
}
/*
************************************************************************************************************************
* RETRIEVE MESSAGE FROM MESSAGE QUEUE
*
* Description: This function retrieves a message from a message queue
*
* Arguments : p_msg_q is a pointer to the message queue where we want to extract the message from
* -------
*
* p_msg_size is a pointer to where the size (in bytes) of the message will be placed
*
* p_ts is a pointer to where the time stamp will be placed
*
* p_err is a pointer to an error code that will be returned from this call.
*
* OS_ERR_Q_EMPTY
* OS_ERR_NONE
*
* Returns : The message (a pointer)
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void *OS_MsgQGet (OS_MSG_Q *p_msg_q,
OS_MSG_SIZE *p_msg_size,
CPU_TS *p_ts,
OS_ERR *p_err)
{
OS_MSG *p_msg;
void *p_void;
#if (OS_CFG_TS_EN == 0u)
(void)p_ts; /* Prevent compiler warning for not using 'ts' */
#endif
if (p_msg_q->NbrEntries == 0u) { /* Is the queue empty? */
*p_msg_size = 0u; /* Yes */
#if (OS_CFG_TS_EN > 0u)
if (p_ts != (CPU_TS *)0) {
*p_ts = 0u;
}
#endif
*p_err = OS_ERR_Q_EMPTY;
return ((void *)0);
}
p_msg = p_msg_q->OutPtr; /* No, get the next message to extract from the queue */
p_void = p_msg->MsgPtr;
*p_msg_size = p_msg->MsgSize;
#if (OS_CFG_TS_EN > 0u)
if (p_ts != (CPU_TS *)0) {
*p_ts = p_msg->MsgTS;
}
#endif
p_msg_q->OutPtr = p_msg->NextPtr; /* Point to next message to extract */
if (p_msg_q->OutPtr == (OS_MSG *)0) { /* Are there any more messages in the queue? */
p_msg_q->InPtr = (OS_MSG *)0; /* No */
p_msg_q->NbrEntries = 0u;
} else {
p_msg_q->NbrEntries--; /* Yes, One less message in the queue */
}
p_msg->NextPtr = OSMsgPool.NextPtr; /* Return message control block to free list */
OSMsgPool.NextPtr = p_msg;
OSMsgPool.NbrFree++;
OSMsgPool.NbrUsed--;
*p_err = OS_ERR_NONE;
return (p_void);
}
/*
************************************************************************************************************************
* DEPOSIT MESSAGE IN MESSAGE QUEUE
*
* Description: This function places a message in a message queue
*
* Arguments : p_msg_q is a pointer to the OS_TCB of the task to post the message to
* -------
*
* p_void is a pointer to the message to send.
*
* msg_size is the size of the message (in bytes)
*
* opt specifies whether the message will be posted in FIFO or LIFO order
*
* OS_OPT_POST_FIFO
* OS_OPT_POST_LIFO
*
* ts is a timestamp as to when the message was posted
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_Q_MAX if the queue is full
* OS_ERR_MSG_POOL_EMPTY if we no longer have any OS_MSG to use
* OS_ERR_NONE the message was deposited in the queue
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_MsgQPut (OS_MSG_Q *p_msg_q,
void *p_void,
OS_MSG_SIZE msg_size,
OS_OPT opt,
CPU_TS ts,
OS_ERR *p_err)
{
OS_MSG *p_msg;
OS_MSG *p_msg_in;
#if (OS_CFG_TS_EN == 0u)
(void)ts; /* Prevent compiler warning for not using 'ts' */
#endif
if (p_msg_q->NbrEntries >= p_msg_q->NbrEntriesSize) {
*p_err = OS_ERR_Q_MAX; /* Message queue cannot accept any more messages */
return;
}
if (OSMsgPool.NbrFree == 0u) {
*p_err = OS_ERR_MSG_POOL_EMPTY; /* No more OS_MSG to use */
return;
}
p_msg = OSMsgPool.NextPtr; /* Remove message control block from free list */
OSMsgPool.NextPtr = p_msg->NextPtr;
OSMsgPool.NbrFree--;
OSMsgPool.NbrUsed++;
#if (OS_CFG_DBG_EN > 0u)
if (OSMsgPool.NbrUsedMax < OSMsgPool.NbrUsed) {
OSMsgPool.NbrUsedMax = OSMsgPool.NbrUsed;
}
#endif
if (p_msg_q->NbrEntries == 0u) { /* Is this first message placed in the queue? */
p_msg_q->InPtr = p_msg; /* Yes */
p_msg_q->OutPtr = p_msg;
p_msg_q->NbrEntries = 1u;
p_msg->NextPtr = (OS_MSG *)0;
} else { /* No */
if ((opt & OS_OPT_POST_LIFO) == OS_OPT_POST_FIFO) { /* Is it FIFO or LIFO? */
p_msg_in = p_msg_q->InPtr; /* FIFO, add to the head */
p_msg_in->NextPtr = p_msg;
p_msg_q->InPtr = p_msg;
p_msg->NextPtr = (OS_MSG *)0;
} else {
p_msg->NextPtr = p_msg_q->OutPtr; /* LIFO, add to the tail */
p_msg_q->OutPtr = p_msg;
}
p_msg_q->NbrEntries++;
}
#if (OS_CFG_DBG_EN > 0u)
if (p_msg_q->NbrEntriesMax < p_msg_q->NbrEntries) {
p_msg_q->NbrEntriesMax = p_msg_q->NbrEntries;
}
#endif
p_msg->MsgPtr = p_void; /* Deposit message in the message queue entry */
p_msg->MsgSize = msg_size;
#if (OS_CFG_TS_EN > 0u)
p_msg->MsgTS = ts;
#endif
*p_err = OS_ERR_NONE;
}
#endif