📄 os_q.src
字号:
; * application MUST NOT call this function.
; *
; * Arguments : none
; *
; * Returns : none
; *********************************************************************************************************
; */
;
; void OSQInit (void) reentrant
; {
; INT16U i;
;
;
; for (i = 0; i < (OS_MAX_QS - 1); i++) { /* Init. list of free QUEUE control blocks */
; OSQTbl[i].OSQPtr = &OSQTbl[i+1];
; }
; OSQTbl[OS_MAX_QS - 1].OSQPtr = (OS_Q *)0;
; OSQFreeList = &OSQTbl[0];
; }
;
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * PEND ON A QUEUE FOR A MESSAGE
; *
; * Description: This function waits for a message to be sent to a queue
; *
; * Arguments : pevent is a pointer to the event control block associated with the desired queue
; *
; * timeout is an optional timeout period (in clock ticks). If non-zero, your task will
; * wait for a message to arrive at the queue up to the amount of time
; * specified by this argument. If you specify 0, however, your task will wait
; * forever at the specified queue or, until a message arrives.
; *
; * err is a pointer to where an error message will be deposited. Possible error
; * messages are:
; *
; * OS_NO_ERR The call was successful and your task received a message.
; * OS_TIMEOUT A message was not received within the specified timeout
; * OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue
; * OS_ERR_PEND_ISR If you called this function from an ISR and the result
; * would lead to a suspension.
; *
; * Returns : != (void *)0 is a pointer to the message received
; * == (void *)0 if no message was received or you didn't pass a pointer to a queue.
; *********************************************************************************************************
; */
;
; void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) reentrant
; {
; void *msg;
; OS_Q *pq;
;
;
; OS_ENTER_CRITICAL();
; if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */
; OS_EXIT_CRITICAL();
; *err = OS_ERR_EVENT_TYPE;
; return ((void *)0);
; }
; pq = pevent->OSEventPtr; /* Point at queue control block */
; if (pq->OSQEntries != 0) { /* See if any messages in the queue */
; msg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */
; pq->OSQEntries--; /* Update the number of entries in the queue */
; if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */
; pq->OSQOut = pq->OSQStart;
; }
; OS_EXIT_CRITICAL();
; *err = OS_NO_ERR;
; } else if (OSIntNesting > 0) { /* See if called from ISR ... */
; OS_EXIT_CRITICAL(); /* ... can't PEND from an ISR */
; *err = OS_ERR_PEND_ISR;
; } else {
; OSTCBCur->OSTCBStat |= OS_STAT_Q; /* Task will have to pend for a message to be posted */
; OSTCBCur->OSTCBDly = timeout; /* Load timeout into TCB */
; OSEventTaskWait(pevent); /* Suspend task until event or timeout occurs */
; OS_EXIT_CRITICAL();
; OSSched(); /* Find next highest priority task ready to run */
; OS_ENTER_CRITICAL();
; if ((msg = OSTCBCur->OSTCBMsg) != (void *)0) {/* Did we get a message? */
; OSTCBCur->OSTCBMsg = (void *)0; /* Extract message from TCB (Put there by QPost) */
; OSTCBCur->OSTCBStat = OS_STAT_RDY;
; OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */
; OS_EXIT_CRITICAL();
; *err = OS_NO_ERR;
; } else if (OSTCBCur->OSTCBStat & OS_STAT_Q) { /* Timed out if status indicates pending on Q */
; OSEventTO(pevent);
; OS_EXIT_CRITICAL();
; msg = (void *)0; /* No message received */
; *err = OS_TIMEOUT; /* Indicate a timeout occured */
; } else {
; msg = *pq->OSQOut++; /* Extract message from queue */
; pq->OSQEntries--; /* Update the number of entries in the queue */
; if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of Q */
; pq->OSQOut = pq->OSQStart;
; }
; OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
; OS_EXIT_CRITICAL();
; *err = OS_NO_ERR;
; }
; }
; return (msg); /* Return message received (or NULL) */
; }
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * POST MESSAGE TO A QUEUE
; *
; * Description: This function sends a message to a queue
; *
; * Arguments : pevent is a pointer to the event control block associated with the desired queue
; *
; * msg is a pointer to the message to send. You MUST NOT send a NULL pointer.
; *
; * Returns : OS_NO_ERR The call was successful and the message was sent
; * OS_Q_FULL If the queue cannot accept any more messages because it is full.
; * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
; *********************************************************************************************************
; */
;
; INT8U OSQPost (OS_EVENT *pevent, void *msg) reentrant
; {
; OS_Q *pq;
;
;
; OS_ENTER_CRITICAL();
; if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
; OS_EXIT_CRITICAL();
; return (OS_ERR_EVENT_TYPE);
; }
; if (pevent->OSEventGrp) { /* See if any task pending on queue */
; OSEventTaskRdy(pevent, msg, OS_STAT_Q); /* Ready highest priority task waiting on event */
; OS_EXIT_CRITICAL();
; OSSched(); /* Find highest priority task ready to run */
; return (OS_NO_ERR);
; } else {
; pq = pevent->OSEventPtr; /* Point to queue control block */
; if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */
; OS_EXIT_CRITICAL();
; return (OS_Q_FULL);
; } else {
; *pq->OSQIn++ = msg; /* Insert message into queue */
; pq->OSQEntries++; /* Update the nbr of entries in the queue */
; if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */
; pq->OSQIn = pq->OSQStart;
; }
; OS_EXIT_CRITICAL();
; }
; return (OS_NO_ERR);
; }
; }
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * POST MESSAGE TO THE FRONT OF A QUEUE
; *
; * Description: This function sends a message to a queue but unlike OSQPost(), the message is posted at
; * the front instead of the end of the queue. Using OSQPostFront() allows you to send
; * 'priority' messages.
; *
; * Arguments : pevent is a pointer to the event control block associated with the desired queue
; *
; * msg is a pointer to the message to send. You MUST NOT send a NULL pointer.
; *
; * Returns : OS_NO_ERR The call was successful and the message was sent
; * OS_Q_FULL If the queue cannot accept any more messages because it is full.
; * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
; *********************************************************************************************************
; */
;
; INT8U OSQPostFront (OS_EVENT *pevent, void *msg) reentrant
; {
; OS_Q *pq;
;
;
; OS_ENTER_CRITICAL();
; if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
; OS_EXIT_CRITICAL();
; return (OS_ERR_EVENT_TYPE);
; }
; if (pevent->OSEventGrp) { /* See if any task pending on queue */
; OSEventTaskRdy(pevent, msg, OS_STAT_Q); /* Ready highest priority task waiting on event */
; OS_EXIT_CRITICAL();
; OSSched(); /* Find highest priority task ready to run */
; return (OS_NO_ERR);
; } else {
; pq = pevent->OSEventPtr; /* Point to queue control block */
; if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */
; OS_EXIT_CRITICAL();
; return (OS_Q_FULL);
; } else {
; if (pq->OSQOut == pq->OSQStart) { /* Wrap OUT ptr if we are at the 1st queue entry */
; pq->OSQOut = pq->OSQEnd;
; }
; pq->OSQOut--;
; *pq->OSQOut = msg; /* Insert message into queue */
; pq->OSQEntries++; /* Update the nbr of entries in the queue */
; OS_EXIT_CRITICAL();
; }
; return (OS_NO_ERR);
; }
; }
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * QUERY A MESSAGE QUEUE
; *
; * Description: This function obtains information about a message queue.
; *
; * Arguments : pevent is a pointer to the event control block associated with the desired mailbox
; *
; * pdata is a pointer to a structure that will contain information about the message
; * queue.
; *
; * Returns : OS_NO_ERR The call was successful and the message was sent
; * OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non queue.
; *********************************************************************************************************
; */
;
; INT8U OSQQuery (OS_EVENT *pevent, OS_Q_DATA *ppdata) reentrant
; {
; OS_Q *pq;
; INT8U i;
; INT8U *psrc;
; INT8U *pdest;
;
;
; OS_ENTER_CRITICAL();
; if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
; OS_EXIT_CRITICAL();
; return (OS_ERR_EVENT_TYPE);
; }
; ppdata->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */
; psrc = &pevent->OSEventTbl[0];
; pdest = &ppdata->OSEventTbl[0];
; for (i = 0; i < OS_EVENT_TBL_SIZE; i++) {
; *pdest++ = *psrc++;
; }
; pq = (OS_Q *)pevent->OSEventPtr;
; if (pq->OSQEntries > 0) {
; ppdata->OSMsg = pq->OSQOut; /* Get next message to return if available */
; } else {
; ppdata->OSMsg = (void *)0;
; }
; ppdata->OSNMsgs = pq->OSQEntries;
; ppdata->OSQSize = pq->OSQSize;
; OS_EXIT_CRITICAL();
; return (OS_NO_ERR);
; }
; #endif
; *** sync lost ***
; *** sync lost ***
; *** sync lost ***
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -