前面寫了switch case做任務(wù)調(diào)度的應(yīng)用,這邊寫一下如何實現(xiàn).像一般的RTOS一樣都有一個任務(wù)控制塊(TCB)列表來管理所有的任務(wù),所以這里也需要一個結(jié)構(gòu)體來管理動作任務(wù),這里叫做ACB吧.
動作任務(wù)管理結(jié)構(gòu)體
這個結(jié)構(gòu)體用來記錄當(dāng)前動作任務(wù)的當(dāng)前步驟,函數(shù)地址,事件處理函數(shù)的函數(shù)地址,動作名稱,運行時間等.
typedef struct _ACB
{
uint8_t nStep; // 分支動作步驟
uint8_t nChildID; //子動作ID
uint32_t nDelay; // 延時
uint32_t nStartTime;
uint32_t nUsedTime;
uint32_t nStatus; //當(dāng)前狀態(tài)
ActionEvent EventQueue[4]; //動作事件隊列
uint8_t nEventCnt; //事件數(shù)量和個數(shù)
void (*AppCallBack)(); //業(yè)務(wù)動作函數(shù)指針
void (*EventCallback)(); //事件處理函數(shù)指針
void (*ActionCallback)(); //當(dāng)前運行的函數(shù)指針
char ActionParam[10]; //動作參數(shù)
//17
char* pActionName; //動作名稱
char* pErrorInfo; //錯誤信息
//8
struct _ACB* next; //上一個控制塊 便于刪除添加到就緒隊列
struct _ACB* prev; //下一個控制塊 便于添加刪除到就緒隊列
} ACB;
動作任務(wù)創(chuàng)建
//將OpApp業(yè)務(wù)函數(shù)指針和ACB結(jié)構(gòu)體綁定
void AddAction(int nID,void (*OpApp)(),const char* pActionName)
{
if(nID<90)
{
mOS.ActionPool[nID].AppCallBack = OpApp;
mOS.ActionPool[nID].EventCallback = EventAction;
mOS.ActionPool[nID].ActionCallback = OpApp;
mOS.ActionPool[nID].nStatus = 0xff;
mOS.ActionPool[nID].nEventCnt = 0;
mOS.ActionPool[nID].nUsedTime = 0;
mOS.ActionPool[nID].nStartTime = 0;
mOS.ActionPool[nID].pActionName = (char*)pActionName;
}
}
動作任務(wù)執(zhí)行
1.動作結(jié)構(gòu)體初始化,添加到就緒隊列
//根據(jù)ID啟動動作任務(wù)
int8_t StartAction(uint8_t ActionId)
{
if(ActionId>90)
{
return false;
}
ACB* pAction = &mOS.ActionPool[ActionId];
pAction->ActionStartTime = mOS.SystemTime;
pAction->nStep = STEP1;
pAction->nEventCnt = 0;
pAction->nUsedTime = 0;
pAction->nChildID = 0;
pAction->EventCallback = EventAction;
pAction->ActionCallback = pAction->AppCallBack;//先指向業(yè)務(wù)函數(shù)指針
AddReadyActionToTail(pAction); //把當(dāng)前的控制塊添加到就緒隊列
return true;
}
//將要運行的動作添加到就緒運行隊列
void AddReadyActionToTail(ACB * pAction)
{
pAction->nStaus = 0;
pAction->next = NULL;
pAction->prev = mOS.tail; //
if(mOS.head==NULL)
{
mOS.head = pAction;
}
if(mOS.tail!=NULL) //當(dāng)就緒鏈表沒有動作時 tail為空
{
mOS.tail->next = pAction;
}
mOS.tail = pAction; //移動尾部指針
}
2.就緒隊列遍歷
inline void AppLoop()
{
mOS.current = mOS.head;
while(mOS.current!=NULL)
{
mOS.current->ActionCallback();
DelFinishAction(); //需要把完成的任務(wù)從就緒隊列刪除
mOS.current = mOS.current->next;
}
}
//動作完成后,并計算動作使用時間,從鏈表刪除
inline void DelFinishAction()
{
if(mOS.current->nStatus==0) //動作任務(wù)正在運行
{
return ;
}
//統(tǒng)計任務(wù)耗時
mOS.current->nUsedTime = mOS.SystemTime - mOS.CurrentAction->nStartTime; //當(dāng)前時間減去開始時間
if(mOS.head==mOS.tail) //只有一個元素
{
mOS.head= NULL;
mOS.tail = NULL;
return ;
}
if(mOS.current==mOS.head) //頭部刪除,需要將頭部指針往后移動
{
mOS.head = mOS.current->next;
return ;
}
if(mOS.current==mOS.tail) //尾部刪除,需要將尾部指針往前移動
{
mOS.tail = mOS.current->prev;
mOS.tail->next = NULL;
return ;
}
//中間刪除
mOS.current->prev->next = mOS.current->next;
mOS.current->next->prev = mOS.current->prev;
}
-
Switch
+關(guān)注
關(guān)注
1文章
533瀏覽量
58222 -
RTOS
+關(guān)注
關(guān)注
22文章
811瀏覽量
119595 -
結(jié)構(gòu)體
+關(guān)注
關(guān)注
1文章
130瀏覽量
10840
發(fā)布評論請先 登錄
相關(guān)推薦
評論