📄 os_q.lst
字号:
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)
325 {
326 OS_Q *pq;
327 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
328 OS_CPU_SR cpu_sr = 0;
329 #endif
330
331
332
333 #if OS_ARG_CHK_EN > 0
334 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
335 return (OS_ERR_PEVENT_NULL);
336 }
337 if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
338 return (OS_ERR_EVENT_TYPE);
339 }
340 #endif
341 OS_ENTER_CRITICAL();
342 pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue storage structure */
343 pq->OSQIn = pq->OSQStart;
344 pq->OSQOut = pq->OSQStart;
345 pq->OSQEntries = 0;
346 OS_EXIT_CRITICAL();
347 return (OS_ERR_NONE);
348 }
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 *
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)
389 {
390 void *pmsg;
391 OS_Q *pq;
392 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
393 OS_CPU_SR cpu_sr = 0;
394 #endif
395
396
397
398 #if OS_ARG_CHK_EN > 0
399 if (perr == (INT8U *)0) { /* Validate 'perr' */
400 return ((void *)0);
401 }
402 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
403 *perr = OS_ERR_PEVENT_NULL;
404 return ((void *)0);
405 }
406 #endif
407 if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */
408 *perr = OS_ERR_EVENT_TYPE;
409 return ((void *)0);
410 }
411 if (OSIntNesting > 0) { /* See if called from ISR ... */
412 *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
413 return ((void *)0);
414 }
415 if (OSLockNesting > 0) { /* See if called with scheduler locked ... */
416 *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */
417 return ((void *)0);
418 }
419 OS_ENTER_CRITICAL();
420 pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */
421 if (pq->OSQEntries > 0) { /* See if any messages in the queue */
422 pmsg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */
423 pq->OSQEntries--; /* Update the number of entries in the queue */
424 if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */
425 pq->OSQOut = pq->OSQStart;
426 }
427 OS_EXIT_CRITICAL();
428 *perr = OS_ERR_NONE;
429 return (pmsg); /* Return message received */
430 }
431 OSTCBCur->OSTCBStat |= OS_STAT_Q; /* Task will have to pend for a message to be posted */
432 OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;
433 OSTCBCur->OSTCBDly = timeout; /* Load timeout into TCB */
434 OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
435 OS_EXIT_CRITICAL();
436 OS_Sched(); /* Find next highest priority task ready to run */
437 OS_ENTER_CRITICAL();
438 switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */
439 case OS_STAT_PEND_OK: /* Extract message from TCB (Put there by QPost) */
440 pmsg = OSTCBCur->OSTCBMsg;
441 *perr = OS_ERR_NONE;
442 break;
443
444 case OS_STAT_PEND_ABORT:
445 pmsg = (void *)0;
446 *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */
447 break;
448
449 case OS_STAT_PEND_TO:
450 default:
451 OS_EventTaskRemove(OSTCBCur, pevent);
452 pmsg = (void *)0;
453 *perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get event within TO */
454 break;
455 }
456 OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */
457 OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */
458 OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */
459 #if (OS_EVENT_MULTI_EN > 0)
460 OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0;
461 #endif
462 OSTCBCur->OSTCBMsg = (void *)0; /* Clear received message */
463 OS_EXIT_CRITICAL();
464 return (pmsg); /* Return received message */
465 }
466 /*$PAGE*/
467 /*
468 *********************************************************************************************************
469 * ABORT WAITING ON A MESSAGE QUEUE
470 *
471 * Description: This function aborts & readies any tasks currently waiting on a queue. This function
472 * should be used to fault-abort the wait on the queue, rather than to normally signal
473 * the queue via OSQPost(), OSQPostFront() or OSQPostOpt().
474 *
475 * Arguments : pevent is a pointer to the event control block associated with the desired queue.
476 *
477 * opt determines the type of ABORT performed:
478 * OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the
479 * queue
480 * OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the
481 * queue
482 *
483 * perr is a pointer to where an error message will be deposited. Possible error
484 * messages are:
485 *
486 * OS_ERR_NONE No tasks were waiting on the queue.
487 * OS_ERR_PEND_ABORT At least one task waiting on the queue was readied
488 * and informed of the aborted wait; check return value
489 * for the number of tasks whose wait on the queue
490 * was aborted.
491 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
492 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
493 *
494 * Returns : == 0 if no tasks were waiting on the queue, or upon error.
495 * > 0 if one or more tasks waiting on the queue are now readied and informed.
496 *********************************************************************************************************
497 */
498
499 #if OS_Q_PEND_ABORT_EN > 0
500 INT8U OSQPendAbort (OS_EVENT *pevent, INT8U opt, INT8U *perr)
501 {
502 INT8U nbr_tasks;
503 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
504 OS_CPU_SR cpu_sr = 0;
505 #endif
506
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -