轉自 http://blog.csdn.net/xiaocaichonga/article/details/7449409
建立任務OSTaskCreate()
1.OSTaskCreate()函數的聲明
INT8U OSTaskCreate(void(*task)(void*pd),void*pdata,OS_STK *ptos,INT8U prio)
1.1返回類型 INT8U
1.2參數:4個參數,分別是指向任務代碼段的函數指針task,指向任務數據的指針pdata,指向任務所分配的堆棧的棧頂指針ptos,以及任務的優先級prio
2.OSTaskCreate()函數的定義
INT8U OSTaskCreate(void(*task)(void*pd),void*pdata,OS_STK *ptos,INT8U prio)
{
void *psp; /*用於指向任務堆棧初始化後棧頂的指針*/
INT8U err; /*用於存放任務TCB初始化後返回的值*/
if(prio>OS_LOWEST_PRIO) /*判斷任務的優先級是否在允許的範圍內,即如果該任務的優先級比系統的空閒優先級*/
{ /*都低的話,那麼就出錯了*/
return (OS_PRIO_INVALID) /*返回優先級不可得*/
}
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[prio]==(OS_TCB *)0) /*判斷所分配的優先級是否已經被其他任務佔用,(OS_TCB)*0 表示沒有佔用*/
{
OSTCBPrioTbl[prio]=(OS_TCB *)1; /*將新分配的優先級在OSTCBPrioTbl[]中更改爲已佔用狀態即(OS_TCB)*1,注意:
OS_EXIT_CRITICAL(); /*在(OS_TCB)*1狀態下表示僅僅被佔用,但是並沒有爲任務分配資源等操作*/
psp=(void *)OSTaskStkInit(task,pdata,ptos,0);/*將任務堆棧進行初始化,並返回初始化後的棧頂指針給psp*/
/*注意任務堆棧的初始化函數的參數:①代碼段指針②數據段指針③堆棧的棧頂*/
err=OSTCBInit(prio,psp,(void *)0,0,0,(void*0),0);/*TCB的初始化,注意傳入的參數:①任務的優先級即任務的標識符②堆棧初始化後的棧頂指針*/
if(err==OS_NO_ERR) /*如果TCB初始化成功*/
{
OS_ENTER_CRITICAL();
OSTaskCtr++; /*則將系統中的進程數加1*/
OSTaskCreateHook(OSTCBPrioTbl[prio]); /*新建任務的擴展功能,可以由用戶自行定義,但是代碼不能太長,因爲此時中斷關閉*/
OS_EXIT_CRITICAL();
if(OSRunning) /*判斷任務建立時,系統中是否有其他任務在運行,即系統是否已經OSStart()了*/
{
OSSched(); /*如果系統中已經有其他任務運行,則用任務調度函數OSSched()進行任務調度*/
}
}
else
{
OS_ENTER_CRITICAL();
OSTCBPrioTble[prio]=(OS_TCB *)0; /*如果TCB初始化失敗,則將本來佔用的OSTCBPrioTble[]中對應的位標識爲此優先級未被使用*/
OS_EXIT_CRITICAL();
}
return (err); /*在判斷優先級在於規定範圍內的情況下,無論TCB初始化是成功還是失敗,都將返回TCB初始化的值*/
}
else
{
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST); /*如果此優先級已經被佔用,則返回OS_PRIO_EXIST,以告訴系統和用戶優先級已被佔用*/
}
}
3.小結
任務的建立函數OSTaskCreate()到底做了哪些事情呢?
①判斷任務的優先級;
②系統的OSTCBPrioTbl[];
③任務堆棧的初始化;
④任務TCB的初始化。
執行過程:第一步,判斷任務的優先級是否越界,如果越界則返回失敗,如果沒越界進行下一步;
第二步,判斷任務的優先級是否已經被佔用,如果被佔用則返回失敗,如果沒有被佔用進行下一步;
第三步,對OSTCBPrioTbl[]相應位置1,表明此優先級被使用了;
第四步,任務堆棧的初始化;
第五步,任務TCB的初始化,無論初始化失敗還是成功,都將TCB初始化的返回值返回給OSTaskCreate();
第六步,如果TCB初始化失敗了,則將OSTCBPrioTbl[]中的相應位再清0,以表明此優先級沒被使用;如果TCB初始化成功了
則將系統中的任務數加1,並進行下一步;
第七步,盤對系統是否已經處於運行狀態,如果處於運行狀態則進行任務調度。
注意:1.OSTaskCreate()的四個參數分別做了什麼:
①task,pdata和ptos用於了任務堆棧的初始化,即要對任務的代碼指針,數據指針,根據當前分配的棧頂繼續壓棧
②prio用於了PCB的初始化。
2.對於OSTCBPrioTbl[]的理解,該表中的元素是指向TCB的指針,當該指針爲(OS_TCB *)0時標明該位對應的優先級並未被使用,
該爲不爲(OS_TCB *)0時,標明該位對應的優先級被使用,至於使用的情況還要分爲兩種:
①(OS_TCB *)1時,標明該優先級被佔用但是並沒說明該優先級對應哪個TCB;
②指名該優先級被佔用並且指向對應的TCB,這部分在TCB的初始化中完成了。