dragonFANG 发表于 2016-11-17 22:39:48

最近在学FreeRTOS,遇到一个任务切换的问题,大神们帮我看...

在学FREERTOS中,小弟遇到个问题。
第一步创建了2个任务LED0和LED1,任务都是灯亮500ms,灭500ms,这两个任务的优先级我都设成一样的,比如都是3,然后在创建任务后开始任务调度。这时两个灯几乎是同时亮同时灭的。说明这两个任务是论循的,LED0任务运行,对应的IO口响应了变化,然后论循到了LED1任务运行,对应的LED1的IO口响应了变化,之后在这样论循,就这样一直在两个任务间论循;

第二步、我改变了一下,将两个任务设置不同的优先级,比如LED0的优先级设为4,LED1的优先级设为3,这样编译后观看结果还是LED0和LED1同时亮500ms,同时灭500ms,这应该是高优先级的LED0先开始运行,在运行到LED0的IO翻转指令后,进行了延时(这里和上面的延时用的都是FREERTOS自带的延时),延时中发生了任务调度,LED0释放了CPU的使用权,LED1抢到了CPU的使用权(这应该就是抢占式的原因吧),系统继续运行到LED1的IO翻转指令后,IO电平进行翻转,然后进入延时发生任务调度。就这样一直在两个高低优先级的任务间发生循环调度,因为响应IO的速度是非常快的,所以看起来又是同时亮500ms,灭500ms;

第三步、我将系统的延时去掉了,用上了自己写的延时(里面没有任务调度的函数),任务的优先级也改成了相同的了,编译后烧写到芯片中看到的现象是LED0和LED1同时亮500ms,灭500ms。这里我就不理解了,在这里用的是自己的延时函数,是不会发生任务调度的。按理说应该是其中一个LED的IO口进行电平翻转之后进入自己的延时,然后再等延时之后另一个LED的IO口进行电平翻转,接着又进入了延时等待。这样一直轮询下去。我想这样的话那么现象不应该是两个LED同时亮灭的;

第四步、我将两个任务换成不一样的优先级,比如LED0的优先级设为4,LED1的优先级设为3,用的还是自己的延时函数。则现象是高优先级的LED一直在亮500ms,灭500ms。因为是高优先级的任务一直没有发生任务调度,所以CPU的使用权都没有释放。

结果小弟就在想了,是不是这同一优先级的任务是不是的运行是不是就是所谓的时间轮转调度,跟抢占式的调度的机理不一样,他不需要任务调度函数,时间到了就会自己发生调度,所以才会出现第三步中的情况。还有大神帮忙看看我分析的第一步到第四步是不是对的呢、、、

dragonFANG 发表于 2016-11-17 22:49:43

自己先顶一下、、、

zzh90513 发表于 2016-11-18 07:06:05

别忘了有个tick一直在中断判断

dragonFANG 发表于 2016-11-18 07:12:57

zzh90513 发表于 2016-11-18 07:06
别忘了有个tick一直在中断判断

是判断时间吗?然后时间到了就会发生时间轮换调度吗?

zzh90513 发表于 2016-11-18 08:27:09

dragonFANG 发表于 2016-11-18 07:12
是判断时间吗?然后时间到了就会发生时间轮换调度吗?

你可以吧系统滴答改为1S就明白了,每到系统滴答中断都会检查任务就绪表,有不小于当前任务优先级就绪的就会执行任务切换

zzh90513 发表于 2016-11-18 08:34:00

看Systick中断里面的task.c中xTaskIncrementTick函数,其中有如图所示判断

techbaby 发表于 2016-11-18 08:55:15

看来楼主还是没有搞清楚RTOS的调度原理!

dragonFANG 发表于 2016-11-18 09:38:06

techbaby 发表于 2016-11-18 08:55
看来楼主还是没有搞清楚RTOS的调度原理!

刚开始接触,希望大神们多指点指点、、、

haoyurenzhu 发表于 2016-11-18 09:57:38

freertos相同优先级使用时间片轮询调度的,不同优先级才抢占式调度。

security 发表于 2016-11-18 10:09:15

dragonFANG 发表于 2016-11-18 09:38
刚开始接触,希望大神们多指点指点、、、

关于操作系统的调度,你可以看下这个帖子UCOSIII中无干扰下最高优先级任务何时才会任务切换?,4 楼的回复,
不过还是先多看看书吧。

小油猪儿 发表于 2016-11-18 10:46:23

9 10楼都很好的解答了楼主的问题。

laoshuhunya 发表于 2016-11-18 10:58:07

〝第三步、我将系统的延时去掉了,用上了自己写的延时(里面没有任务调度的函数),任务的优先级也改成了相同的了,编译后烧写到芯片中看到的现象是LED0和LED1同时亮500ms,灭500ms。这里我就不理解了,在这里用的是自己的延时函数,是不会发生任务调度的。按理说应该是其中一个LED的IO口进行电平翻转之后进入自己的延时,然后再等延时之后另一个LED的IO口进行电平翻转,接着又进入了延时等待。这样一直轮询下去。我想这样的话那么现象不应该是两个LED同时亮灭的;〞

既然两个任务优先级一样,那么就要让它们看起来是同时在运行是吧?但是CPU是单核的,怎么办?只能玩障眼法在两个任务间跳来跳去了,只要跳得够快能骗过程序猿就行{:titter:}
那么任务又是怎么切换的呢?一种想法是任务主动让出CPU,但要是个别任务赖着不还这游戏就玩不下去了{:titter:} 所以这办法总是不妥。机智的程序猿又想到了中断!中断就像特权阶层,想插队就插队,想断谁就断谁,不怕钉子户任务霸占着CPU。不过,在ARM-Cortex 之前,操作系统就像做贼一样,总是在背后偷偷地修改任务返回地址,利用手中特权玩障眼法。返回地址被改了,从中断退出后自然就跳到那地方运行了,这就是任务切换。

flamma 发表于 2016-11-18 11:17:42

你想的没错,同一优先级的任务是时间轮转调度,所以每到一个时间片会切换。

nongxiaoming 发表于 2016-11-18 11:29:10

通过tick来抢占的,同优先级的

dragonFANG 发表于 2016-11-18 12:16:47

haoyurenzhu 发表于 2016-11-18 09:57
freertos相同优先级使用时间片轮询调度的,不同优先级才抢占式调度。

谢谢、、、

kgdso210 发表于 2017-7-20 13:43:07

12楼讲得挺好的,谢谢

563872381hai 发表于 2017-8-3 21:46:56

那第四步中,假如低优先级的任务想运行是不是需要高优先级的任务主动暂停然后启动优先级低的才可以

笑笑我笑了 发表于 2017-8-3 22:44:08

563872381hai 发表于 2017-8-3 21:46
那第四步中,假如低优先级的任务想运行是不是需要高优先级的任务主动暂停然后启动优先级低的才可以 ...

一般是被队列啊、信号量之类的东西阻塞了。

563872381hai 发表于 2017-8-4 09:12:08

笑笑我笑了 发表于 2017-8-3 22:44
一般是被队列啊、信号量之类的东西阻塞了。

我的意思是如果要运行低优先级的任务是不是需要高优先级任务主动释放

security 发表于 2017-8-4 09:18:31

563872381hai 发表于 2017-8-4 09:12
我的意思是如果要运行低优先级的任务是不是需要高优先级任务主动释放

是的,请回头看看 10 楼的链接。
页: [1]
查看完整版本: 最近在学FreeRTOS,遇到一个任务切换的问题,大神们帮我看...