uC/OS II--与ECB操作相关的四个函数
對ECB的操作一般包括:
????* 初始化一個事件控制塊???????????????(void??OS_EventWaitListInit (OS_EVENT *pevent))
????* 使一個任務進入就緒態???????????????(INT8U OS_EventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk))
????* 使一個任務進入等待某事件的狀態?????(void??OS_EventTaskWait (OS_EVENT *pevent))
????* 因為等待超時而使一個任務進入就緒態 (void??OS_EventTO (OS_EVENT *pevent))
????對OS_EventTaskRdy()函數和OS_EventTO函數的調用都需要關中斷。
1. OS_EventWaitListInit (OS_EVENT *pevent)
????此函數被與ECB建立相關的函數調用,如OSSemCreate()、OSMutexCreate()、OSQCreate()和OSMboxCreate()。函數功能就是對ECB中的等待任務列表進行初始化,函數創建時,等待任務列表初始化為空。這個函數是對內的,即此函數可以被uC/OS II調用,用戶應用程序不可以直接調用此函數。代碼如下:
#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) || (OS_SEM_EN > 0) || (OS_MUTEX_EN > 0)
void??OS_EventWaitListInit (OS_EVENT *pevent)
{
????INT8U??*ptbl;
????pevent->OSEventGrp = 0x00;??????????????????
????ptbl???????????????= &pevent->OSEventTbl[0];
#if OS_EVENT_TBL_SIZE > 0
????*ptbl++????????????= 0x00;
#endif
#if OS_EVENT_TBL_SIZE > 1
????*ptbl++????????????= 0x00;
#endif
#if OS_EVENT_TBL_SIZE > 2
????*ptbl++????????????= 0x00;
#endif
#if OS_EVENT_TBL_SIZE > 3
????*ptbl++????????????= 0x00;
#endif
#if OS_EVENT_TBL_SIZE > 4
????*ptbl++????????????= 0x00;
#endif
#if OS_EVENT_TBL_SIZE > 5
????*ptbl++????????????= 0x00;
#endif
#if OS_EVENT_TBL_SIZE > 6
????*ptbl++????????????= 0x00;
#endif
#if OS_EVENT_TBL_SIZE > 7
????*ptbl??????????????= 0x00;
#endif
}
#endif
????上面的代碼功能比較簡單,唯一需要注意的是,Labrosse先生使用條件編譯代替了for循環,這樣做的目的是減少編譯時間(具體的效率,暫不清楚)。
2. INT8U OS_EventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk)
????當某事件發生時,要將等待該事件任務列表中優先級最高的的任務置于就緒態,信號量、互斥型信號量、消息郵箱、消息隊列所對應的POST函數都會調用OS_EventTaskRdy()。這個函數是對內的,即此函數可以被uC/OS II調用,用戶應用程序不可以直接調用此函數。源碼如下:
#if OS_EVENT_EN > 0
INT8U??OS_EventTaskRdy?(OS_EVENT *pevent, void *msg, INT8U msk)
{
????OS_TCB *ptcb;
????INT8U???x;
????INT8U???y;
????INT8U???bitx;
????INT8U???bity;
????INT8U???prio;
????y????= OSUnMapTbl[pevent->OSEventGrp];???????????
????bity = OSMapTbl[y];
????x????= OSUnMapTbl[pevent->OSEventTbl[y]];
????bitx = OSMapTbl[x];
????prio = (INT8U)((y << 3) + x);????????????????????
????if ((pevent->OSEventTbl[y] &= ~bitx) == 0x00) {??
????????pevent->OSEventGrp &= ~bity;??????????????????
????}
????ptcb?????????????????=??OSTCBPrioTbl[prio];??????
????ptcb->OSTCBDly???????=??0;???????????????????????
????ptcb->OSTCBEventPtr??= (OS_EVENT *)0;????????????
#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0)
????ptcb->OSTCBMsg???????= msg;??????????????????????
#else
????msg??????????????????= msg;??????????????????????
#endif
????ptcb->OSTCBStat?????&= ~msk;?????????????????????
????if (ptcb->OSTCBStat == OS_STAT_RDY) {????????????
????????OSRdyGrp????????|=??bity;????????????????????
????????OSRdyTbl[y]?????|=??bitx;
????}
????return (prio);
}
#endif
????需要注意的是if (ptcb->OSTCBStat == OS_STAT_RDY),這說明最高優先級任務得到該事件后不一定就能進入就緒態,也許該任務由于其他原因“suspend”了。
3. void??OS_EventTaskWait (OS_EVENT *pevent)
????當某任務等待某事件的發生時,信號量、互斥型信號量、消息郵箱、消息隊列所對應的PEND函數就會調用OS_EventTaskWait(),是當前任務脫離就緒態,并放到相應的ECB的任務等待表中。這個函數是對內的,即此函數可以被uC/OS II調用,用戶應用程序不可以直接調用此函數。源碼如下:
#if OS_EVENT_EN > 0
void??OS_EventTaskWait (OS_EVENT *pevent)
{
????OSTCBCur->OSTCBEventPtr = pevent;???????????
????if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0x00) {??
????????OSRdyGrp &= ~OSTCBCur->OSTCBBitY;???????
????}
????pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;
????pevent->OSEventGrp???????????????????|= OSTCBCur->OSTCBBitY;
}
#endif
4. void??OS_EventTO (OS_EVENT *pevent)
????這個函數牽涉到任務等待超時問題,uC/OS II中可以為任務等待設置一個等待時間,如果在規定的時間內任務等待的事件得不到相應(沒有發生),那么OSTimeTick()函數會因為等待超時而將任務置為就緒態。信號量、互斥型信號量、消息郵箱、消息隊列所對應的PEND函數就會調用OS_EventTO()函數,完成上述工作。這個函數是對內的,即此函數可以被uC/OS II調用,用戶應用程序不可以直接調用此函數。源碼如下:
#if OS_EVENT_EN > 0
void??OS_EventTO (OS_EVENT *pevent)
{
????if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0x00) {
????????pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY;
????}
????OSTCBCur->OSTCBStat?????= OS_STAT_RDY;??????
????OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;????
}
#endif
總結
以上是生活随笔為你收集整理的uC/OS II--与ECB操作相关的四个函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++堆 和 栈 空间的区别
- 下一篇: “真三”中的人生哲理