在学习正点原子视频的时间片轮转调度时,发现一个问题:当设置时间片为2个10ms时串口收到的消息为图1所示,Tsak1输出5次以后(未执行换行)2个时间片用完,Task2开始执行,输出5次后回到Task1继续执行输出换行,输出5次后,Task2开始执行,开始循环。
但是任务1与任务2中都有一个任务调度函数,并且延迟的时间是1S,应该在Task1执行输出换行后发生调度执行任务2输出5次Task2:568789才对啊
//task1任务函数
void task1_task(void *p_arg)
{
u8 i,task1_num=0;
OS_ERR err;
p_arg = p_arg;
POINT_COLOR = RED;
LCD_ShowString(30,130,110,16,16,"Task1 Run:000");
POINT_COLOR = BLUE;
while(1)
{
task1_num++; //任务1执行次数加1 注意task1_num1加到255的时候会清零
LCD_ShowxNum(110,130,task1_num,3,16,0x80); //显示任务执行次数
for(i=0;i<5;i++) printf("Task1:01234\r\n");
LED0 = ~LED0;
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1S
}
}
//task2任务函数
void task2_task(void *p_arg)
{
u8 i,task2_num=0;
OS_ERR err;
p_arg = p_arg;
POINT_COLOR = RED;
LCD_ShowString(30,150,110,16,16,"Task2 Run:000");
POINT_COLOR = BLUE;
while(1)
{
task2_num++; //任务2执行次数加1 注意task1_num1加到255的时候会清零
LCD_ShowxNum(110,150,task2_num,3,16,0x80); //显示任务执行次数
for(i=0;i<5;i++) printf("Task2:56789\r\n");
LED1 = ~LED1;
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1S
}
}
![](https://img-blog.csdnimg.cn/614afb10c7314ecbaac5fbbadd2fce83.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5oiR55qE55y844CC,size_14,color_FFFFFF,t_70,g_se,x_16)
于是对代码做了多次修改,主要是添加了一个TEST函数优先级为4,Task1,Task2分别为5,并不时对任务调度函数做了屏蔽,使串口得到多种输出信息。修改的代码如下,注意将Task1,Task2循环的次数改为了4次。
//task1任务函数
void task1_task(void *p_arg)
{
u8 i,task1_num=0;
OS_ERR err;
p_arg = p_arg;
while(1)
{
for(i=0;i<4;i++) printf("Task1:01234\r\n");
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1S
}
}
//测试任务函数
void test_task(void *p_arg)
{
u8 i,task1_num=0;
OS_ERR err;
p_arg = p_arg;
while(1)
{
for(i=0;i<5;i++) printf("TEST\r\n");
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1S
}
}
///task2任务函数
void task2_task(void *p_arg)
{
u8 i,task2_num=0;
OS_ERR err;
p_arg = p_arg;
while(1)
{
for(i=0;i<4;i++) printf("Task2:56789\r\n");
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1S
}
}
得到结论,时间片轮转调度并不会发生调度点(当使用OS_SchedRoundRobin()函数放弃剩下的时间片时才会产生调度点)。添加TEST函数,Task1,Task2屏蔽OSTimeDlyHMSM()函数,除了开始会输出4次TEST随后在4次01234与4次56789之间来回输出;添加TEST函数,Task1不屏蔽OSTimeDlyHMSM()函数,Task2屏蔽OSTimeDlyHMSM()函数,开始会输出5次TEST,然后是4次01234,然后一直是56789。添加TEST函数,Task1,Task2都不屏蔽OSTimeDlyHMSM()函数,会输出4次TEST,4次01234,4次56789,循环。这都是在时间片长度为3的情况下(即时间足够完成Task1、Task2)
然后改为时间片长度2,并分别在Task1,Task2输出完4次后添加一条
printf("Task1任务切换\r\n");
和
printf("Task2任务切换\r\n");
语句
添加TEST函数,Task1,Task2都不屏蔽OSTimeDlyHMSM()函数,得到图2的串口信息。
![](https://img-blog.csdnimg.cn/baa19032a4dc42e9a5db77aad779c2e6.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5oiR55qE55y844CC,size_5,color_FFFFFF,t_70,g_se,x_16)
画图解释图2
再画图解释图1
其它的都可以用类似的过程来解释
以上均为自己根据实验所理解的关于时间片轮转调度器,希望大家一起讨论,指正。