|
本例用了BC4.5軟件,在DOS環(huán)境模擬uc/os-ii ,這是本人發(fā)表在論壇上的一篇筆記;放到這里以便常溫故。
最近本人在學(xué)習(xí)uc/os-ii操作系統(tǒng),收獲真的很大,uc/os-ii系統(tǒng)中我覺得任務(wù)間的同步與通信是有點難;本人將學(xué)習(xí)筆記整理出來放在這里,希望有高人能指出錯誤的地方,歡迎指教,謝謝!
/*建立兩個用戶任務(wù):MyTask和YouTask。這兩個任務(wù)都要訪問一個共享資源S,但是YouTask訪問需要的時間要長一些,而MYTASK訪問的時間要短點,這樣就不可避免的出現(xiàn)了在任務(wù)YOUTASK訪問S期間,任務(wù)MYTASK也來訪問S,從而出現(xiàn)干擾*/#include "INCLUDES.h"
#define TASK_STK_SIZE 512 /* 任務(wù)堆棧長度*/
char ss;
OS_STK MyTaskStk[TASK_STK_SIZE];
OS_STK YouTaskStk[TASK_STK_SIZE];
INT8U y1=0,y2=0; //字符顯示位置
char *s="原始數(shù)據(jù)";
void MyTask(void *data); /* 聲明任務(wù) */
void YouTask(void *data);
/*
****************************************************************************
* MAIN主函數(shù)
***************************************************************************
*/
void main (void)
{
OSInit(); /* 初始化uC/OS-II */
PC_DOSSaveReturn(); /* 保存DOS環(huán)境 */
PC_VectSet(uCOS, OSCtxSw); /* 安裝uC/OS-II的中斷 */
OSTaskCreate(MyTask,(void *)0, &MyTaskStk[TASK_STK_SIZE - 1], 0); /*創(chuàng)建起始函數(shù)*/
OSStart(); /* 啟動多任務(wù)管理 */
}
/*
**************************************************************************
* STARTUP TASK
************************************************************************
*/
void MyTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT16S key; /*用于退出的建*/
pdata = pdata; /* Prevent compiler warning */
OS_ENTER_CRITICAL();
PC_VectSet(0x08, OSTickISR); /* 安裝時鐘中斷向量 */
PC_SetTickRate(OS_TICKS_PER_SEC); /* 設(shè)置時鐘頻率 */
OS_EXIT_CRITICAL();
OSStatInit(); /* 初始化統(tǒng)計任務(wù) */
OSTaskCreate(YouTask,(void *)0, &YouTaskStk[TASK_STK_SIZE - 1], 2); /*創(chuàng)建任務(wù)函數(shù)*/
for (;;)
{
s = "MyTask get source S";
PC_DispStr(2,++y1,s,DISP_BGND_BLACK+DISP_FGND_WHITE);/*任務(wù)*/
//如果恩下ESC鍵,則退出UC/OS-II
if (PC_GetKey(&key) == TRUE)
{
if (key == 0x1B)
{
PC_DOSReturn(); /* Return to DOS */
}
}
OSTimeDly(500); /* 等待500個時鐘節(jié)拍 */
}
}
void YouTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3 /*Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT8U err;
pdata=pdata;
for (;;)
{
s = "YouTask get source S";
PC_DispStr(28,++y2,s,DISP_BGND_BLACK+DISP_FGND_WHITE);
OSTimeSet(0); /*置OSTime為0,注意此句的作用*/
while(OSTime<1000) /*條件語句“OSTime<1000”非常重要!*/
{
//sprintf(ss,"%d",OSTimeGet());
PC_DispStr(55,y2,s,DISP_BGND_BLACK+DISP_FGND_WHITE);/*本實驗的精髓語句*/
}
OSTimeDly(100); //等待100個時鐘節(jié)拍
}
}
/*在YOUTASK訪問資源S期間高優(yōu)先級的任務(wù)MYTASK也訪問了S,從而干擾了任務(wù)YOUTASK對共享資源S的訪問,運行后顯示表明在任務(wù)YOUTASK的延時期間前,共享資源S的內(nèi)容發(fā)生了變化。筆記:
YouTask任務(wù)分析:在YouTask任務(wù)中程序代碼雖然較少但是程序流程相當(dāng)復(fù)雜!必須搞懂每句的含義,提高程序分析能力!分析程序一定要注意流程!下面將YouTask任務(wù)中重要部分語句(紅色注釋部分)分析如下:
1,在MyTask任務(wù)掛起同時執(zhí)行“PC_DispStr(28,++y2,s,DISP_BGND_BLACK+DISP_FGND_WHITE);”語句,所以在顯示屏相應(yīng)的位置幾乎同時顯示"MyTask get source S"和"YouTask get source S";
2,操作系統(tǒng)的每個任務(wù)都在for死循環(huán)里完成;“OSTimeSet(0);”語句的意思是,每進入一次for循環(huán)里就給系統(tǒng)時間全局變量OSTime重新賦值,在這里就是將OSTime清零;為下一語句“while(OSTime<1000)”做鋪墊;
3,本任務(wù)中有兩個循環(huán)體,另一個就是“while(OSTime<1000)”,因為前面有“OSTimeSet(0);”語句,所以系統(tǒng)每次進入YOUTASK任務(wù)的for循環(huán)里都會執(zhí)行“while(OSTime<1000)”語句,進入“while(OSTime<1000)”語句之后,全局變量OSTime會以設(shè)定的時鐘節(jié)拍不斷自加1,當(dāng)全局變量OSTime等于1000時,系統(tǒng)就會退出“while(OSTime<1000)”語句,執(zhí)行“ OSTimeDly(100);”語句,也就是說在OSTime的值在0到1000的時間段里程序會一直執(zhí)行“PC_DispStr(55,y2,s,DISP_BGND_BLACK+DISP_FGND_WHITE);”語句,即顯示相應(yīng)的內(nèi)容;
4,因為在YouTask任務(wù)中有兩句即“PC_DispStr(28,y2,s,DISP_BGND_BLACK+DISP_FGND_WHITE);”語句和
“PC_DispStr(55,y2,s,DISP_BGND_BLACK+DISP_FGND_WHITE);”語句,這樣就會在同一個任務(wù)中出現(xiàn)爭搶s資源的現(xiàn)象(即在內(nèi)存同一位置幾乎同時被賦不同的值)而造成程序出錯干擾,這是不允許的!。所以在實驗現(xiàn)象中在“55,y2”坐標處先顯示“YouTask get source S”再變成顯示"MyTask get source SS"的現(xiàn)象。
5,注意:a,在死循環(huán)for里才是要創(chuàng)建任務(wù)的內(nèi)容,換句話說任務(wù)需要執(zhí)行的內(nèi)容只能寫在死循環(huán)for里;b,本實驗中,兩個任務(wù)都應(yīng)用了“OSTimeDly(ticks)”函數(shù),當(dāng)兩個任務(wù)同時掛起時系統(tǒng)運行哪個任務(wù)呢?操作系統(tǒng)不會讓cpu閑著,這時會選擇優(yōu)先級最高的任務(wù)運行!
6,系統(tǒng)進入YouTask任務(wù)時,執(zhí)行“PC_DispStr(28,++y2,s,DISP_BGND_BLACK+DISP_FGND_WHITE);”語句,在顯示屏相應(yīng)的位置顯示"MyTask get source S",接著進入while循環(huán)執(zhí)行
“PC_DispStr(55,y2,s,DISP_BGND_BLACK+DISP_FGND_WHITE);”語句即顯示"YouTask get source S",程序很快就會退出while循環(huán)執(zhí)行下面的“ OSTimeDly(100);”語句即掛起YouTask任務(wù),就在掛起YouTask任務(wù)的同時系統(tǒng)選擇運行MyTask任務(wù),s同時被賦值為"MyTask get source S",所以在實驗現(xiàn)象中就出現(xiàn)在“55,y2”坐標處先顯示“YouTask get source S”再馬上變成顯示"MyTask get source SS"的現(xiàn)象(為什么是兩個“SS”?)。
7,本實驗中MyTask任務(wù)占用CPU的時長由程序代碼的精度決定。可以通過實驗驗證。
8,在時序上,s先在MyTask任務(wù)中被賦值,再執(zhí)行YouTask任務(wù)s再次被賦值,接著還是在YouTask任務(wù)的while中s 再次被賦值;在這個過程中兩個任務(wù)沒有對s資源發(fā)生爭搶,而在YouTask任務(wù)的“ OSTimeDly(100);”語句中兩個任務(wù)對s資源發(fā)生了爭搶,導(dǎo)致出現(xiàn)“55,y2”處出現(xiàn)干擾。
|
|