uC/OS-II源码分析(二)
生活随笔
收集整理的這篇文章主要介紹了
uC/OS-II源码分析(二)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在真正開始分析源代碼前,先來看使用uC/OS-II的三個例子
#define??N_TASKS????????????????????????10???????/*?任務數*/
OS_STK????????TaskStk[N_TASKS][TASK_STK_SIZE];????????/*任務堆棧*/
OS_STK????????TaskStartStk[TASK_STK_SIZE];????????????//開始任務的堆棧????
char??????????TaskData[N_TASKS];??????????????????????/*傳給每個任務的數據*/
OS_EVENT?????*RandomSem;????????????????????????????//互斥型信號量
void??main?(void)
{
????PC_DispClrScr(DISP_FGND_WHITE?+?DISP_BGND_BLACK);??????/*清空屏幕*/
????OSInit();??????????????????????????????????????????????/*?初始化uC/OS-II*/
????PC_DOSSaveReturn();????????????????????????????????????/*?保存環境以便稍后可以返回DOS環境*/
????PC_VectSet(uCOS,?OSCtxSw);?????????????????????????????/*設置uC/OS-II的切換處理函數*/
????RandomSem???=?OSSemCreate(1);??????????????????????????/*?建立一個信號量*/
????OSTaskCreate(TaskStart,?(void?*)0,?&TaskStartStk[TASK_STK_SIZE?-?1],?0);//創建第一個任務,優先級設置為最大值
????OSStart();?????????????????????????????????????????????/*?開始多任務*/
}
void??TaskStart?(void?*pdata)
{
#if?OS_CRITICAL_METHOD?==?3????????????????????????????????/*?為CPU的狀態寄存器分配內存*/
????OS_CPU_SR??cpu_sr;
#endif
????char???????s[100];
????INT16S?????key;
????pdata?=?pdata;?????????????????????????????????????????/*?這步是為了防止編譯錯誤*/
????TaskStartDispInit();???????????????????????????????????/*?初始化顯示屏*/
????OS_ENTER_CRITICAL();
????PC_VectSet(0x08,?OSTickISR);???????????????????????????/*替換機器的時鐘中斷函數為uC/OS-II所需要的中斷函數*/
????PC_SetTickRate(OS_TICKS_PER_SEC);??????????????????????/*?調整時鐘頻率*/
????OS_EXIT_CRITICAL();
????OSStatInit();??????????????????????????????????????????/*?初始化統計任務*/
????TaskStartCreateTasks();????????????????????????????????/*創建其他任務*/
????for?(;;)?{
????????TaskStartDisp();????????????????????????????????
????????if?(PC_GetKey(&key)?==?TRUE)?{?????????????????????/*?是否按鍵*/
????????????if?(key?==?0x1B)?{?????????????????????????????/*?ESCAPE按下了*/
????????????????PC_DOSReturn();????????????????????????????/*?返回DOS*/
????????????}
????????}
????????OSCtxSwCtr?=?0;????????????????????????????????????/*?切換次數計數器清零*/
????????OSTimeDlyHMSM(0,?0,?1,?0);?????????????????????????/*掛起秒,讓給其他任務運行*/
????}
}
static??void??TaskStartCreateTasks?(void)
{
????INT8U??i;
????for?(i?=?0;?i?<?N_TASKS;?i++)?{????????????????????????/*?創建N_TASKS個任務*/
????????TaskData[i]?=?'0'?+?i;?????????????????????????????/*?每個任務顯示其數據*/
????????OSTaskCreate(Task,?(void?*)&TaskData[i],?&TaskStk[i][TASK_STK_SIZE?-?1],?i?+?1);
????}
}
void??Task?(void?*pdata)
{
????INT8U??x;
????INT8U??y;
????INT8U??err;
????for?(;;)?{
????????OSSemPend(RandomSem,?0,?&err);???????????/*?獲取信號量*/
????????x?=?random(80);??????????????????????????/*?計算X坐標*/
????????y?=?random(16);??????????????????????????/*?計算Y坐標*/
????????OSSemPost(RandomSem);????????????????????/*?釋放信號量*/
????????/*?Display?the?task?number?on?the?screen??????????????*/
????????PC_DispChar(x,?y?+?5,?*(char?*)pdata,?DISP_FGND_BLACK?+?DISP_BGND_LIGHT_GRAY);
????????OSTimeDly(1);????????????????????????????/*?掛起秒,讓給其他任務運行*/
????}
}
#define??????????TASK_STK_SIZE?????512???????????????
#define??????????TASK_START_ID???????0????????????????/*?任務ID*/
#define??????????TASK_CLK_ID?????????1
#define??????????TASK_1_ID???????????2
#define??????????TASK_2_ID???????????3
#define??????????TASK_3_ID???????????4
#define??????????TASK_4_ID???????????5
#define??????????TASK_5_ID???????????6
#define??????????TASK_START_PRIO????10????????????????/*?任務優先級*/
#define??????????TASK_CLK_PRIO??????11
#define??????????TASK_1_PRIO????????12
#define??????????TASK_2_PRIO????????13
#define??????????TASK_3_PRIO????????14
#define??????????TASK_4_PRIO????????15
#define??????????TASK_5_PRIO????????16
OS_STK????????TaskStartStk[TASK_STK_SIZE];????????????
OS_STK????????TaskClkStk[TASK_STK_SIZE];?????????????
OS_STK????????Task1Stk[TASK_STK_SIZE];????????????????
OS_STK????????Task2Stk[TASK_STK_SIZE];????????????????
OS_STK????????Task3Stk[TASK_STK_SIZE];???????????????
OS_STK????????Task4Stk[TASK_STK_SIZE];??????????????
OS_STK????????Task5Stk[TASK_STK_SIZE];???????????????
OS_EVENT?????*AckMbox;????????????????????????????????/*?任務和使用的消息郵箱*/
OS_EVENT?????*TxMbox;
void?main?(void)
{
????OS_STK?*ptos;
????OS_STK?*pbos;
????INT32U??size;
????PC_DispClrScr(DISP_FGND_WHITE);???????????????????????
????OSInit();????????????????????????????????????????????
????PC_DOSSaveReturn();??????????????????????????????????
????PC_VectSet(uCOS,?OSCtxSw);????????????????????????????
????PC_ElapsedInit();?????????????????????????????????????
????ptos????????=?&TaskStartStk[TASK_STK_SIZE?-?1];????????
????pbos????????=?&TaskStartStk[0];
????size????????=?TASK_STK_SIZE;
????OSTaskStkInit_FPE_x86(&ptos,?&pbos,?&size);????????????
????OSTaskCreateExt(TaskStart,
????????(void?*)0,
????????ptos,
????????TASK_START_PRIO,
????????TASK_START_ID,
????????pbos,
????????size,
????????(void?*)0,
????????OS_TASK_OPT_STK_CHK?|?OS_TASK_OPT_STK_CLR);
????OSStart();?????????????????????????????????????????????
}
void??TaskStart?(void?*pdata)
{
#if?OS_CRITICAL_METHOD?==?3???????????????????????????????
????OS_CPU_SR??cpu_sr;
#endif
????INT16S?????key;
????pdata?=?pdata;???????????????????????????????????????
????TaskStartDispInit();????????????????????????????????
????OS_ENTER_CRITICAL();????????????????????????????????
????PC_VectSet(0x08,?OSTickISR);
????PC_SetTickRate(OS_TICKS_PER_SEC);????????????????????
????OS_EXIT_CRITICAL();
????OSStatInit();??????????????????????????????????????????
????AckMbox?=?OSMboxCreate((void?*)0);?????????????????????/*?創建兩個消息郵箱*/
????TxMbox??=?OSMboxCreate((void?*)0);
????TaskStartCreateTasks();???????????????????????????????
????for?(;;)?{
????????TaskStartDisp();?????????????????????????????????
????????if?(PC_GetKey(&key))?{???????????????????????????
????????????if?(key?==?0x1B)?{????????????????????????????
????????????????PC_DOSReturn();???????????????????????????
????????????}
????????}
????????OSCtxSwCtr?=?0;????????????????????????????????????
????????OSTimeDly(OS_TICKS_PER_SEC);??????????????????????
????}
}
void??Task1?(void?*pdata)
{
????INT8U???????err;
????OS_STK_DATA?data;???????????????????????/*?任務堆棧數據*/
????INT16U??????time;??????????????????????
????INT8U???????i;
????char????????s[80];
????pdata?=?pdata;
????for?(;;)?{
????????for?(i?=?0;?i?<?7;?i++)?{
????????????PC_ElapsedStart();
????????????err??=?OSTaskStkChk(TASK_START_PRIO?+?i,?&data);//執行堆棧檢查
????????????time?=?PC_ElapsedStop();
????????????if?(err?==?OS_NO_ERR)?{
????????????????sprintf(s,?"%4ld????????%4ld????????%4ld????????%6d",
????????????????????data.OSFree?+?data.OSUsed,
????????????????????data.OSFree,
????????????????????data.OSUsed,
????????????????????time);
????????????????PC_DispStr(19,?12?+?i,?s,?DISP_FGND_BLACK?+?DISP_BGND_LIGHT_GRAY);
????????????}
????????}
????????OSTimeDlyHMSM(0,?0,?0,?100);???????????????????????/*?掛起mS*/
????}
}
void??Task4?(void?*data)
{
????char???txmsg;
????INT8U??err;
????data??=?data;
????txmsg?=?'A';
????for?(;;)?{
????????OSMboxPost(TxMbox,?(void?*)&txmsg);??????/*?發消息給Task?#5*/
????????OSMboxPend(AckMbox,?0,?&err);????????????/*?等待Task?#5的應答消息*/
????????txmsg++;?????????????????????????????????/*下一個要發的消息數據*/
????????if?(txmsg?==?'Z')?{
????????????txmsg?=?'A';?????????????????????????/*?循環發送A-Z*/
????????}
????}
}
void??Task5?(void?*data)
{
????char??*rxmsg;
????INT8U??err;
????data?=?data;
????for?(;;)?{
????????rxmsg?=?(char?*)OSMboxPend(TxMbox,?0,?&err);?/*?等待來自Task?#4的數據*/
????????PC_DispChar(70,?18,?*rxmsg,?DISP_FGND_YELLOW?+?DISP_BGND_BLUE);
????????OSTimeDlyHMSM(0,?0,?1,?0);?/*?掛起秒,讓給其他任務運行*/
????????OSMboxPost(AckMbox,?(void?*)1);?/*發送接收到數據的應答消息*/
????}
}
#define??????????TASK_START_ID???????0???????????????
#define??????????TASK_CLK_ID?????????1
#define??????????TASK_1_ID???????????2
#define??????????TASK_2_ID???????????3
#define??????????TASK_3_ID???????????4
#define??????????TASK_4_ID???????????5
#define??????????TASK_5_ID???????????6
#define??????????TASK_START_PRIO????10???????????????
#define??????????TASK_CLK_PRIO??????11
#define??????????TASK_1_PRIO????????12
#define??????????TASK_2_PRIO????????13
#define??????????TASK_3_PRIO????????14
#define??????????TASK_4_PRIO????????15
#define??????????TASK_5_PRIO????????16
#define??????????MSG_QUEUE_SIZE?????20????????????????/*?消息隊列大小*/
typedef?struct?{
????char????TaskName[30];
????INT16U??TaskCtr;
????INT16U??TaskExecTime;
????INT32U??TaskTotExecTime;
}?TASK_USER_DATA;
OS_STK??????????TaskStartStk[TASK_STK_SIZE];?????????
OS_STK??????????TaskClkStk[TASK_STK_SIZE];????????????
OS_STK??????????Task1Stk[TASK_STK_SIZE];??????????????
OS_STK??????????Task2Stk[TASK_STK_SIZE];????????????
OS_STK??????????Task3Stk[TASK_STK_SIZE];?????????????
OS_STK??????????Task4Stk[TASK_STK_SIZE];????????????
OS_STK??????????Task5Stk[TASK_STK_SIZE];?????????????
TASK_USER_DATA??TaskUserData[7];
OS_EVENT???????*MsgQueue;?????????????????????????????/*消息隊列指針*/
void???????????*MsgQueueTbl[20];??????????????????????/*消息存儲*/
void??main?(void)
{
????PC_DispClrScr(DISP_BGND_BLACK);????????????????????????
????OSInit();????????????????????????????????????????????
????PC_DOSSaveReturn();????????????????????????????????????
????PC_VectSet(uCOS,?OSCtxSw);????????????????????????????
????PC_ElapsedInit();??????????????????????????????????????
????strcpy(TaskUserData[TASK_START_ID].TaskName,?"StartTask");
????OSTaskCreateExt(TaskStart,
????????(void?*)0,
????????&TaskStartStk[TASK_STK_SIZE?-?1],
????????TASK_START_PRIO,
????????TASK_START_ID,
????????&TaskStartStk[0],
????????TASK_STK_SIZE,
????????&TaskUserData[TASK_START_ID],
????????0);
????OSStart();??????????????????????????????????????????
}
void??TaskStart?(void?*pdata)
{
#if?OS_CRITICAL_METHOD?==?3????????????????????????????????
????OS_CPU_SR??cpu_sr;
#endif
????INT16S?????key;
????pdata?=?pdata;??????????????????????????????????????
????TaskStartDispInit();????????????????????????????????
????OS_ENTER_CRITICAL();??????????????????????????????????
????PC_VectSet(0x08,?OSTickISR);
????PC_SetTickRate(OS_TICKS_PER_SEC);????????????????????
????OS_EXIT_CRITICAL();
????OSStatInit();?????????????????????????????????????????
????MsgQueue?=?OSQCreate(&MsgQueueTbl[0],?MSG_QUEUE_SIZE);?/*創建消息隊列,大小為*/
????TaskStartCreateTasks();
????for?(;;)?{
????????TaskStartDisp();???????????????????????????????
????????if?(PC_GetKey(&key))?{???????????????????????????
????????????if?(key?==?0x1B)?{?????????????????????????
????????????????PC_DOSReturn();?????????????????????????
????????????}
????????}
????????OSCtxSwCtr?=?0;???????????????????????????????????
????????OSTimeDly(OS_TICKS_PER_SEC);??????????????????????
????}
}
void??Task1?(void?*pdata)
{
????char??*msg;
????INT8U??err;
????pdata?=?pdata;
????for?(;;)?{
????????msg?=?(char?*)OSQPend(MsgQueue,?0,?&err);//從消息隊列中取消息
????????PC_DispStr(70,?13,?msg,?DISP_FGND_YELLOW?+?DISP_BGND_BLUE);
????????OSTimeDlyHMSM(0,?0,?0,?100);
????}
}
void??Task2?(void?*pdata)
{
????char??msg[20];
????pdata?=?pdata;
????strcpy(&msg[0],?"Task?2");
????for?(;;)?{
????????OSQPost(MsgQueue,?(void?*)&msg[0]);//發送消息到隊列中
????????OSTimeDlyHMSM(0,?0,?0,?500);
????}
}
void??Task3?(void?*pdata)
{
????char??msg[20];
????pdata?=?pdata;
????strcpy(&msg[0],?"Task?3");
????for?(;;)?{
????????OSQPost(MsgQueue,?(void?*)&msg[0]);//發送消息到隊列中
????????OSTimeDlyHMSM(0,?0,?0,?500);
????}
}
void??Task4?(void?*pdata)
{
????char??msg[20];
????pdata?=?pdata;
????strcpy(&msg[0],?"Task?4");
????for?(;;)?{
????????OSQPost(MsgQueue,?(void?*)&msg[0]);//發送消息到隊列中
????????OSTimeDlyHMSM(0,?0,?0,?500);
????}
}
void??OSTaskStatHook?(void)
{
????char????s[80];
????INT8U???i;
????INT32U??total;
????INT8U???pct;
????total?=?0L;??????????????????????????????????????????/*?Totalize?TOT.?EXEC.?TIME?for?each?task?
????for?(i?=?0;?i?<?7;?i++)?{
????????total?+=?TaskUserData[i].TaskTotExecTime;
????????DispTaskStat(i);?????????????????????????????????/*?Display?task?data??????????????????????
????}
????if?(total?>?0)?{
????????for?(i?=?0;?i?<?7;?i++)?{????????????????????????/*?Derive?percentage?of?each?task?????????*/
????????????pct?=?100?*?TaskUserData[i].TaskTotExecTime?/?total;
????????????sprintf(s,?"%3d?%%",?pct);
????????????PC_DispStr(62,?i?+?11,?s,?DISP_FGND_BLACK?+?DISP_BGND_LIGHT_GRAY);
????????}
????}
????if?(total?>?1000000000L)?{???????????????????????????/*?Reset?total?time?counters?at?1?billion?
????????for?(i?=?0;?i?<?7;?i++)?{
????????????TaskUserData[i].TaskTotExecTime?=?0L;
????????}
????}
}
void??OSTaskSwHook?(void)
{
????INT16U???????????time;
????TASK_USER_DATA??*puser;
????time??=?PC_ElapsedStop();????????????????????/*?This?task?is?done??????????????????????????????????
????PC_ElapsedStart();???????????????????????????/*?Start?for?next?task????????????????????????????????
????puser?=?OSTCBCur->OSTCBExtPtr;???????????????/*?Point?to?used?data?????????????????????????????????
????if?(puser?!=?(TASK_USER_DATA?*)0)?{
????????puser->TaskCtr++;????????????????????????/*?Increment?task?counter?????????????????????????????
????????puser->TaskExecTime?????=?time;??????????/*?Update?the?task's?execution?time???????????????????
????????puser->TaskTotExecTime?+=?time;??????????/*?Update?the?task's?total?execution?time?????????????
????}
}
1)使用信號量
?
#define??TASK_STK_SIZE?????????????????512???????/*?每個任務堆棧的大小(以字計算)*/#define??N_TASKS????????????????????????10???????/*?任務數*/
OS_STK????????TaskStk[N_TASKS][TASK_STK_SIZE];????????/*任務堆棧*/
OS_STK????????TaskStartStk[TASK_STK_SIZE];????????????//開始任務的堆棧????
char??????????TaskData[N_TASKS];??????????????????????/*傳給每個任務的數據*/
OS_EVENT?????*RandomSem;????????????????????????????//互斥型信號量
void??main?(void)
{
????PC_DispClrScr(DISP_FGND_WHITE?+?DISP_BGND_BLACK);??????/*清空屏幕*/
????OSInit();??????????????????????????????????????????????/*?初始化uC/OS-II*/
????PC_DOSSaveReturn();????????????????????????????????????/*?保存環境以便稍后可以返回DOS環境*/
????PC_VectSet(uCOS,?OSCtxSw);?????????????????????????????/*設置uC/OS-II的切換處理函數*/
????RandomSem???=?OSSemCreate(1);??????????????????????????/*?建立一個信號量*/
????OSTaskCreate(TaskStart,?(void?*)0,?&TaskStartStk[TASK_STK_SIZE?-?1],?0);//創建第一個任務,優先級設置為最大值
????OSStart();?????????????????????????????????????????????/*?開始多任務*/
}
void??TaskStart?(void?*pdata)
{
#if?OS_CRITICAL_METHOD?==?3????????????????????????????????/*?為CPU的狀態寄存器分配內存*/
????OS_CPU_SR??cpu_sr;
#endif
????char???????s[100];
????INT16S?????key;
????pdata?=?pdata;?????????????????????????????????????????/*?這步是為了防止編譯錯誤*/
????TaskStartDispInit();???????????????????????????????????/*?初始化顯示屏*/
????OS_ENTER_CRITICAL();
????PC_VectSet(0x08,?OSTickISR);???????????????????????????/*替換機器的時鐘中斷函數為uC/OS-II所需要的中斷函數*/
????PC_SetTickRate(OS_TICKS_PER_SEC);??????????????????????/*?調整時鐘頻率*/
????OS_EXIT_CRITICAL();
????OSStatInit();??????????????????????????????????????????/*?初始化統計任務*/
????TaskStartCreateTasks();????????????????????????????????/*創建其他任務*/
????for?(;;)?{
????????TaskStartDisp();????????????????????????????????
????????if?(PC_GetKey(&key)?==?TRUE)?{?????????????????????/*?是否按鍵*/
????????????if?(key?==?0x1B)?{?????????????????????????????/*?ESCAPE按下了*/
????????????????PC_DOSReturn();????????????????????????????/*?返回DOS*/
????????????}
????????}
????????OSCtxSwCtr?=?0;????????????????????????????????????/*?切換次數計數器清零*/
????????OSTimeDlyHMSM(0,?0,?1,?0);?????????????????????????/*掛起秒,讓給其他任務運行*/
????}
}
static??void??TaskStartCreateTasks?(void)
{
????INT8U??i;
????for?(i?=?0;?i?<?N_TASKS;?i++)?{????????????????????????/*?創建N_TASKS個任務*/
????????TaskData[i]?=?'0'?+?i;?????????????????????????????/*?每個任務顯示其數據*/
????????OSTaskCreate(Task,?(void?*)&TaskData[i],?&TaskStk[i][TASK_STK_SIZE?-?1],?i?+?1);
????}
}
void??Task?(void?*pdata)
{
????INT8U??x;
????INT8U??y;
????INT8U??err;
????for?(;;)?{
????????OSSemPend(RandomSem,?0,?&err);???????????/*?獲取信號量*/
????????x?=?random(80);??????????????????????????/*?計算X坐標*/
????????y?=?random(16);??????????????????????????/*?計算Y坐標*/
????????OSSemPost(RandomSem);????????????????????/*?釋放信號量*/
????????/*?Display?the?task?number?on?the?screen??????????????*/
????????PC_DispChar(x,?y?+?5,?*(char?*)pdata,?DISP_FGND_BLACK?+?DISP_BGND_LIGHT_GRAY);
????????OSTimeDly(1);????????????????????????????/*?掛起秒,讓給其他任務運行*/
????}
}
?
?
2)使用消息郵箱
?
#define??????????TASK_STK_SIZE?????512???????????????
#define??????????TASK_START_ID???????0????????????????/*?任務ID*/
#define??????????TASK_CLK_ID?????????1
#define??????????TASK_1_ID???????????2
#define??????????TASK_2_ID???????????3
#define??????????TASK_3_ID???????????4
#define??????????TASK_4_ID???????????5
#define??????????TASK_5_ID???????????6
#define??????????TASK_START_PRIO????10????????????????/*?任務優先級*/
#define??????????TASK_CLK_PRIO??????11
#define??????????TASK_1_PRIO????????12
#define??????????TASK_2_PRIO????????13
#define??????????TASK_3_PRIO????????14
#define??????????TASK_4_PRIO????????15
#define??????????TASK_5_PRIO????????16
OS_STK????????TaskStartStk[TASK_STK_SIZE];????????????
OS_STK????????TaskClkStk[TASK_STK_SIZE];?????????????
OS_STK????????Task1Stk[TASK_STK_SIZE];????????????????
OS_STK????????Task2Stk[TASK_STK_SIZE];????????????????
OS_STK????????Task3Stk[TASK_STK_SIZE];???????????????
OS_STK????????Task4Stk[TASK_STK_SIZE];??????????????
OS_STK????????Task5Stk[TASK_STK_SIZE];???????????????
OS_EVENT?????*AckMbox;????????????????????????????????/*?任務和使用的消息郵箱*/
OS_EVENT?????*TxMbox;
void?main?(void)
{
????OS_STK?*ptos;
????OS_STK?*pbos;
????INT32U??size;
????PC_DispClrScr(DISP_FGND_WHITE);???????????????????????
????OSInit();????????????????????????????????????????????
????PC_DOSSaveReturn();??????????????????????????????????
????PC_VectSet(uCOS,?OSCtxSw);????????????????????????????
????PC_ElapsedInit();?????????????????????????????????????
????ptos????????=?&TaskStartStk[TASK_STK_SIZE?-?1];????????
????pbos????????=?&TaskStartStk[0];
????size????????=?TASK_STK_SIZE;
????OSTaskStkInit_FPE_x86(&ptos,?&pbos,?&size);????????????
????OSTaskCreateExt(TaskStart,
????????(void?*)0,
????????ptos,
????????TASK_START_PRIO,
????????TASK_START_ID,
????????pbos,
????????size,
????????(void?*)0,
????????OS_TASK_OPT_STK_CHK?|?OS_TASK_OPT_STK_CLR);
????OSStart();?????????????????????????????????????????????
}
void??TaskStart?(void?*pdata)
{
#if?OS_CRITICAL_METHOD?==?3???????????????????????????????
????OS_CPU_SR??cpu_sr;
#endif
????INT16S?????key;
????pdata?=?pdata;???????????????????????????????????????
????TaskStartDispInit();????????????????????????????????
????OS_ENTER_CRITICAL();????????????????????????????????
????PC_VectSet(0x08,?OSTickISR);
????PC_SetTickRate(OS_TICKS_PER_SEC);????????????????????
????OS_EXIT_CRITICAL();
????OSStatInit();??????????????????????????????????????????
????AckMbox?=?OSMboxCreate((void?*)0);?????????????????????/*?創建兩個消息郵箱*/
????TxMbox??=?OSMboxCreate((void?*)0);
????TaskStartCreateTasks();???????????????????????????????
????for?(;;)?{
????????TaskStartDisp();?????????????????????????????????
????????if?(PC_GetKey(&key))?{???????????????????????????
????????????if?(key?==?0x1B)?{????????????????????????????
????????????????PC_DOSReturn();???????????????????????????
????????????}
????????}
????????OSCtxSwCtr?=?0;????????????????????????????????????
????????OSTimeDly(OS_TICKS_PER_SEC);??????????????????????
????}
}
void??Task1?(void?*pdata)
{
????INT8U???????err;
????OS_STK_DATA?data;???????????????????????/*?任務堆棧數據*/
????INT16U??????time;??????????????????????
????INT8U???????i;
????char????????s[80];
????pdata?=?pdata;
????for?(;;)?{
????????for?(i?=?0;?i?<?7;?i++)?{
????????????PC_ElapsedStart();
????????????err??=?OSTaskStkChk(TASK_START_PRIO?+?i,?&data);//執行堆棧檢查
????????????time?=?PC_ElapsedStop();
????????????if?(err?==?OS_NO_ERR)?{
????????????????sprintf(s,?"%4ld????????%4ld????????%4ld????????%6d",
????????????????????data.OSFree?+?data.OSUsed,
????????????????????data.OSFree,
????????????????????data.OSUsed,
????????????????????time);
????????????????PC_DispStr(19,?12?+?i,?s,?DISP_FGND_BLACK?+?DISP_BGND_LIGHT_GRAY);
????????????}
????????}
????????OSTimeDlyHMSM(0,?0,?0,?100);???????????????????????/*?掛起mS*/
????}
}
void??Task4?(void?*data)
{
????char???txmsg;
????INT8U??err;
????data??=?data;
????txmsg?=?'A';
????for?(;;)?{
????????OSMboxPost(TxMbox,?(void?*)&txmsg);??????/*?發消息給Task?#5*/
????????OSMboxPend(AckMbox,?0,?&err);????????????/*?等待Task?#5的應答消息*/
????????txmsg++;?????????????????????????????????/*下一個要發的消息數據*/
????????if?(txmsg?==?'Z')?{
????????????txmsg?=?'A';?????????????????????????/*?循環發送A-Z*/
????????}
????}
}
void??Task5?(void?*data)
{
????char??*rxmsg;
????INT8U??err;
????data?=?data;
????for?(;;)?{
????????rxmsg?=?(char?*)OSMboxPend(TxMbox,?0,?&err);?/*?等待來自Task?#4的數據*/
????????PC_DispChar(70,?18,?*rxmsg,?DISP_FGND_YELLOW?+?DISP_BGND_BLUE);
????????OSTimeDlyHMSM(0,?0,?1,?0);?/*?掛起秒,讓給其他任務運行*/
????????OSMboxPost(AckMbox,?(void?*)1);?/*發送接收到數據的應答消息*/
????}
}
?
運行結果:
?
3)使用消息隊列
?
#define??????????TASK_STK_SIZE?????512???????????????#define??????????TASK_START_ID???????0???????????????
#define??????????TASK_CLK_ID?????????1
#define??????????TASK_1_ID???????????2
#define??????????TASK_2_ID???????????3
#define??????????TASK_3_ID???????????4
#define??????????TASK_4_ID???????????5
#define??????????TASK_5_ID???????????6
#define??????????TASK_START_PRIO????10???????????????
#define??????????TASK_CLK_PRIO??????11
#define??????????TASK_1_PRIO????????12
#define??????????TASK_2_PRIO????????13
#define??????????TASK_3_PRIO????????14
#define??????????TASK_4_PRIO????????15
#define??????????TASK_5_PRIO????????16
#define??????????MSG_QUEUE_SIZE?????20????????????????/*?消息隊列大小*/
typedef?struct?{
????char????TaskName[30];
????INT16U??TaskCtr;
????INT16U??TaskExecTime;
????INT32U??TaskTotExecTime;
}?TASK_USER_DATA;
OS_STK??????????TaskStartStk[TASK_STK_SIZE];?????????
OS_STK??????????TaskClkStk[TASK_STK_SIZE];????????????
OS_STK??????????Task1Stk[TASK_STK_SIZE];??????????????
OS_STK??????????Task2Stk[TASK_STK_SIZE];????????????
OS_STK??????????Task3Stk[TASK_STK_SIZE];?????????????
OS_STK??????????Task4Stk[TASK_STK_SIZE];????????????
OS_STK??????????Task5Stk[TASK_STK_SIZE];?????????????
TASK_USER_DATA??TaskUserData[7];
OS_EVENT???????*MsgQueue;?????????????????????????????/*消息隊列指針*/
void???????????*MsgQueueTbl[20];??????????????????????/*消息存儲*/
void??main?(void)
{
????PC_DispClrScr(DISP_BGND_BLACK);????????????????????????
????OSInit();????????????????????????????????????????????
????PC_DOSSaveReturn();????????????????????????????????????
????PC_VectSet(uCOS,?OSCtxSw);????????????????????????????
????PC_ElapsedInit();??????????????????????????????????????
????strcpy(TaskUserData[TASK_START_ID].TaskName,?"StartTask");
????OSTaskCreateExt(TaskStart,
????????(void?*)0,
????????&TaskStartStk[TASK_STK_SIZE?-?1],
????????TASK_START_PRIO,
????????TASK_START_ID,
????????&TaskStartStk[0],
????????TASK_STK_SIZE,
????????&TaskUserData[TASK_START_ID],
????????0);
????OSStart();??????????????????????????????????????????
}
void??TaskStart?(void?*pdata)
{
#if?OS_CRITICAL_METHOD?==?3????????????????????????????????
????OS_CPU_SR??cpu_sr;
#endif
????INT16S?????key;
????pdata?=?pdata;??????????????????????????????????????
????TaskStartDispInit();????????????????????????????????
????OS_ENTER_CRITICAL();??????????????????????????????????
????PC_VectSet(0x08,?OSTickISR);
????PC_SetTickRate(OS_TICKS_PER_SEC);????????????????????
????OS_EXIT_CRITICAL();
????OSStatInit();?????????????????????????????????????????
????MsgQueue?=?OSQCreate(&MsgQueueTbl[0],?MSG_QUEUE_SIZE);?/*創建消息隊列,大小為*/
????TaskStartCreateTasks();
????for?(;;)?{
????????TaskStartDisp();???????????????????????????????
????????if?(PC_GetKey(&key))?{???????????????????????????
????????????if?(key?==?0x1B)?{?????????????????????????
????????????????PC_DOSReturn();?????????????????????????
????????????}
????????}
????????OSCtxSwCtr?=?0;???????????????????????????????????
????????OSTimeDly(OS_TICKS_PER_SEC);??????????????????????
????}
}
void??Task1?(void?*pdata)
{
????char??*msg;
????INT8U??err;
????pdata?=?pdata;
????for?(;;)?{
????????msg?=?(char?*)OSQPend(MsgQueue,?0,?&err);//從消息隊列中取消息
????????PC_DispStr(70,?13,?msg,?DISP_FGND_YELLOW?+?DISP_BGND_BLUE);
????????OSTimeDlyHMSM(0,?0,?0,?100);
????}
}
void??Task2?(void?*pdata)
{
????char??msg[20];
????pdata?=?pdata;
????strcpy(&msg[0],?"Task?2");
????for?(;;)?{
????????OSQPost(MsgQueue,?(void?*)&msg[0]);//發送消息到隊列中
????????OSTimeDlyHMSM(0,?0,?0,?500);
????}
}
void??Task3?(void?*pdata)
{
????char??msg[20];
????pdata?=?pdata;
????strcpy(&msg[0],?"Task?3");
????for?(;;)?{
????????OSQPost(MsgQueue,?(void?*)&msg[0]);//發送消息到隊列中
????????OSTimeDlyHMSM(0,?0,?0,?500);
????}
}
void??Task4?(void?*pdata)
{
????char??msg[20];
????pdata?=?pdata;
????strcpy(&msg[0],?"Task?4");
????for?(;;)?{
????????OSQPost(MsgQueue,?(void?*)&msg[0]);//發送消息到隊列中
????????OSTimeDlyHMSM(0,?0,?0,?500);
????}
}
void??OSTaskStatHook?(void)
{
????char????s[80];
????INT8U???i;
????INT32U??total;
????INT8U???pct;
????total?=?0L;??????????????????????????????????????????/*?Totalize?TOT.?EXEC.?TIME?for?each?task?
????for?(i?=?0;?i?<?7;?i++)?{
????????total?+=?TaskUserData[i].TaskTotExecTime;
????????DispTaskStat(i);?????????????????????????????????/*?Display?task?data??????????????????????
????}
????if?(total?>?0)?{
????????for?(i?=?0;?i?<?7;?i++)?{????????????????????????/*?Derive?percentage?of?each?task?????????*/
????????????pct?=?100?*?TaskUserData[i].TaskTotExecTime?/?total;
????????????sprintf(s,?"%3d?%%",?pct);
????????????PC_DispStr(62,?i?+?11,?s,?DISP_FGND_BLACK?+?DISP_BGND_LIGHT_GRAY);
????????}
????}
????if?(total?>?1000000000L)?{???????????????????????????/*?Reset?total?time?counters?at?1?billion?
????????for?(i?=?0;?i?<?7;?i++)?{
????????????TaskUserData[i].TaskTotExecTime?=?0L;
????????}
????}
}
void??OSTaskSwHook?(void)
{
????INT16U???????????time;
????TASK_USER_DATA??*puser;
????time??=?PC_ElapsedStop();????????????????????/*?This?task?is?done??????????????????????????????????
????PC_ElapsedStart();???????????????????????????/*?Start?for?next?task????????????????????????????????
????puser?=?OSTCBCur->OSTCBExtPtr;???????????????/*?Point?to?used?data?????????????????????????????????
????if?(puser?!=?(TASK_USER_DATA?*)0)?{
????????puser->TaskCtr++;????????????????????????/*?Increment?task?counter?????????????????????????????
????????puser->TaskExecTime?????=?time;??????????/*?Update?the?task's?execution?time???????????????????
????????puser->TaskTotExecTime?+=?time;??????????/*?Update?the?task's?total?execution?time?????????????
????}
}
?
運行結果:
作者:洞庭散人
出處:http://phinecos.cnblogs.com/
本博客遵從Creative Commons Attribution 3.0 License,若用于非商業目的,您可以自由轉載,但請保留原作者信息和文章鏈接URL。轉載于:https://www.cnblogs.com/xumaojun/p/8541665.html
總結
以上是生活随笔為你收集整理的uC/OS-II源码分析(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 李宏毅2020机器学习资料汇总
- 下一篇: Maple 热工计算