|
調(diào)用系統(tǒng)服務(wù)使任務(wù)切換時(shí)不保存寄存器變量
中斷服務(wù)執(zhí)行任務(wù)切換時(shí),保存寄存器變量
支持7個(gè)任務(wù),支持7級(jí)中斷嵌套
基于優(yōu)先級(jí)調(diào)度,0號(hào)任務(wù)具有最高優(yōu)先級(jí)
包含K_FLG K_SEM K_MSG K_TMO這幾個(gè)系統(tǒng)服務(wù),每種類型的系統(tǒng)服務(wù)最多提供16個(gè)
單片機(jī)源程序如下:
- #define _IN_LQ51_C_
- #include "lq51.h"
- #include<reg52.h>
- /******************************************
- / 定義全局變量
- /******************************************/
- unsigned char data lqTaskStack[lqMaxID+1]; /*任務(wù)堆棧指針*/
- unsigned char data lqSPtemp; /*記錄ID號(hào)=當(dāng)前任務(wù)ID+1的堆棧底部*/
- unsigned char data lqTaskTimer[lqMaxID]; /*任務(wù)定時(shí)器*/
- unsigned char data lqTaskState[lqMaxID]; /*任務(wù)狀態(tài)表*/
- unsigned char data lqRdyTbl; /*就緒表*/
- unsigned char data lqSwitchType; /*任務(wù)切換類型,如果通過中斷切換任務(wù)則在相應(yīng)位置1,否則置0*/
- unsigned char data lqIntNum; /*進(jìn)入中斷服務(wù)子程序后系統(tǒng)把中斷號(hào)傳給這個(gè)變量*/
- unsigned char data lqCrt; /*當(dāng)前正在運(yùn)行的任務(wù)*/
- #if LQ_FLG_EN /*該事件的最高位表示該標(biāo)志位是否置位,其他位表示等待該標(biāo)志量的任務(wù),當(dāng)標(biāo)志位置位時(shí),所有等待這個(gè)標(biāo)志的任務(wù)都被激活*/
- unsigned char data lqFlgData[lqFlgMax]={
- 0,0
- };
- #endif
- #if LQ_SEM_EN /*信號(hào)量數(shù)據(jù)結(jié)構(gòu)*/
- /*一個(gè)信號(hào)量數(shù)據(jù)結(jié)構(gòu)包含兩個(gè)字節(jié),第一個(gè)字節(jié)為信號(hào)量值*/
- unsigned char data lqSemData[lqSemMax*2]={ /*第二個(gè)字節(jié)為等待這個(gè)信號(hào)量的任務(wù)*/
- 0,0,
- 0,0};
- #endif
- #if LQ_MSG_EN /*消息郵箱數(shù)據(jù)結(jié)構(gòu)*/
- /*一個(gè)消息郵箱數(shù)據(jù)結(jié)構(gòu)包含兩個(gè)字節(jié),第一個(gè)字節(jié)為消息郵箱的消息*/
- unsigned char data lqMsgData[lqMsgMax*2]={ /*第二個(gè)字節(jié)的最高位表示當(dāng)前郵箱是否有消息0表示沒有1表示有,其他為表示等待這個(gè)消息的任務(wù)*/
- 0,0,
- 0,0};
- #endif
- const unsigned char code lqMap[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
- /*****************************************
- / 開始函數(shù)
- /這個(gè)函數(shù)必須在0號(hào)任務(wù)的最開始的部分調(diào)用
- / void lqStart(void);
- /*****************************************/
- void lqStart(void)
- {
- char i;
- for(i=0;i<lqMaxID;++i){
- lqTaskTimer[i] = 0;
- lqTaskState[i] = 0;
- }
- lqRdyTbl=0xFF;
- lqSwitchType=0x00;
- EA = 1;
- lqCrt=0;
- }
- #if LQ_DELAY_EN
- /***************************************************
- / 任務(wù)延遲一段時(shí)間
- / void lqDelay(unsigned char tmo)
- / tmo:延遲時(shí)間,如果tmo=0,那么當(dāng)前任務(wù)休眠,永遠(yuǎn)不會(huì)被激活
- /***************************************************/
- void lqDelay(unsigned char tmo)
- {
- EA=0;
- lqRdyTbl &= ~lqMap[lqCrt];
- lqTaskState[lqCrt] |= K_TMO;
- lqTaskTimer[lqCrt] = tmo;
- EA=1;
- lqSche();
- }
- #endif
- #if LQ_FLG_EN
- /**************************************************
- / 等待標(biāo)志
- / char lqWaitFlg(unsigned char index,unsigned char tmo)
- / index :標(biāo)志量索引
- / tmo :超時(shí)等待時(shí)限,如果為0則無限等待
- / 返回值:
- / 標(biāo)志量有效返回 K_FLG
- / 在規(guī)定的時(shí)件內(nèi)標(biāo)志量未發(fā)生返回 K_TMO
- /*************************************************/
- unsigned char lqWaitFlg(unsigned char index,unsigned char tmo)
- {
- EA=0;
- lqTaskState[lqCrt] &= 0xF0;
- lqTaskState[lqCrt]|= index; /*將當(dāng)前索引值保存到任務(wù)狀態(tài)的低四位,因?yàn)楹瘮?shù)是不可重入的*/
- if(lqFlgData[index] & 0x80){ /*標(biāo)志量置位*/
- lqFlgData[index] = 0;
- EA=1;
- return K_FLG;
- }
- lqFlgData[index] |= lqMap[lqCrt];
- lqRdyTbl &= ~lqMap[lqCrt];
- lqTaskState[lqCrt] |= K_FLG;
- if(tmo){
- lqTaskState[lqCrt] |= K_TMO;
- lqTaskTimer[lqCrt] = tmo;
- }
- EA=1;
- lqSche();
- EA=0;
- index = 0x0F & lqTaskState[lqCrt];
- if(lqTaskState[lqCrt] & K_FLG){ /*等待超時(shí)返回*/
- lqTaskState[lqCrt] &= ~K_FLG;
- lqTaskState[lqCrt] |= K_TMO; /*超時(shí)標(biāo)記*/
- lqFlgData[index] &= ~lqMap[lqCrt];
- EA=1;
- return K_TMO;
- }
- EA=1;
- return K_FLG;
- }
- /************************************************
- / 中斷服務(wù)子程序發(fā)送標(biāo)志
- / char lqSendFlgISR(unsigned char index)
- / index :標(biāo)志量索引
- / 返回值:
- / 1 -- 有更高優(yōu)先級(jí)的任務(wù)就緒,需要執(zhí)行任務(wù)切換
- / 0 -- 不需要執(zhí)行任務(wù)切換
- /************************************************/
- char lqSendFlgISR(unsigned char index)
- {
- char i,j;
- EA=0;
- if(lqFlgData[index] & 0x7F){ /*有任務(wù)在等待這個(gè)標(biāo)志事件*/
- i=lqMaxID;
- for(j=0;j<lqMaxID;++j){
- if(lqFlgData[index] & lqMap[j]){ /*任務(wù)等待這個(gè)標(biāo)志事件*/
- lqTaskState[j] &= ~K_FLG;
- lqTaskState[j] &= ~K_TMO;
- lqTaskTimer[j] = 0;
- lqRdyTbl |= lqMap[j];
- if(j<i){
- i=j;
- }
- }
- }
- lqFlgData[index] = 0;
- if(i<lqCrt){
- EA=1;
- return 1;
- }
- EA=1;
- return 0;
- }
- lqFlgData[index] = 0x80;
- EA=1;
- return 0;
- }
- /********************************************
- / 任務(wù)發(fā)送標(biāo)志事件
- / void lqSendFlg(unsigned char index)
- /********************************************/
- void lqSendFlg(unsigned char index)
- {
- if(lqSendFlgISR(index)){
- lqSche();
- }
- }
- #endif
- #if LQ_SEM_EN
- /************************************************
- / 等待一個(gè)信號(hào)量
- / char lqWaitSem(unsigned char index,unsigned char tmo)
- / index :信號(hào)量索引
- / tmo :超時(shí)等待時(shí)限,如果為0則無限等待
- / 返回值:
- / 信號(hào)量有效返回 K_SEM
- / 在規(guī)定的時(shí)件內(nèi)信號(hào)量未發(fā)生返回 K_TMO
- /************************************************/
- unsigned char lqWaitSem(unsigned char index,unsigned char tmo)
- {
- EA=0;
- lqTaskState[lqCrt] &= 0xF0;
- lqTaskState[lqCrt]|= index; /*因?yàn)楹瘮?shù)不可重,所以存儲(chǔ)信號(hào)量索引*/
- index *= 2;
- if(lqSemData[index]){
- --lqSemData[index];
- EA=1;
- return K_SEM;
- }
- lqRdyTbl &= ~lqMap[lqCrt];
- lqSemData[index+1] |= lqMap[lqCrt];
- lqTaskState[lqCrt] |= K_SEM;
- if(tmo){
- lqTaskState[lqCrt] |= K_TMO;
- lqTaskTimer[lqCrt] = tmo;
- }
- EA=1;
- lqSche();
- EA=0;
- index = 0x0F & lqTaskState[lqCrt];
- if(lqTaskState[lqCrt] & K_SEM){
- lqTaskState[lqCrt] &= ~K_SEM;
- lqTaskState[lqCrt] |= K_TMO;
- lqSemData[index*2+1] &= ~lqMap[lqCrt];
- EA=1;
- return K_TMO;
- }
- EA=1;
- return K_SEM;
- }
- /*********************************************
- / 中斷子程序發(fā)送信號(hào)量
- / char lqSendSemISR(unsigned char index)
- / index :信號(hào)量索引
- / 返回值:
- / 1 -- 有更高優(yōu)先級(jí)的任務(wù)就緒,需要執(zhí)行任務(wù)切換
- / 0 -- 不需要執(zhí)行任務(wù)切換
- /*********************************************/
- char lqSendSemISR(unsigned char index)
- {
- char j;
- EA=0;
- index*=2;
- if(lqSemData[index+1]){
- for(j=0;j<lqMaxID;++j){
- if(lqSemData[index+1] & lqMap[j]){
- break;
- }
- }
- lqSemData[index+1] &= ~lqMap[j];
- lqTaskTimer[j] = 0;
- lqTaskState[j] &= ~K_SEM;
- lqTaskState[j] &= ~K_TMO;
- lqRdyTbl |= lqMap[j];
- if(j<lqCrt){
- EA=1;
- return 1;
- }
- EA=1;
- return 0;
- }
- ++lqSemData[index];
- EA=1;
- return 0;
- }
- /************************************************
- / 任務(wù)發(fā)送信號(hào)量
- / void lqSendSem(unsinged char index)
- /***********************************************/
- void lqSendSem(unsigned char index)
- {
- if(lqSendSemISR(index)){
- lqSche();
- }
- }
- #endif
- #if LQ_MSG_EN
- /*********************************************
- / 等待消息郵箱
- / unsigned char lqWaitMsg(unsigned char index,unsigned char tmo)
- / index :郵箱索引
- / tmo :超時(shí)等待時(shí)限,如果為0則無限等待
- / 郵箱中的值為 0x00~0xFF
- / lqMsgData[2*index+1]的最高為0表示當(dāng)前沒郵件,
- / 否則表示當(dāng)前有郵件
- / 返回值 :
- / 如果在規(guī)定的時(shí)間內(nèi)有消息送到這個(gè)郵箱,則返回這個(gè)消息
- / 如果在規(guī)定的時(shí)間內(nèi)沒有消息送到這個(gè)郵箱,則返回 MSG_TMO
- / MSG_TMO在lq51.h中有定義,如果 MSG_TMO 所代表的值是消息的一部分,
- / 那么在這個(gè)函數(shù)返回后建議執(zhí)行char lqIsTaskTmo(),檢查當(dāng)前任務(wù)
- / 是否從超時(shí)返回
- /********************************************/
- unsigned char lqWaitMsg(unsigned char index,unsigned char tmo)
- {
- EA=0;
- lqTaskState[lqCrt] &= 0xF0;
- lqTaskState[lqCrt] |= index;
- index *= 2;
- if(lqMsgData[index+1] & 0x80){ /*當(dāng)前郵箱有郵件*/
- lqMsgData[index+1] &= 0x7F;
- EA=1;
- return lqMsgData[index];
- }
- lqRdyTbl &= ~lqMap[lqCrt];
- lqMsgData[index+1] |= lqMap[lqCrt];
- lqTaskState[lqCrt] |= K_MSG;
- if(tmo){
- lqTaskState[lqCrt] |= K_TMO;
- lqTaskTimer[lqCrt] = tmo;
- }
- EA=1;
- lqSche();
- EA=0;
- index = lqTaskState[lqCrt] & 0x0F;
- index *= 2;
- if(lqTaskState[lqCrt] & K_MSG){
- lqTaskState[lqCrt] &= ~K_MSG;
- lqTaskState[lqCrt] |= K_TMO;
- lqMsgData[index] = MSG_TMO;
- lqMsgData[index+1] &= ~lqMap[lqCrt];
- }
- lqMsgData[index+1] &= 0x7F;
- EA=1;
- return lqMsgData[index];
- }
- /*******************************************
- / char lqIsMsgEmpty(unsigned char index)
- / index :郵箱索引
- / 返回值:
- / 0 -- 郵箱中有消息
- / 1 -- 郵箱中沒有消息
- /******************************************/
- #if LQ_CHK_MSG_EN
- char lqIsMsgEmpty(unsigned char index)
- {
- EA=0;
- if(lqMsgData[index*2+1] & 0x80){
- EA=1;
- return 0; /*郵箱不為空,郵箱中有消息*/
- }
- EA=1;
- return 1; /*郵箱為空,郵箱中無消息*/
- }
- #endif
- /*******************************************
- / 中斷子程序發(fā)送郵件
- / char lqSendMsgISR(unsigned char index,unsigned char Msg)
- / index :郵箱索引
- / Msg :被發(fā)送的消息
- / 如果郵箱中已經(jīng)存在消息,原來的消息不會(huì)被覆蓋,函數(shù)之間返回
- / 返回值:
- / 1 -- 有更高優(yōu)先級(jí)的任務(wù)就緒,需要執(zhí)行任務(wù)切換
- / 0 -- 不需要執(zhí)行任務(wù)切換
- /*******************************************/
- char lqSendMsgISR(unsigned char index,unsigned char Msg)
- {
- EA=0;
- index *= 2;
- if(lqMsgData[index+1] & 0x80){
- EA=1;
- return 0; /*郵箱不為空*/
- }
- lqMsgData[index] = Msg;
- ++index;
- lqMsgData[index] |= 0x80;
- if(lqMsgData[index] & 0x7F){ /*有任務(wù)在等待這個(gè)郵件*/
- for(Msg=0;Msg<lqMaxID;++Msg){
- if(lqMsgData[index] & lqMap[Msg]){
- break;
- }
- }
- lqMsgData[index] &= ~lqMap[Msg];
- lqTaskState[Msg] &= ~K_MSG;
- lqRdyTbl |= lqMap[Msg];
- if(Msg < lqCrt){
- EA=1;
- return 1;
- }
- }
- EA = 1;
- return 0;
- }
- /********************************************
- / 任務(wù)發(fā)送郵件
- / void lqSendMsg(unsigned char index,unsigned char Msg)
- / index :郵箱索引
- / Msg :被發(fā)送的消息
- /*******************************************/
- void lqSendMsg(unsigned char index,unsigned char Msg)
- {
- if(lqSendMsgISR(index,Msg)){
- lqSche();
- }
- }
- #endif
- #if LQ_TASK_TMO_CHK_EN
- /***********************************************
- / 任務(wù)超時(shí)返回檢查
- / char lqIsTaskTmo()
- / 如果當(dāng)前任務(wù)是超時(shí)返回,那么任務(wù)狀態(tài)(lqTaskState)的B_TMO位置位,否則該標(biāo)志位被清零
- / 一般情況下只針對(duì)郵箱事件返回后做超時(shí)檢查
- / 返回值:
- / 1 -- 當(dāng)前任務(wù)是超時(shí)返回
- / 0 -- 當(dāng)前任務(wù)不是超時(shí)返回
- /************************************************/
- char lqIsTaskTmo()
- {
- if(lqTaskState[lqCrt] & K_TMO){
- return 1;
- }
- return 0;
- }
- #endif
復(fù)制代碼
所有資料51hei提供下載:
lq51-master.zip
(216.94 KB, 下載次數(shù): 18)
2019-11-22 20:53 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|