📄 os_mbox.lst
字号:
128 * OS_ERR_INVALID_OPT An invalid option was specified
129 * OS_ERR_TASK_WAITING One or more tasks were waiting on the mailbox
130 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mailbox
131 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
132 *
133 * Returns : pevent upon error
134 * (OS_EVENT *)0 if the mailbox was successfully deleted.
135 *
136 * Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
137 * the mailbox MUST check the return code of OSMboxPend().
138 * 2) OSMboxAccept() callers will not know that the intended mailbox has been deleted!
139 * 3) This call can potentially disable interrupts for a long time. The interrupt disable
140 * time is directly proportional to the number of tasks waiting on the mailbox.
141 * 4) Because ALL tasks pending on the mailbox will be readied, you MUST be careful in
142 * applications where the mailbox is used for mutual exclusion because the resource(s)
143 * will no longer be guarded by the mailbox.
144 *********************************************************************************************************
145 */
146
147 #if OS_MBOX_DEL_EN > 0
148 OS_EVENT *OSMboxDel (OS_EVENT *pevent, INT8U opt, INT8U *err)
149 {
150 BOOLEAN tasks_waiting;
151 OS_EVENT *pevent_return;
152 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
155
156
157
158 #if OS_ARG_CHK_EN > 0
159 if (err == (INT8U *)0) { /* Validate 'err' */
160 return (pevent);
161 }
162 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
163 *err = OS_ERR_PEVENT_NULL;
164 return (pevent);
165 }
166 #endif
167 if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
168 *err = OS_ERR_EVENT_TYPE;
169 return (pevent);
170 }
171 if (OSIntNesting > 0) { /* See if called from ISR ... */
172 *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
173 return (pevent);
174 }
175 OS_ENTER_CRITICAL();
176 if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on mailbox */
177 tasks_waiting = TRUE; /* Yes */
178 } else {
179 tasks_waiting = FALSE; /* No */
180 }
181 switch (opt) {
182 case OS_DEL_NO_PEND: /* Delete mailbox only if no task waiting */
183 if (tasks_waiting == FALSE) {
C51 COMPILER V8.08 OS_MBOX 08/04/2008 21:49:52 PAGE 5
184 #if OS_EVENT_NAME_SIZE > 1
185 pevent->OSEventName[0] = '?'; /* Unknown name */
186 pevent->OSEventName[1] = OS_ASCII_NUL;
187 #endif
188 pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
189 pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
190 pevent->OSEventCnt = 0;
191 OSEventFreeList = pevent; /* Get next free event control block */
192 OS_EXIT_CRITICAL();
193 *err = OS_NO_ERR;
194 pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */
195 } else {
196 OS_EXIT_CRITICAL();
197 *err = OS_ERR_TASK_WAITING;
198 pevent_return = pevent;
199 }
200 break;
201
202 case OS_DEL_ALWAYS: /* Always delete the mailbox */
203 while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for mailbox */
204 (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX);
205 }
206 #if OS_EVENT_NAME_SIZE > 1
207 pevent->OSEventName[0] = '?'; /* Unknown name */
208 pevent->OSEventName[1] = OS_ASCII_NUL;
209 #endif
210 pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
211 pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
212 pevent->OSEventCnt = 0;
213 OSEventFreeList = pevent; /* Get next free event control block */
214 OS_EXIT_CRITICAL();
215 if (tasks_waiting == TRUE) { /* Reschedule only if task(s) were waiting */
216 OS_Sched(); /* Find highest priority task ready to run */
217 }
218 *err = OS_NO_ERR;
219 pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */
220 break;
221
222 default:
223 OS_EXIT_CRITICAL();
224 *err = OS_ERR_INVALID_OPT;
225 pevent_return = pevent;
226 break;
227 }
228 return (pevent_return);
229 }
230 #endif
231
232 /*$PAGE*/
233 /*
234 *********************************************************************************************************
235 * PEND ON MAILBOX FOR A MESSAGE
236 *
237 * Description: This function waits for a message to be sent to a mailbox
238 *
239 * Arguments : pevent is a pointer to the event control block associated with the desired mailbox
240 *
241 * timeout is an optional timeout period (in clock ticks). If non-zero, your task will
242 * wait for a message to arrive at the mailbox up to the amount of time
243 * specified by this argument. If you specify 0, however, your task will wait
244 * forever at the specified mailbox or, until a message arrives.
245 *
C51 COMPILER V8.08 OS_MBOX 08/04/2008 21:49:52 PAGE 6
246 * err is a pointer to where an error message will be deposited. Possible error
247 * messages are:
248 *
249 * OS_NO_ERR The call was successful and your task received a
250 * message.
251 * OS_TIMEOUT A message was not received within the specified timeout
252 * OS_ERR_EVENT_TYPE Invalid event type
253 * OS_ERR_PEND_ISR If you called this function from an ISR and the result
254 * would lead to a suspension.
255 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
256 *
257 * Returns : != (void *)0 is a pointer to the message received
258 * == (void *)0 if no message was received or,
259 * if 'pevent' is a NULL pointer or,
260 * if you didn't pass the proper pointer to the event control block.
261 *********************************************************************************************************
262 */
263
264 void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
265 {
266 void *msg;
267 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
270
271
272
273 #if OS_ARG_CHK_EN > 0
274 if (err == (INT8U *)0) { /* Validate 'err' */
275 return ((void *)0);
276 }
277 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
278 *err = OS_ERR_PEVENT_NULL;
279 return ((void *)0);
280 }
281 #endif
282 if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
283 *err = OS_ERR_EVENT_TYPE;
284 return ((void *)0);
285 }
286 if (OSIntNesting > 0) { /* See if called from ISR ... */
287 *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
288 return ((void *)0);
289 }
290 OS_ENTER_CRITICAL();
291 msg = pevent->OSEventPtr;
292 if (msg != (void *)0) { /* See if there is already a message */
293 pevent->OSEventPtr = (void *)0; /* Clear the mailbox */
294 OS_EXIT_CRITICAL();
295 *err = OS_NO_ERR;
296 return (msg); /* Return the message received (or NULL) */
297 }
298 OSTCBCur->OSTCBStat |= OS_STAT_MBOX; /* Message not available, task will pend */
299 OSTCBCur->OSTCBPendTO = FALSE;
300 OSTCBCur->OSTCBDly = timeout; /* Load timeout in TCB */
301 OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
302 OS_EXIT_CRITICAL();
303 OS_Sched(); /* Find next highest priority task ready to run */
304 OS_ENTER_CRITICAL();
305 if (OSTCBCur->OSTCBPendTO == TRUE) { /* See if we were given the message */
306 OS_EventTO(pevent); /* Timed out, Make task ready */
307 OS_EXIT_CRITICAL();
C51 COMPILER V8.08 OS_MBOX 08/04/2008 21:49:52 PAGE 7
308 *err = OS_TIMEOUT; /* Indicate that a timeout occured */
309 return ((void *)0); /* Return a NULL message */
310 }
311 msg = OSTCBCur->OSTCBMsg;
312 OSTCBCur->OSTCBMsg = (void *)0; /* Yes, clear message received */
313 OSTCBCur->OSTCBStat = OS_STAT_RDY;
314 OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */
315 OS_EXIT_CRITICAL();
316 *err = OS_NO_ERR;
317 return (msg); /* Return the message received */
318 }
319 /*$PAGE*/
320 /*
321 *********************************************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -