📄 133.htm
字号:
if ((msg = pevent->OSEventPtr) != (void *)0) { /* See if there is alreadyy a message */ <br>
pevent->OSEventPtr = (void *)0; /* Clear the mailbox <br>
} <br>
OS_EXIT_CRITICAL(); <br>
return (msg); /* Return the message receeived (or NULL) */ <br>
} <br>
} <br>
/*$PAGE*/ <br>
/* <br>
********************************************************************************************************** <br>
* PEND ON MAILBOX FOR A MESSAGE <br>
********************************************************************************************************** <br>
*/ <br>
<br>
void *OSMboxPend(OS_EVENT *pevent, UWORD timeout, UBYTE *err) <br>
{ <br>
void *msg; <br>
<br>
<br>
OS_ENTER_CRITICAL(); <br>
if ((msg = pevent->OSEventPtr) != (void *)0) { /* See if there is alreadyy a message */ <br>
pevent->OSEventPtr = (void *)0; /* Clear the mailbox <br>
OS_EXIT_CRITICAL(); <br>
*err = OS_NO_ERR; <br>
} else { <br>
OSTCBCur->OSTCBStat |= OS_STAT_MBOX; /* Message not available, task will pend */ <br>
OSTCBCur->OSTCBDly = timeout; /* Load timeout in TCB <br>
OSTCBCur->OSTCBEventPtr = pevent; /* Store pointer to event control block in TCB */ <br>
if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) { /* Tassk no longer ready */ <br>
OSRdyGrp &= ~OSTCBCur->OSTCBBitY; <br>
} <br>
pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX; /* Putt task in waiting list */ <br>
pevent->OSEventGrp |= OSTCBCur->OSTCBBitY; <br>
OS_EXIT_CRITICAL(); <br>
OSSched(); /* Find next highest priorrity task ready to run */ <br>
OS_ENTER_CRITICAL(); <br>
if (OSTCBCur->OSTCBStat & OS_STAT_MBOX) { /* If status is not OS_STAAT_RDY, timeout occured */ <br>
if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) === 0) { <br>
pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY; <br>
} <br>
OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set status to readdy */ <br>
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; <br>
OS_EXIT_CRITICAL(); <br>
msg = (void *)0; /* Set message contennts to NULL */ <br>
*err = OS_TIMEOUT; /* Indicate that a tiimeout occured */ <br>
} else { <br>
if ((msg = OSTCBCur->OSTCBMsg) != (void *)0) { /* See if we were givven the message */ <br>
OSTCBCur->OSTCBMsg = (void *)0; /* Yes, clear messagee received */ <br>
} else { <br>
msg = pevent->OSEventPtr; /* Message received */ <br>
pevent->OSEventPtr = (void *)0; /* Clear the mailbox */ <br>
} <br>
OS_EXIT_CRITICAL(); <br>
*err = OS_NO_ERR; <br>
} <br>
} <br>
return (msg); /* Return the messagee received (or NULL) */ <br>
} <br>
/*$PAGE*/ <br>
/* <br>
********************************************************************************************************** <br>
* POST MESSAGE TO A MAILBOX <br>
********************************************************************************************************** <br>
*/ <br>
<br>
UBYTE OSMboxPost(OS_EVENT *pevent, void *msg) <br>
{ <br>
OS_TCB *ptcb; <br>
UBYTE x; <br>
UBYTE y; <br>
UBYTE bitx; <br>
UBYTE bity; <br>
UBYTE p; <br>
UBYTE p; <br>
<br>
<br>
OS_ENTER_CRITICAL(); <br>
if (pevent->OSEventGrp) { /* See if any task pendingg on mailbox */ <br>
y = OSUnMapTbl[pevent->OSEventGrp]; /* Find highest prio. taskk waiting for message */ <br>
bity = OSMapTbl[y]; <br>
x = OSUnMapTbl[pevent->OSEventTbl[y]]; <br>
bitx = OSMapTbl[x]; <br>
p = (y << 3) + x; /* Find the priority of thhe task */ <br>
if ((pevent->OSEventTbl[y] &= ~bitx) == 0) { /* Remove this task from tthe waiting list */ <br>
pevent->OSEventGrp &= ~bity; <br>
} <br>
ptcb = OSTCBPrioTbl[p]; /* Point to this task's OSS_TCB */ <br>
ptcb->OSTCBDly = 0; /* Prevent OSTimeTick() frrom readying task */ <br>
ptcb->OSTCBEventPtr = (OS_EVENT *)0; /* Unlink ECB from this taask */ <br>
ptcb->OSTCBMsg = msg; /* Send message directly tto waiting task */ <br>
ptcb->OSTCBStat &= ~OS_STAT_MBOX; /* Clear bit associated wiith event type */ <br>
if (ptcb->OSTCBStat == OS_STAT_RDY) { /* See if task is ready (ccould be suspended) */ <br>
OSRdyGrp |= bity; /* Put task in the ready tto run list */ <br>
OSRdyTbl[y] |= bitx; <br>
} <br>
OS_EXIT_CRITICAL(); <br>
OSSched(); /* Find highest priority ttask ready to run */ <br>
return (OS_NO_ERR); <br>
} else { <br>
if (pevent->OSEventPtr != (void *)0) { /* Make sure mailbox doesnn't already have a msg */ <br>
OS_EXIT_CRITICAL(); <br>
return (OS_MBOX_FULL); <br>
} else { <br>
pevent->OSEventPtr = msg; /* Place message in mailboox */ <br>
OS_EXIT_CRITICAL(); <br>
return (OS_NO_ERR); <br>
} <br>
} <br>
} <br>
#endif <br>
/*$PAGE*/ <br>
#if OS_Q_EN <br>
/* <br>
********************************************************************************************************** <br>
* INITIALIZE MESSAGE QUEUE <br>
********************************************************************************************************** <br>
*/ <br>
<br>
<br>
OS_EVENT *OSQCreate(void **start, UBYTE size) <br>
{ <br>
OS_EVENT *pevent; <br>
OS_Q *pq; <br>
<br>
<br>
OS_ENTER_CRITICAL(); <br>
pevent = OSEventFreeList; /* Get next free event control block */ <br>
if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pooll was empty */ <br>
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; <br>
} <br>
OS_EXIT_CRITICAL(); <br>
if (pevent != (OS_EVENT *)0) { /* See if we have an event conttrol block */ <br>
OS_ENTER_CRITICAL(); /* Get a free queue control bloock */ <br>
pq = OSQFreeList; <br>
if (OSQFreeList != (OS_Q *)0) { <br>
OSQFreeList = OSQFreeList->OSQPtr; <br>
} <br>
OS_EXIT_CRITICAL(); <br>
if (pq != (OS_Q *)0) { /* See if we were able to get aa queue control block */ <br>
pq->OSQStart = start; /* Yes, initialize the queue <br>
pq->OSQEnd = &start[size]; <br>
pq->OSQIn = start; <br>
pq->OSQOut = start; <br>
pq->OSQSize = size; <br>
pq->OSQEntries = 0; <br>
pevent->OSEventPtr = pq; <br>
pevent->OSEventGrp = 0x00; /* Initialize rest of event conntrol block */ <br>
pevent->OSEventTbl[0] = 0x00; <br>
pevent->OSEventTbl[1] = 0x00; <br>
pevent->OSEventTbl[2] = 0x00; <br>
pevent->OSEventTbl[3] = 0x00; <br>
pevent->OSEventTbl[4] = 0x00; <br>
pevent->OSEventTbl[5] = 0x00; <br>
pevent->OSEventTbl[6] = 0x00; <br>
pevent->OSEventTbl[7] = 0x00; <br>
} else { /* No, since we couldn't get aa queue control block */ <br>
OS_ENTER_CRITICAL(); /* Return event control block oon error */ <br>
pevent->OSEventPtr = (void *)OSEventFreeList; <br>
OSEventFreeList = pevent; <br>
OS_EXIT_CRITICAL(); <br>
pevent = (OS_EVENT *)0; <br>
} <br>
} <br>
} <br>
return (pevent); <br>
} <br>
/*$PAGE*/ <br>
/* <br>
********************************************************************************************************** <br>
* ACCEPT MESSAGE FROM QUEUE <br>
* <br>
* Description: This function checks the queue to see if a message is available. Unlike OSQPend(), <br>
* OSQAccept() does not suspend the calling task if a message is nott available. <br>
* Arguments : 'pevent' is a pointer to the event control block <br>
* Returns : != (void *)0 is the message in the queue if one is available. TThe message is removed <br>
* from the so the next time OSQAccept() is called, thhe queue will contain <br>
* one less entry. <br>
* == (void *)0 if the queue is empty <br>
********************************************************************************************************** <br>
*/ <br>
<br>
void *OSQAccept(OS_EVENT *pevent) <br>
{ <br>
void *msg; <br>
OS_Q *pq; <br>
<br>
<br>
<br>
OS_ENTER_CRITICAL(); <br>
pq = pevent->OSEventPtr; /* Point at queue control blockk */ <br>
if (pq->OSQEntries != 0) { /* See if any messages in the qqueue */ <br>
msg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */ <br>
pq->OSQEntries--; /* Update the number of entriess in the queue */ <br>
if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are aat the end of the queue */ <br>
pq->OSQOut = pq->OSQStart; <br>
} <br>
} else { <br>
msg = (void *)0; /* Queue is empty <br>
} <br>
OS_EXIT_CRITICAL(); <br>
return (msg); /* Return message received (or NULL) */ <br>
} <br>
/*$PAGE*/ <br>
/* <br>
********************************************************************************************************** <br>
* PEND ON A QUEUE FOR A MESSAGE <br>
********************************************************************************************************** <br>
*/ <br>
<br>
<br>
void *OSQPend(OS_EVENT *pevent, UWORD timeout, UBYTE *err) <br>
{ <br>
void *msg; <br>
OS_Q *pq; <br>
<br>
<br>
OS_ENTER_CRITICAL(); <br>
pq = pevent->OSEventPtr; /* Point at queue control blockk */ <br>
if (pq->OSQEntries != 0) { /* See if any messages in the qqueue */ <br>
msg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */ <br>
pq->OSQEntries--; /* Update the number of entriess in the queue */ <br>
if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are aat the end of the queue */ <br>
pq->OSQOut = pq->OSQStart; <br>
} <br>
OS_EXIT_CRITICAL(); <br>
*err = OS_NO_ERR; <br>
} else { <br>
OSTCBCur->OSTCBStat |= OS_STAT_Q; /* Task will have to pend for aa message to be posted */ <br>
OSTCBCur->OSTCBDly = timeout; /* Load timeout into TCB <br>
OSTCBCur->OSTCBEventPtr = pevent; /* Store pointer to event contrrol block in TCB */ <br>
if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) { /* Tassk no longer ready */ <br>
OSRdyGrp &= ~OSTCBCur->OSTCBBitY; <br>
} <br>
pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX; /* Putt task in waiting list */ <br>
pevent->OSEventGrp |= OSTCBCur->OSTCBBitY; <br>
OS_EXIT_CRITICAL(); <br>
OSSched(); /* Find next highest priority ttask ready to run */ <br>
OS_ENTER_CRITICAL(); <br>
if (OSTCBCur->OSTCBStat & OS_STAT_Q) { /* Timeout occured if status inndicates pending on Q */ <br>
if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) === 0) { <br>
pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY; <br>
} <br>
OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set status to ready <br>
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for eevent */ <br>
OS_EXIT_CRITICAL(); <br>
msg = (void *)0; /* No message received <br>
*err = OS_TIMEOUT; /* Indicate a timeout occuured */ <br>
} else { <br>
if ((msg = OSTCBCur->OSTCBMsg) != (void *)0) { <br>
OSTCBCur->OSTCBMsg = (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -