Createdon:2012-10-7Author:zhangbin
本文引用地址:http://www.j9360.com/article/201611/322851.htm
學習筆記
forucos-iiPC
redesignedbyzhangbin
2012-10-7
versions:V-0.1
AllRightsReserved
#include"includes.h"
#defineTASK_STK_SIZE512
#defineN_MESSAGES128
OS_STKStartTaskStk[TASK_STK_SIZE];
OS_STKMyTaskStk[TASK_STK_SIZE];
OS_STKYouTaskStk[TASK_STK_SIZE];
char*s_flag;//該字符串指示哪個任務在運行
//char*s_1;
char*ss;//存放接收到的消息指針
char*s100;//存放發送消息的指針
char*s;
char*s500;
void*MsgGrp[N_MESSAGES];//定義消息指針數組
//創建消息隊列,首先需要定義一個指針數組(用于存放消息郵箱),然后把各個消息數據緩沖區的首地址存入這個數組中
//最后再調用函數OSQCreate()來創建消息隊列
INT8Uerr;
INT8Uy=0;
OS_EVENT*Str_Q;//定義事件控制塊指針隊列的事件控制塊指針用于存放創建的消息隊列的指針
voidMyTask(void*data);
voidStartTask(void*data);
voidYouTask(void*data);
voidmain(void)
{
OSInit();
PC_DOSSaveReturn();
PC_VectSet(uCOS,OSCtxSw);
Str_Q=OSQCreate(&MsgGrp[0],N_MESSAGES);//創建消息隊列
//函數的第一個參數&MsgGrp[0]是void**start,是存放消息緩沖區指針數組的地址,它是指向指針數組的指針
//可以用指針數組的首個元素的地址表示
//N_MESSAGES是該數組的大小
//返回值是消息隊列的指針Str_Q是OS_EVENT型的指針,是事件控制塊型的指針
OSTaskCreate(StartTask,(void*)0,&StartTaskStk[TASK_STK_SIZE-1],0);
OSStart();
}
voidStartTask(void*pdata)
{
#ifOS_CRITICAL_METHOD==3
OS_CPU_SRcpu_sr;
#endif
INT16Skey;
pdata=pdata;
OS_ENTER_CRITICAL();
PC_VectSet(0x08,OSTickISR);
PC_SetTickRate(OS_TICKS_PER_SEC);
OS_EXIT_CRITICAL();
OSStatInit();
OSTaskCreate(MyTask,(void*)0,&MyTaskStk[TASK_STK_SIZE-1],3);
OSTaskCreate(YouTask,(void*)0,&YouTaskStk[TASK_STK_SIZE-1],4);
//s="Howmanystringscouldbegeted?";
//OSQPostFront(Str_Q,s);//發送消息以LIFO后進先出的方式發送
//第一個參數Str_Q是消息隊列的指針,是OSQCreate的返回值,第二個參數s是消息指針
for(;;)
{
s_flag="TheStartTaskisrunning!";
PC_DispStr(50,++y,s_flag,DISP_FGND_RED+DISP_BGND_LIGHT_GRAY);//提示哪個任務在運行
if(OSTimeGet()>100&&OSTimeGet()<500)
{
s100="ThevalueofOSTIMEisfrom100to500NOW!!";
OSQPostFront(Str_Q,s100);//發送消息以LIFO后進先出的方式發送
//發送消息以LIFO后進先出的方式發送
//第一個參數Str_Q是消息隊列的指針,是OSQCreate的返回值,第二個參數s是消息指針
s="Thestringbelongstowhichtask.";
OSQPostFront(Str_Q,s);//發送消息以LIFO方式發送所以如果要申請消息時,會先得到s,然后才是s100
}
if(OSTimeGet()>1000&&OSTimeGet()<1500)
{
s500="ThevalueofOSTIMEisfrom1000to1500NOW!!";
OSQPostFront(Str_Q,s500);//發送消息
}
if(PC_GetKey(&key)==TRUE)
{
if(key==0x1B)
{
PC_DOSReturn();
}
}
OSTimeDlyHMSM(0,0,1,0);
}
}
voidMyTask(void*pdata)
{
#ifOS_CRITICAL_METHOD==3
OS_CPU_SRcpu_sr;
#endif
pdata=pdata;
for(;;)
{
s_flag="TheMyTaskisrunning!";
PC_DispStr(50,++y,s_flag,DISP_FGND_RED+DISP_BGND_LIGHT_GRAY);//提示哪個任務在運行
ss=OSQPend(Str_Q,0,&err);//請求消息隊列,參數分別是:Str_Q為所請求消息隊列的指針第二個參數為等待時間
//0表示無限等待,&err為錯誤信息,返回值為隊列控制塊OS_Q成員OSQOut指向的消息(如果隊列中有消息可用的話),如果
//沒有消息可用,在使調用OSQPend的任務掛起,使之處于等待狀態,并引發一次任務調度
//因為前面發送消息時使用的是LIFO的方式,所以此處第一次得到的消息是上面最后發送的消息
PC_DispStr(3,y,ss,DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);//顯示得到的消息
//s_1="M";
PC_DispStr(0,y,"My",DISP_FGND_RED+DISP_BGND_LIGHT_GRAY);//顯示是哪一個任務顯示的
OSTimeDlyHMSM(0,0,1,0);
}
}
voidYouTask(void*pdata)
{
#ifOS_CRITICAL_METHOD==3
OS_CPU_SRcpu_sr;
#endif
pdata=pdata;
for(;;)
{
s_flag="TheYouTaskisrunning!";
PC_DispStr(50,++y,s_flag,DISP_FGND_RED+DISP_BGND_LIGHT_GRAY);//提示哪個任務在運行
ss=OSQPend(Str_Q,0,&err);//請求消息隊列
PC_DispStr(3,y,ss,DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);//顯示得到的消息
//s_1="Y";
PC_DispStr(0,y,"You",DISP_FGND_RED+DISP_BGND_LIGHT_GRAY);//顯示是哪一個任務顯示的
OSTimeDlyHMSM(0,0,1,0);
}
}
//運行的現象說明上面分析是正確的,因為當時鐘節拍數大于100,小于500時,會發送第一個if語句中的兩個字符串s100和s
//下面運行的任務接收到并且顯示。當時鐘節拍數大于1000小于1500時,發送第二個if語句中的字符串,下面運行的任務
//接收并顯示。當時鐘節拍數大于1500時,就不再發送消息了,下面的任務得不到消息就無限等待下去,所以就不再顯示了
//從運行的現象不難可以看出,有時MyTask或YouTask運行了,但是沒有得到消息而處于等待狀態
//使用上面的方法可以很清楚地看出任務調度和運行的關系了MyTask和YouTask是交替運行的,因為延遲時間相等
評論