搜索
bottom↓
回复: 45

rtos是通过什么东西来调度的?

[复制链接]

出0入22汤圆

发表于 2018-9-19 16:43:54 来自手机 | 显示全部楼层 |阅读模式
一直没有深入了解过这个问题,希望有经验的大虾能够用通俗语言科普一下。问题是,
我理解一个单片机,只能执行一个while 1,但是,我看操作系统,可以有很多个while 1,那么,通过什么方式来切换这多个while1之间程序的呢。
如果是定时器,我的理解是定时器只能影响到中断内部的代码,没法影响到while1里面去。
所以,想破了我的乳头也想不到。

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2018-9-19 16:46:38 | 显示全部楼层
本帖最后由 canopen 于 2018-9-19 17:12 编辑

rtos 调度很简单,定时器中断后,保存当前线程的现场,将需要激活的现场的现场恢复,出中断的时候调入要切换的线程即可。。。   讲rtos的书一大堆

arm 应该有个寄存器是保存出中断后的程序计数器的,将需要切换的线程的 堆栈指针,相关寄存器恢复后,把需要切换线程挂起时的程序指针恢复到那个寄存器,出中断后就完成线程切换了

出0入0汤圆

发表于 2018-9-19 17:45:00 | 显示全部楼层
本帖最后由 bigk2000 于 2018-9-19 17:50 编辑

弄懂OS调度原理前,需要懂汇编,如果不懂汇编,解释起来就非常难了;
还需要知道CPU执行指令的机制,OS调度相关的主要包括:调用子程序时发生什么,子程序返回时发生了什么, 中断时发生了什么,中断返回时发生了什么;
弄懂了这些,理解OS调度原理就很容易了

出0入0汤圆

发表于 2018-9-19 17:55:07 | 显示全部楼层
不建议楼主,现在去研究理论很累的,需要不停的看书,思考,直接在项目中多用用,用个几个案例之后,自然无师自通。。。实践出真知。。

出30入54汤圆

发表于 2018-9-19 18:02:33 | 显示全部楼层
楼主这样去思考问题:
while(1)能被外面的什么打断?当然只有一种,那就是中断(或者更通用的叫法:异常)
所以切换的核心就是利用一个中断来打断CPU的正常运行。
正常一个中断打断CPU运行后就会通过一系列的机制(软件和硬件的)返回到原来while(1)中的代码中去继续运行,这里面的机制就包括要记录刚刚CPU跑到哪里了(因为一会中断退出还要回来)。
此时,只要我们研究CPU的这些机制,通过修改CPU的一些寄存器,让CPU“误以为”另一个Task的某行代码是刚刚进中断前运行的就可以了,然后CPU就会乖乖的顺着原有的机制切换到了一个新的代码空间中
大概就是这么个意思

出0入17汤圆

发表于 2018-9-19 18:22:30 来自手机 | 显示全部楼层
最核心的就是指针,每个时刻指针指向不同的函数,就实现在while里运行不同的函数。os就负责调度指针应该指向哪个函数。

出0入17汤圆

发表于 2018-9-19 18:28:20 来自手机 | 显示全部楼层
在定时起的中断里给运行while里的函数指针赋值,就实现函数切换。

出0入17汤圆

发表于 2018-9-19 18:28:20 来自手机 | 显示全部楼层
在定时起的中断里给运行while里的函数指针赋值,就实现函数切换。

出0入0汤圆

发表于 2018-9-19 20:37:53 来自手机 | 显示全部楼层
线程1进入中断,然后中断退出的时候让他进入线程2,这样就切换过去了。

出0入0汤圆

发表于 2018-9-19 20:39:32 | 显示全部楼层
楼上好图

出0入0汤圆

发表于 2018-9-19 20:40:40 | 显示全部楼层
本帖最后由 bigk2000 于 2018-9-19 20:52 编辑

一图搞懂RTOS任务切换原理

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2018-9-19 20:41:23 来自手机 | 显示全部楼层
线程1进入中断,然后中断退出的时候让他进入线程2,这样就切换过去了。

出0入0汤圆

发表于 2018-9-19 21:42:35 来自手机 | 显示全部楼层
看一遍源代码就明白了,哈哈哈

出0入0汤圆

发表于 2018-9-19 21:54:44 | 显示全部楼层
通俗点讲,就是"刻意"制造了中断

你应该容易理解
while(1)可以被外部中断打断
外部中断发生后,
程序压栈
然后跳转到中断向量所在的地址执行
中断程序执行完毕,退栈
返回原来的位置继续执行

RTOS简单来说就是人工制造了这样一种中断环境
让每个子程序都能够进入和退出

只不过基于其他细节的完善,RTOS需要附带一些其他组件
比如优先级管理,任务切换,任务列表,消息等等..

出0入0汤圆

发表于 2018-9-19 22:11:36 | 显示全部楼层
bigk2000 发表于 2018-9-19 20:40
一图搞懂RTOS任务切换原理

其实我一直有个疑惑
OS里面可以不断地切换不同的任务
假如我有20个任务,他们分别都进入了嵌套
比如Task1运行到一半,被切换到优先级更高的Task2,Task2运行到一半,又被切换到Task3.....一直嵌套到Task20
此时需要保存的"现场"数据这么多,难道不会导致栈空间不足吗?

另外一种情况是
假如我Task1有大量的临时变量,被Task2切换后
是不是需要足够的栈空间存放这些Task1的临时变量
这时候又如何保证内存不会溢出的呢?

出0入0汤圆

发表于 2018-9-19 22:28:33 | 显示全部楼层
本帖最后由 bigk2000 于 2018-9-19 22:52 编辑
qq335702318 发表于 2018-9-19 22:11
其实我一直有个疑惑
OS里面可以不断地切换不同的任务
假如我有20个任务,他们分别都进入了嵌套


好问题
每个任务都有独立的任务栈,任何当前任务被打断时,栈都会压到当前任务栈中;
task1被打断时,压到task1的栈中;
task2被打断时,就压到task2的栈中;
类推。。。
task3,task2要压的栈不占用task1的栈空间;
所以再多嵌套也不会导致栈溢出,当然前提是每个任务栈大小足够;.
由于每个任务都有各自的栈,所以OS吃内存厉害;

临时变量会占用任务栈,所以少用临时,否则会导致栈溢出,系统崩溃。。。
太多的临时变量无法保证不爆栈,但OS都有检查机制,当发现爆栈时,系统只能选择停止调度(类似windows蓝屏)。。。

另外
根据CPU内核机制的不同,需要考虑中断时压的栈会压到哪里去了?
cortex为例,当一级中断发生时,栈会压到任务栈上;更高级中断(嵌套)发生时,会压到系统栈上,因为一级中断发生时,内核自动把栈指针切换为了系统栈;这样就大大节省了任务栈,ARM的设计就是为OS而生的;
而其他cpu有的就糟糕了,比如STM8,当中断发生时,统统压到任务栈上了,当嵌套发生时,每套一级就需要额外的任务栈空间,每个任务都要给中断需要的栈开辟空间,浪费惊人;

出0入4汤圆

发表于 2018-9-19 23:54:21 | 显示全部楼层
rtos修改了任务栈的出口地址

出0入0汤圆

发表于 2018-9-20 08:23:08 来自手机 | 显示全部楼层
每个任务都有任务栈,可以保存恢复现场

出0入0汤圆

发表于 2018-9-20 09:09:36 | 显示全部楼层
bigk2000 发表于 2018-9-19 22:28
好问题
每个任务都有独立的任务栈,任何当前任务被打断时,栈都会压到当前任务栈中;
task1被打断时,压 ...

大神,这些机制哪里有详细的讲解?另外任务栈和系统栈怎么看?调试界面里面能看到吗?

出330入0汤圆

发表于 2018-9-20 09:50:12 来自手机 | 显示全部楼层
还真不知道栈有任务栈,系统栈之分。

出0入0汤圆

发表于 2018-9-20 09:57:36 | 显示全部楼层
zhang0352505 发表于 2018-9-20 09:09
大神,这些机制哪里有详细的讲解?另外任务栈和系统栈怎么看?调试界面里面能看到吗? ...

没有看到哪里有讲解的,我也是自己写OS时自己领悟和看其他OS学习到的这些;
CORTEX为例,调试界面的CPU Registers里的CONTROL的SPSEL位指示当前是哪个栈;

我开始写OS时,用的就是系统栈(MSP),没发现任务栈(PSP)有什么鸟用。。。
后来发现UCOS/FreeRTOS都用的是PSP,我开始思考为什么。。。
后来发现,用MSP时,所有的任务栈都必须为中断时压的栈开辟空间,尤其嵌套中断时,套越深,任务栈就必须越大,非常浪费;
而用PSP就不同了,由于中断打断任务后,内核自动选择了MSP,当嵌套时,压栈是压到系统栈的,这样任务栈只需要为第一级中断时的压栈开辟空间,嵌套的就不管了,解决了浪费问题;

这也是为什么高级CPU都有2个栈指针的原因;
低端CPU只有一个栈指针,要跑OS就太费RAM了。

出0入0汤圆

发表于 2018-9-20 09:58:21 | 显示全部楼层
zhang0352505 发表于 2018-9-20 09:09
大神,这些机制哪里有详细的讲解?另外任务栈和系统栈怎么看?调试界面里面能看到吗? ...

看这《RT-Thread内核实现与应用开发实战指南—基于STM32》的第一部分,里面有实现的细节。
https://www.amobbs.com/thread-5695550-1-1.html

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入8汤圆

发表于 2018-9-20 09:58:35 | 显示全部楼层
zcllom 发表于 2018-9-20 09:50
还真不知道栈有任务栈,系统栈之分。

去看看 Cortex-M 系列的 MSP 和 PSP。

出0入0汤圆

发表于 2018-9-20 10:02:39 来自手机 | 显示全部楼层
定时器切换栈指针  使得pc指针和r寄存器按需要弹出和压入

出0入0汤圆

发表于 2018-9-20 10:04:20 来自手机 | 显示全部楼层
pc和r使得切换了代码和临时变量  就切换了不同的while1循环

出0入8汤圆

发表于 2018-9-20 10:06:14 | 显示全部楼层
zcllom 发表于 2018-9-20 09:50
还真不知道栈有任务栈,系统栈之分。

更通俗的说法是,任务线程栈和中断栈的区分。
可以去这边看看:「在RTOS里,应用程序堆栈和芯片内核中断服务的堆栈是一样的吗?」

出0入8汤圆

发表于 2018-9-20 10:09:46 | 显示全部楼层
bigk2000 发表于 2018-9-20 09:57
没有看到哪里有讲解的,我也是自己写OS时自己领悟和看其他OS学习到的这些;
CORTEX为例,调试界面的CPU R ...

只有一个栈指针的硬件,也可以用软件方式实现,中断栈和任务栈的区分的。
看软件架构设计的取舍了。

出0入0汤圆

发表于 2018-9-20 10:15:28 | 显示全部楼层
security 发表于 2018-9-20 10:09
只有一个栈指针的硬件,也可以用软件方式实现,中断栈和任务栈的区分的。
看软件架构设计的取舍了。 ...

好想法。。。。

出0入0汤圆

发表于 2018-9-20 10:26:49 | 显示全部楼层
bigk2000 发表于 2018-9-20 09:57
没有看到哪里有讲解的,我也是自己写OS时自己领悟和看其他OS学习到的这些;
CORTEX为例,调试界面的CPU R ...

哦,明白了,多谢

出0入0汤圆

发表于 2018-9-20 10:27:22 | 显示全部楼层
610570143 发表于 2018-9-20 09:58
看这《RT-Thread内核实现与应用开发实战指南—基于STM32》的第一部分,里面有实现的细节。
https://www.a ...

嗯,我下载来看一下,这个好

出0入0汤圆

发表于 2018-9-20 11:22:46 | 显示全部楼层
简单的说就是修改中断返回地址,以及必要的现场保护和恢复

出0入0汤圆

发表于 2018-9-20 14:16:59 | 显示全部楼层
security 发表于 2018-9-20 10:09
只有一个栈指针的硬件,也可以用软件方式实现,中断栈和任务栈的区分的。
看软件架构设计的取舍了。 ...

假如刚刚进入低级中断,高级中断就发生了,
这时高级中断还是把栈压到了当前任务栈上啊

极端情况是,所有的嵌套中断都会压到当前任务栈上。

除非个别CPU架构进低级中断时就把全局中断屏蔽了,才有可能使用软件栈指针;

出0入8汤圆

发表于 2018-9-20 14:26:19 | 显示全部楼层
bigk2000 发表于 2018-9-20 14:16
假如刚刚进入低级中断,高级中断就发生了,
这时高级中断还是把栈压到了当前任务栈上啊

是的。
但我想应该有不少架构,都有这样的支持处理。
即便不支持,极端情况也是,所有中断的栈压入到任务栈的开销而已,不会太大,同时这概率又有多大。
IRQ 的运行时栈和任务栈分开,才是关键点。

出0入0汤圆

发表于 2018-9-20 14:39:50 | 显示全部楼层
security 发表于 2018-9-20 14:26
是的。
但我想应该有不少架构,都有这样的支持处理。
即便不支持,极端情况也是,所有中断的栈压入到任务 ...

除非从时序上100%保证不同时发生,否则只能把嵌套要压的栈空间都在任务栈上开辟出来。。。。
分开是个好想法,但是为了保险,还是要把IRQ嵌套的开销算在任务栈上,并不能解决内存浪费问题,
而且还要处理软件栈硬件栈的切换,又浪费了时间,
那边软件栈的意义何在?
有什么机制可以完美解决这个问题?

出0入8汤圆

发表于 2018-9-20 14:48:43 | 显示全部楼层
bigk2000 发表于 2018-9-20 14:39
除非从时序上100%保证不同时发生,否则只能把嵌套要压的栈空间都在任务栈上开辟出来。。。。
分开是个好 ...

每种方案,都有其适应场景,
所以说,要看你的取舍。

出0入0汤圆

发表于 2018-9-20 15:13:08 | 显示全部楼层
举个例,你有两个女朋友分别是A和B,你正在和A女朋友吃饭,这时候你手机响了,B女朋友叫你去逛街,你骗A女朋友说要去上厕所,就去和B女朋友逛街,逛了一会儿,手机又响了,A女朋友说还没上完厕所?你骗B女朋友说要去上厕所,就去和A女朋友继续吃饭,如此反复,你就分别实现了与A,B女朋友约会的任务。

出0入0汤圆

发表于 2018-12-7 12:28:43 | 显示全部楼层
cqfeiyu 发表于 2018-9-20 15:13
举个例,你有两个女朋友分别是A和B,你正在和A女朋友吃饭,这时候你手机响了,B女朋友叫你去逛街,你骗A女 ...

这个厉害!!!

出0入0汤圆

发表于 2018-12-7 22:45:00 来自手机 | 显示全部楼层
嗯说的还不错

出0入0汤圆

发表于 2018-12-8 11:48:17 | 显示全部楼层
bigk2000 发表于 2018-9-19 22:28
好问题
每个任务都有独立的任务栈,任何当前任务被打断时,栈都会压到当前任务栈中;
task1被打断时,压 ...

STM8不也是cortex内核吗,处理中断还不一样?

出0入0汤圆

发表于 2018-12-8 12:15:56 | 显示全部楼层
wq_601840968 发表于 2018-12-8 11:48
STM8不也是cortex内核吗,处理中断还不一样?

8时ST自家的8位核,不是cortex

出0入0汤圆

发表于 2018-12-8 13:08:42 | 显示全部楼层
有个词叫 软中断

出0入0汤圆

发表于 2018-12-8 13:17:47 | 显示全部楼层

然后?。。。。。。。。。。

出0入0汤圆

发表于 2018-12-8 17:55:38 来自手机 | 显示全部楼层
wq_601840968 发表于 2018-12-8 11:48
STM8不也是cortex内核吗,处理中断还不一样?

。。。看看书册再说

出0入0汤圆

发表于 2018-12-10 17:56:51 | 显示全部楼层
这个帖子不错!

出0入0汤圆

发表于 2019-1-3 14:41:01 | 显示全部楼层
之前一直裸跑, 前不久第一次看ucos的代码时,也碰到多个while 1的疑惑。     想想在while 1中,中断也能打断while 1。  然后在中断中完成多个while 1中的跳转。  就释然了。

出0入0汤圆

发表于 2019-1-3 18:09:30 | 显示全部楼层
一石激起千层浪,回复很精彩,学习了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 08:48

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表