|
對(duì)于TCB控制塊我的理解是:
任務(wù)控制塊是記錄任務(wù)的優(yōu)先級(jí),狀態(tài),堆棧指針等參數(shù)的一個(gè)鏈表,這個(gè)鏈表分為兩部分,一個(gè)叫做空閑鏈表,一個(gè)叫做當(dāng)前任務(wù)鏈表,空閑鏈表是人物創(chuàng)建的時(shí)候去申請(qǐng),得到后設(shè)置參數(shù),設(shè)置完了就把這個(gè)鏈表加載到當(dāng)前鏈表中,下面看看任務(wù)建立的時(shí)候是怎么做的。
、、部分代碼,不相關(guān)的略去
psp = (void DT_XDATA *)OSTaskStkInit(task, ppdata, ptos, 0); /* Initialize the task's stack
err = OSTCBInit(prio, psp, (void DT_XDATA *)0, 0, 0, (void DT_XDATA *)0, 0);
第一個(gè)是用來獲得任務(wù)堆棧的基地址,任務(wù)堆棧這個(gè)東西,在開始的時(shí)候就建好了,其實(shí)就是個(gè)大數(shù)組,每個(gè)任務(wù)都有一個(gè),當(dāng)任務(wù)切換時(shí)這個(gè)數(shù)組用來存CPU相關(guān)的寄存器,比如累加器和8個(gè)寄存器,返回指針,任務(wù)的切換說白了就是人為的模仿了一次軟件中斷,
第二個(gè)用來獲取任務(wù)的TCB控制塊,并加載到當(dāng)前任務(wù)控制塊列表,
主要看第二個(gè)函數(shù),第一個(gè)就是對(duì)堆棧的一個(gè)分配,決定那個(gè)字節(jié)些什么,初始化,關(guān)鍵是第二個(gè)TCB的創(chuàng)建
程序如下:
OS_TCB DT_XDATA * ptcb;//定義一個(gè)TCB的結(jié)構(gòu)指針
OS_ENTER_CRITICAL();//進(jìn)入臨界代碼區(qū)
/* Get a free TCB from the free TCB list */
ptcb = OSTCBFreeList; //獲取一個(gè)空的TCB塊給PTCB
//判斷TCB是否用完?用完了返回錯(cuò)誤70
if (ptcb != (OS_TCB DT_XDATA *)0) {
OSTCBFreeList = ptcb->OSTCBNext; /* Update pointer to free TCB list */
OS_EXIT_CRITICAL();//開中斷
ptcb->OSTCBStkPtr = ptos;//任務(wù)堆棧指針寫入 /* Load Stack pointer in TCB */
ptcb->OSTCBPrio = (INT8U)prio; //任務(wù)優(yōu)先級(jí) /* Load task priority into TCB */
ptcb->OSTCBStat = OS_STAT_RDY;//任務(wù)狀態(tài)這個(gè)表示準(zhǔn)備好了 /* Task is ready to run */
ptcb->OSTCBDly = 0; //任務(wù)延時(shí) /* Task is not delayed */
/* Pre-compute X, Y, BitX and BitY */
//把優(yōu)先級(jí)分解,計(jì)算出在就緒表中的位置
ptcb->OSTCBY = prio >> 3;
ptcb->OSTCBBitY = OSMapTbl[ptcb->OSTCBY];
ptcb->OSTCBX = prio & 0x07;
ptcb->OSTCBBitX = OSMapTbl[ptcb->OSTCBX];
OS_ENTER_CRITICAL();
/* OSTCBPrioTbl */
OSTCBPrioTbl[prio] = ptcb; //寫入OSTCBPrioTbl數(shù)組中對(duì)應(yīng)的優(yōu)先級(jí)的TCB指針地址
/* Link into TCB chain. insert to the first of chain */
ptcb->OSTCBNext = OSTCBList; //裝載下一個(gè)鏈表地址
ptcb->OSTCBPrev = (OS_TCB DT_XDATA *)0; //裝載先前指針
//如果 OSTCBList不為0 那么上一個(gè)指針就是當(dāng)前的ptcb
if (OSTCBList != (OS_TCB DT_XDATA *)0) {
OSTCBList->OSTCBPrev = ptcb;
}
OSTCBList = ptcb;
//優(yōu)先級(jí)寫入就緒表
OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
這里面的就是TCB的創(chuàng)建!大體上分為以下幾個(gè)部分:
1,申請(qǐng)空鏈表
2.對(duì)申請(qǐng)到的空鏈表進(jìn)行初始化,
3加載空鏈表到當(dāng)前鏈表
4釋放下一個(gè)鏈表的位置,
這里又有4個(gè)結(jié)構(gòu)指針是核心分別是
OS_TCB DT_XDATA * ptcb
OS_EXT OS_TCB DT_XDATA * DT_XDATA OSTCBFreeList;
OS_EXT OS_TCB DT_XDATA * DT_XDATA OSTCBList;
OS_EXT OS_TCB DT_XDATA * DT_XDATA OSTCBPrioTbl[OS_LOWEST_PRIO + 1];
第一個(gè)是中間指針變量,第二個(gè)是空鏈表,第三個(gè)是當(dāng)前TCB表,第四個(gè)是對(duì)應(yīng)優(yōu)先級(jí)的TCB表位置
對(duì)他們的操作如下:
第一歩:
ptcb = OSTCBFreeList;
表示把指向空閑鏈表指針的地址給PTCB這個(gè)中間人
第二部:
ptcb->OSTCBStkPtr = ptos;//任務(wù)堆棧指針寫入 /* Load Stack pointer in TCB */
ptcb->OSTCBPrio = (INT8U)prio; //任務(wù)優(yōu)先級(jí) /* Load task priority into TCB */
ptcb->OSTCBStat = OS_STAT_RDY;//任務(wù)狀態(tài)這個(gè)表示準(zhǔn)備好了 /* Task is ready to run */
ptcb->OSTCBDly = 0;
表示對(duì)空閑鏈表初始化操作
第三部:
OSTCBPrioTbl[prio] = ptcb;
表示把申請(qǐng)到的當(dāng)前TCB控制塊的地址放到優(yōu)先級(jí)里這樣使得優(yōu)先級(jí)和對(duì)應(yīng)的TCB對(duì)應(yīng)起來,比如優(yōu)先級(jí)是20,那么他就在20那個(gè)結(jié)構(gòu)數(shù)組里
存入優(yōu)先級(jí)為20的任務(wù)TCB控制塊,
第四部:
ptcb->OSTCBNext = OSTCBList;
ptcb->OSTCBPrev = (OS_TCB DT_XDATA *)0;
if (OSTCBList != (OS_TCB DT_XDATA *)0) {
OSTCBList->OSTCBPrev = ptcb;
}
OSTCBList = ptcb;
這一步表示下一個(gè)鏈表的地址是OSTCBList當(dāng)前地址
并且吧當(dāng)前申請(qǐng)到的TCB表寫回到當(dāng)前鏈表中,這是個(gè)加載,而上一個(gè)是釋放
最后加載到入任務(wù)就緒表中就OK樂。。!
|
|