📄 os_q.lst
字号:
215 1 OS_EVENT *pevent_return;
216 1 OS_Q *pq;
217 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
220 1
221 1
222 1
223 1 #if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return (pevent);
}
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
*perr = OS_ERR_PEVENT_NULL;
return (pevent);
}
#endif
232 1 if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
233 2 *perr = OS_ERR_EVENT_TYPE;
234 2 return (pevent);
235 2 }
236 1 if (OSIntNesting > 0) { /* See if called from ISR ... */
237 2 *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
238 2 return (pevent);
239 2 }
240 1 OS_ENTER_CRITICAL();
C51 COMPILER V7.50 OS_Q 12/14/2007 08:25:37 PAGE 5
241 1 if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on queue */
242 2 tasks_waiting = OS_TRUE; /* Yes */
243 2 } else {
244 2 tasks_waiting = OS_FALSE; /* No */
245 2 }
246 1 switch (opt) {
247 2 case OS_DEL_NO_PEND: /* Delete queue only if no task waiting */
248 2 if (tasks_waiting == OS_FALSE) {
249 3 #if OS_EVENT_NAME_SIZE > 1
250 3 pevent->OSEventName[0] = '?'; /* Unknown name */
251 3 pevent->OSEventName[1] = OS_ASCII_NUL;
252 3 #endif
253 3 pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */
254 3 pq->OSQPtr = OSQFreeList;
255 3 OSQFreeList = pq;
256 3 pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
257 3 pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
258 3 pevent->OSEventCnt = 0;
259 3 OSEventFreeList = pevent; /* Get next free event control block */
260 3 OS_EXIT_CRITICAL();
261 3 *perr = OS_ERR_NONE;
262 3 pevent_return = (OS_EVENT *)0; /* Queue has been deleted */
263 3 } else {
264 3 OS_EXIT_CRITICAL();
265 3 *perr = OS_ERR_TASK_WAITING;
266 3 pevent_return = pevent;
267 3 }
268 2 break;
269 2
270 2 case OS_DEL_ALWAYS: /* Always delete the queue */
271 2 while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for queue */
272 3 (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_OK);
273 3 }
274 2 #if OS_EVENT_NAME_SIZE > 1
275 2 pevent->OSEventName[0] = '?'; /* Unknown name */
276 2 pevent->OSEventName[1] = OS_ASCII_NUL;
277 2 #endif
278 2 pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */
279 2 pq->OSQPtr = OSQFreeList;
280 2 OSQFreeList = pq;
281 2 pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
282 2 pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
283 2 pevent->OSEventCnt = 0;
284 2 OSEventFreeList = pevent; /* Get next free event control block */
285 2 OS_EXIT_CRITICAL();
286 2 if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */
287 3 OS_Sched(); /* Find highest priority task ready to run */
288 3 }
289 2 *perr = OS_ERR_NONE;
290 2 pevent_return = (OS_EVENT *)0; /* Queue has been deleted */
291 2 break;
292 2
293 2 default:
294 2 OS_EXIT_CRITICAL();
295 2 *perr = OS_ERR_INVALID_OPT;
296 2 pevent_return = pevent;
297 2 break;
298 2 }
299 1 return (pevent_return);
300 1 }
301 #endif
302
C51 COMPILER V7.50 OS_Q 12/14/2007 08:25:37 PAGE 6
303 /*$PAGE*/
304 /*
305 *********************************************************************************************************
306 * FLUSH QUEUE
307 *
308 * Description : This function is used to flush the contents of the message queue.
309 *
310 * Arguments : none
311 *
312 * Returns : OS_ERR_NONE upon success
313 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue
314 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
315 *
316 * WARNING : You should use this function with great care because, when to flush the queue, you LOOSE
317 * the references to what the queue entries are pointing to and thus, you could cause
318 * 'memory leaks'. In other words, the data you are pointing to that's being referenced
319 * by the queue entries should, most likely, need to be de-allocated (i.e. freed).
320 *********************************************************************************************************
321 */
322
323 #if OS_Q_FLUSH_EN > 0
324 INT8U OSQFlush (OS_EVENT *pevent) reentrant
325 {
326 1 OS_Q *pq;
327 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
330 1
331 1
332 1
333 1 #if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
return (OS_ERR_EVENT_TYPE);
}
#endif
341 1 OS_ENTER_CRITICAL();
342 1 pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue storage structure */
343 1 pq->OSQIn = pq->OSQStart;
344 1 pq->OSQOut = pq->OSQStart;
345 1 pq->OSQEntries = 0;
346 1 OS_EXIT_CRITICAL();
347 1 return (OS_ERR_NONE);
348 1 }
349 #endif
350
351 /*$PAGE*/
352 /*
353 *********************************************************************************************************
354 * PEND ON A QUEUE FOR A MESSAGE
355 *
356 * Description: This function waits for a message to be sent to a queue
357 *
358 * Arguments : pevent is a pointer to the event control block associated with the desired queue
359 *
360 * timeout is an optional timeout period (in clock ticks). If non-zero, your task will
361 * wait for a message to arrive at the queue up to the amount of time
362 * specified by this argument. If you specify 0, however, your task will wait
363 * forever at the specified queue or, until a message arrives.
364 *
C51 COMPILER V7.50 OS_Q 12/14/2007 08:25:37 PAGE 7
365 * perr is a pointer to where an error message will be deposited. Possible error
366 * messages are:
367 *
368 * OS_ERR_NONE The call was successful and your task received a
369 * message.
370 * OS_ERR_TIMEOUT A message was not received within the specified 'timeout'
-.
371 * OS_ERR_PEND_ABORT The wait on the queue was aborted.
372 * OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue
373 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
374 * OS_ERR_PEND_ISR If you called this function from an ISR and the result
375 * would lead to a suspension.
376 * OS_ERR_PEND_LOCKED If you called this function with the scheduler is locked
377 *
378 * Returns : != (void *)0 is a pointer to the message received
379 * == (void *)0 if you received a NULL pointer message or,
380 * if no message was received or,
381 * if 'pevent' is a NULL pointer or,
382 * if you didn't pass a pointer to a queue.
383 *
384 * Note(s) : As of V2.60, this function allows you to receive NULL pointer messages.
385 *********************************************************************************************************
386 */
387
388 void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr) reentrant
389 {
390 1 void *pmsg;
391 1 OS_Q *pq;
392 1 INT8U pend_stat;
393 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
396 1
397 1
398 1
399 1 #if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return ((void *)0);
}
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
*perr = OS_ERR_PEVENT_NULL;
return ((void *)0);
}
if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */
*perr = OS_ERR_EVENT_TYPE;
return ((void *)0);
}
#endif
412 1 if (OSIntNesting > 0) { /* See if called from ISR ... */
413 2 *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
414 2 return ((void *)0);
415 2 }
416 1 if (OSLockNesting > 0) { /* See if called with scheduler locked ... */
417 2 *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */
418 2 return ((void *)0);
419 2 }
420 1 OS_ENTER_CRITICAL();
421 1 pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */
422 1 if (pq->OSQEntries > 0) { /* See if any messages in the queue */
423 2 pmsg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */
424 2 pq->OSQEntries--; /* Update the number of entries in the queue */
425 2 if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */
C51 COMPILER V7.50 OS_Q 12/14/2007 08:25:37 PAGE 8
426 3 pq->OSQOut = pq->OSQStart;
427 3 }
428 2 OS_EXIT_CRITICAL();
429 2 *perr = OS_ERR_NONE;
430 2 return (pmsg); /* Return message received */
431 2 }
432 1 OSTCBCur->OSTCBStat |= OS_STAT_Q; /* Task will have to pend for a message to be posted */
433 1 OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;
434 1 OSTCBCur->OSTCBDly = timeout; /* Load timeout into TCB */
435 1 OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -