📄 os.c
字号:
OSTCBCur->OSTCBDly = ticks; EXIT_CRITICAL(); /* find a new task to run */ OSSched();} /* OSTimeDly *//* set system time */void OSTimeSet(uint ticks){ ENTER_CRITICAL(); OSTime = ticks; EXIT_CRITICAL();} /* OSTimeSet *//* get system time */uint OSTimeGet(void){ return(OSTime);} /* OSTimeGet *//* create a semaphore */OS_EVENT*OSSemCreate(int value){ OS_EVENT *pevent; ENTER_CRITICAL(); /* get next available event CB */ pevent = OSEventFreeList; /* update free list */ if (OSEventFreeList) OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; EXIT_CRITICAL(); if (pevent == (OS_EVENT *)0) return((OS_EVENT *)0); /* ran out of event CB */ if (value < 0) { /* semaphore cannot start negative */ ENTER_CRITICAL(); /* return event CB back to the free list */ pevent->OSEventPtr = (void *)OSEventFreeList; OSEventFreeList = pevent; EXIT_CRITICAL(); return((OS_EVENT *)0); } /* set semaphore values */ pevent->OSEventCnt = value; pevent->OSEventGrp = 0; pevent->OSEventTbl[0] = 0; pevent->OSEventTbl[1] = 0; pevent->OSEventTbl[2] = 0; pevent->OSEventTbl[3] = 0; pevent->OSEventTbl[4] = 0; pevent->OSEventTbl[5] = 0; pevent->OSEventTbl[6] = 0; pevent->OSEventTbl[7] = 0; return(pevent);} /* OSSemCreate */static voidOSEventTaskResume(OS_EVENT *pevent){ uint x, y, bitx, bity, p; OS_TCB *ptcb; ENTER_CRITICAL(); /* find highest priority task pending on event */ y = OSUnMapTbl[pevent->OSEventGrp]; bity = OSMapTbl[y]; x = OSUnMapTbl[pevent->OSEventTbl[y]]; bitx = OSMapTbl[x]; p = (y << 3) + x; /* remove task from waiting list */ if ((pevent->OSEventTbl[y] &= ~bitx) == 0) pevent->OSEventGrp &= ~bity; /* pointer to new task */ ptcb = OSTCBPrioTbl[p]; /* reset timeout */ ptcb->OSTCBDly = 0; /* task is ready to run */ ptcb->OSTCBStat = OS_STAT_RDY; /* unlink control block */ ptcb->OSTCBEventPtr = (OS_EVENT *)0; /* put task in ready to run list */ OSRdyGrp |= bity; OSRdyTbl[y] |= bitx; EXIT_CRITICAL(); } /* OSEventTaskResume *//* signal semaphore */uint OSSemPost(OS_EVENT *pevent){ ENTER_CRITICAL(); if (INT_MAX == pevent->OSEventCnt) { /* semaphore overflow */ EXIT_CRITICAL(); return(OS_SEM_OVF); } if (pevent->OSEventCnt++ < 0) { /* negative semaphore means tasks pending */ if (pevent->OSEventGrp) { EXIT_CRITICAL(); /* resume highest priority task pending on semaphore */ OSEventTaskResume(pevent); OSSched(); } } else EXIT_CRITICAL(); return(OS_NO_ERR);} /* OSSemPost *//* wait semaphore */void OSSemPend(OS_EVENT *pevent, uint timeout, uint *err){ ENTER_CRITICAL(); if (pevent->OSEventCnt-- > 0) { /* resource available */ EXIT_CRITICAL(); *err = OS_NO_ERR; return; } /* resource not available, sleep on semaphore */ OSTCBCur->OSTCBStat = OS_STAT_SEM; OSTCBCur->OSTCBDly = timeout; /* suspend task */ if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) OSRdyGrp &= ~OSTCBCur->OSTCBBitY; pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX; pevent->OSEventGrp |= OSTCBCur->OSTCBBitY; EXIT_CRITICAL(); /* find next task ready to run */ OSSched(); ENTER_CRITICAL(); if (OSTCBCur->OSTCBStat == OS_STAT_SEM) { /* still pending on semaphore: timeout */ if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) ==0) pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY; OSTCBCur->OSTCBStat = OS_STAT_RDY; /* no longer waiting for event */ OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; EXIT_CRITICAL(); /* signal timeout */ *err = OS_TIMEOUT; } else { OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; EXIT_CRITICAL(); *err = OS_NO_ERR; }} /* OSSemPend *//* create mailbox */OS_EVENT*OSMboxCreate(void *msg){ OS_EVENT *pevent; ENTER_CRITICAL(); /* get next available event CB */ pevent = OSEventFreeList; /* update free list */ if (OSEventFreeList) OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; EXIT_CRITICAL(); if (pevent == (OS_EVENT *)0) return((OS_EVENT *)0); /* ran out of event CB */ /* set mailbox values */ pevent->OSEventPtr = msg; pevent->OSEventGrp = 0; pevent->OSEventTbl[0] = 0; pevent->OSEventTbl[1] = 0; pevent->OSEventTbl[2] = 0; pevent->OSEventTbl[3] = 0; pevent->OSEventTbl[4] = 0; pevent->OSEventTbl[5] = 0; pevent->OSEventTbl[6] = 0; pevent->OSEventTbl[7] = 0; return(pevent);} /* OSMBoxCreate *//* post mbox message */uint OSMboxPost(OS_EVENT *pevent, void *msg){ ENTER_CRITICAL(); /* make sure mailbox doesn't contain a message */ if (pevent->OSEventPtr != (void *)0) { EXIT_CRITICAL(); return(OS_MBOX_FULL); } /* place message in mailbox */ pevent->OSEventPtr = msg; /* see if any task is pending on the mailbox */ if (pevent->OSEventGrp) { EXIT_CRITICAL(); /* resume highest priority task pending on mailbox */ OSEventTaskResume(pevent); OSSched(); } else EXIT_CRITICAL(); return(OS_NO_ERR);} /* OSMboxPost *//* pend for mbox message */void*OSMboxPend(OS_EVENT *pevent, uint timeout, uint *err){ void *msg; ENTER_CRITICAL(); /* check if the mailbox already has a message */ if ((msg = pevent->OSEventPtr) != (void *)0) { /* clear the mailbox */ pevent->OSEventPtr = (void *)0; EXIT_CRITICAL(); *err = OS_NO_ERR; /* return mailbox content */ return(msg); } /* resource not available, sleep on mailbox */ OSTCBCur->OSTCBStat = OS_STAT_MBOX; OSTCBCur->OSTCBDly = timeout; /* suspend task */ if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) OSRdyGrp &= ~OSTCBCur->OSTCBBitY; pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX; pevent->OSEventGrp |= OSTCBCur->OSTCBBitY; EXIT_CRITICAL(); /* find next task ready to run */ OSSched(); ENTER_CRITICAL(); if (OSTCBCur->OSTCBStat == OS_STAT_MBOX) { /* still pending on mailbox: timeout */ if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY; OSTCBCur->OSTCBStat = OS_STAT_RDY; /* no longer waiting for event */ OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* set message content to null */ msg = (void *)0; EXIT_CRITICAL(); /* signal timeout */ *err = OS_TIMEOUT; } else { /* message received */ msg = pevent->OSEventPtr; /* clear the mailbox */ pevent->OSEventPtr = (void *)0; EXIT_CRITICAL(); *err = OS_NO_ERR; } return(msg);} /* OSMBoxPend *//* create a queue */OS_EVENT*OSQCreate(void **start, uint size){ OS_EVENT *pevent; OS_Q *pq; ENTER_CRITICAL(); /* get next available event CB */ pevent = OSEventFreeList; /* update free list */ if (OSEventFreeList) OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; if (pevent == (OS_EVENT *)0) { /* ran out of event CB */ EXIT_CRITICAL(); return((OS_EVENT *)0); } pq = OSQFreeList; if (OSQFreeList != (OS_Q *)0) OSQFreeList = OSQFreeList->OSQPtr; if (pq == (OS_Q *)0) { /* ran out of queue CB return event CB to free list */ pevent->OSEventPtr = (void *)OSEventFreeList; OSEventFreeList = pevent; EXIT_CRITICAL(); return((OS_EVENT *)0); } EXIT_CRITICAL(); /* initialize the queue */ pq->OSQStart = start; pq->OSQEnd = &start[size]; pq->OSQIn = start; pq->OSQOut = start; pq->OSQSize = size; pq->OSQEntries = 0; pevent->OSEventPtr = pq; pevent->OSEventGrp = 0; pevent->OSEventTbl[0] = 0; pevent->OSEventTbl[1] = 0; pevent->OSEventTbl[2] = 0; pevent->OSEventTbl[3] = 0; pevent->OSEventTbl[4] = 0; pevent->OSEventTbl[5] = 0; pevent->OSEventTbl[6] = 0; pevent->OSEventTbl[7] = 0; return(pevent);} /* OSQCreate *//* post a message to a queue */uint OSQPost(OS_EVENT *pevent, void *msg){ OS_Q *pq; ENTER_CRITICAL(); pq = (OS_Q*)(pevent->OSEventPtr); /* make sure the queue is not full */ if (pq->OSQEntries >= pq->OSQSize) { EXIT_CRITICAL(); return(OS_Q_FULL); } /* insert message into queue */ *pq->OSQIn++ = msg; pq->OSQEntries++; if (pq->OSQIn == pq->OSQEnd) /* wrap around In pointer if reached end */ pq->OSQIn = pq->OSQStart; /* see if any task is pending on the mailbox */ if (pevent->OSEventGrp) { EXIT_CRITICAL(); /* resume highest priority task pending on mailbox */ OSEventTaskResume(pevent); OSSched(); } else EXIT_CRITICAL(); return(OS_NO_ERR);} /* OSQPost *//* pend for message from a queue */void*OSQPend(OS_EVENT *pevent, uint timeout, uint *err){ void *msg; OS_Q *pq; ENTER_CRITICAL(); pq = (OS_Q *)(pevent->OSEventPtr); /* check if the queue already has a message */ if (pq->OSQEntries != 0) { /* extract the message */ msg = *pq->OSQOut++; /* update message counter */ pq->OSQEntries--; /* wrap around Out pointer if reached end */ if (pq->OSQOut == pq->OSQEnd) pq->OSQOut = pq->OSQStart; EXIT_CRITICAL(); *err = OS_NO_ERR; return(msg); } /* no messages available, sleep on the queue */ OSTCBCur->OSTCBStat = OS_STAT_Q; OSTCBCur->OSTCBDly = timeout; /* suspend task */ if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) OSRdyGrp &= ~OSTCBCur->OSTCBBitY; pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX; pevent->OSEventGrp |= OSTCBCur->OSTCBBitY; EXIT_CRITICAL(); /* find next task ready to run */ OSSched(); ENTER_CRITICAL(); if (OSTCBCur->OSTCBStat == OS_STAT_Q) { /* still pending on queue: timeout */ if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY; OSTCBCur->OSTCBStat = OS_STAT_RDY; /* no longer waiting for event */ OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* set message content to null */ msg = (void *)0; EXIT_CRITICAL(); /* signal timeout */ *err = OS_TIMEOUT; } else { /* message received */ msg = *pq->OSQOut++; /* update message counter */ pq->OSQEntries--; /* wrap around Out pointer if reached end */ if (pq->OSQOut == pq->OSQEnd) pq->OSQOut = pq->OSQStart; EXIT_CRITICAL(); *err = OS_NO_ERR; } return(msg);} /* OSQPend *//* exit from interrupt */intOSIntExit(void){ uint y; ENTER_CRITICAL(); /* balanced by restoring PSR in IRQTrap */ if (--OSIntNesting == 0 && OSLockNesting == 0) { /* reschedule if all ISR completed and not locked */ y = OSUnMapTbl[OSRdyGrp]; OSTCBHighRdy = OSTCBPrioTbl[(y << 3) + OSUnMapTbl[OSRdyTbl[y]]]; if (OSTCBHighRdy == OSTCBCur) { /* the highest priority task is the current task */ return(FALSE); } else { /* signal preemption to IRQTrap */ return(TRUE); } } return(FALSE);} /* OSIntExit */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -