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个时钟节拍
}
}
/*在YOUTASK访问资源S期间高优先级的任务MYTASK也访问了S,从而干扰了任务YOUTASK对共享资源S的访问,运行后显示表明在任务YOUTASK的延时期间前,共享资源S的内容发生了变化。笔记:
YouTask任务分析:在YouTask任务中程序代码虽然较少但是程序流程相当复杂!必须搞懂每句的含义,提高程序分析能力!分析程序一定要注意流程!下面将YouTask任务中重要部分语句(红色注释部分)分析如下:
1,在MyTask任务挂起同时执行“PC_DispStr(28,++y2,s,DISP_BGND_BLACK+DISP_FGND_WHITE);”语句,所以在显示屏相应的位置几乎同时显示"MyTask get source S"和"YouTask get source S";
2,操作系统的每个任务都在for死循环里完成;“OSTimeSet(0);”语句的意思是,每进入一次for循环里就给系统时间全局变量OSTime重新赋值,在这里就是将OSTime清零;为下一语句“while(OSTime<1000)”做铺垫;
3,本任务中有两个循环体,另一个就是“while(OSTime<1000)”,因为前面有“OSTimeSet(0);”语句,所以系统每次进入YOUTASK任务的for循环里都会执行“while(OSTime<1000)”语句,进入“while(OSTime<1000)”语句之后,全局变量OSTime会以设定的时钟节拍不断自加1,当全局变量OSTime等于1000时,系统就会退出“while(OSTime<1000)”语句,执行“ OSTimeDly(100);”语句,也就是说在OSTime的值在0到1000的时间段里程序会一直执行“PC_DispStr(55,y2,s,DISP_BGND_BLACK+DISP_FGND_WHITE);”语句,即显示相应的内容;
4,因为在YouTask任务中有两句即“PC_DispStr(28,y2,s,DISP_BGND_BLACK+DISP_FGND_WHITE);”语句和
“PC_DispStr(55,y2,s,DISP_BGND_BLACK+DISP_FGND_WHITE);”语句,这样就会在同一个任务中出现争抢s资源的现象(即在内存同一位置几乎同时被赋不同的值)而造成程序出错干扰,这是不允许的!。所以在实验现象中在“55,y2”坐标处先显示“YouTask get source S”再变成显示"MyTask get source SS"的现象。
5,注意:a,在死循环for里才是要创建任务的内容,换句话说任务需要执行的内容只能写在死循环for里;b,本实验中,两个任务都应用了“OSTimeDly(ticks)”函数,当两个任务同时挂起时系统运行哪个任务呢?操作系统不会让cpu闲着,这时会选择优先级最高的任务运行!
6,系统进入YouTask任务时,执行“PC_DispStr(28,++y2,s,DISP_BGND_BLACK+DISP_FGND_WHITE);”语句,在显示屏相应的位置显示"MyTask get source S",接着进入while循环执行
“PC_DispStr(55,y2,s,DISP_BGND_BLACK+DISP_FGND_WHITE);”语句即显示"YouTask get source S",程序很快就会退出while循环执行下面的“ OSTimeDly(100);”语句即挂起YouTask任务,就在挂起YouTask任务的同时系统选择运行MyTask任务,s同时被赋值为"MyTask get source S",所以在实验现象中就出现在“55,y2”坐标处先显示“YouTask get source S”再马上变成显示"MyTask get source SS"的现象(为什么是两个“SS”?)。
7,本实验中MyTask任务占用CPU的时长由程序代码的精度决定。可以通过实验验证。
8,在时序上,s先在MyTask任务中被赋值,再执行YouTask任务s再次被赋值,接着还是在YouTask任务的while中s 再次被赋值;在这个过程中两个任务没有对s资源发生争抢,而在YouTask任务的“ OSTimeDly(100);”语句中两个任务对s资源发生了争抢,导致出现“55,y2”处出现干扰。
作者: 帅帅进城 时间: 2018-4-10 21:47
楼主很认真,赞一个。在此提出自己的一点看法,不吝赐教。
1、MyTask先运行,在第一列打印出“MyTask get source S”。在MyTask任务OSTimeDly(500)期间,操作系统进行任务调度,此时,就绪的YouTask开始运行,在第二列打印出“YouTask get source S”。
2、 OSTimeSet(0)使OSTime变量置零,进入while(OSTime<1000)循环。因为此时MyTask任务控制块的OSTCBDLY变量还未为0【OSTimeDly(500)设置MyTask任务控制块的OSTCBDLY变量为500】,即MyTask还处于未就绪状态,所以一直在while(OSTime<1000)循环内第三列打印“YouTask get source S”
3、当OSTime还未计到1000而MyTask任务OSTimeDly(500)已经完成【即MyTask任务控制块的OSTCBDLY变为0】,MyTask任务就绪,操作系统再次进行任务调度,就绪的MyTask开始运行,在第一列打印出“MyTask get source S”。同时改变s变量的值。4、 MyTas再次进入运行OSTimeDly(500),系统返回YouTask任务的while(OSTime<1000)循环继续执行。因为s变量已经在MyTask中改变,所以可以看到输出窗口第三列先输出“YouTask get source S”,随后即变为“MyTask get source S”。【因为You是三个字节,My是两个字节,所以“YouTask get source S”最后的S没有抹除,所以会出现显示"MyTask get source SS"的现象】
5、当OSTime还未计到1000而MyTask任务OSTimeDly(500)又已经完成【因为第一次系统从MyTask任务调度到YouTask任务以及YouTask任务的执行花费了时间,MyTask任务控制块的OSTCBDLY变量的值其实已经小于500了】,操作系统再调MyTas,在第一列打印出“MyTask get source S”。
6、OSTime终于计到1000,又进入了YouTask任务OSTimeDly(100)。此时两个任务都没有就绪,系统调度空闲任务。随后YouTask首先就绪,在第二列又打出“YouTask get source S”。