OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6845|回复: 4

FreeRTOS是如何实现调度的,SysTick中断中处理了啥

[复制链接]

13

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
112
金钱
112
注册时间
2014-9-20
在线时间
8 小时
发表于 2016-6-9 14:41:07 | 显示全部楼层 |阅读模式
10金钱
最近入门RTOS,首先看书了解了合作式调度器的应用,其基本思想是在主循环中不断执行调度函数,在SysTick中断中更新任务状态,程序我也大致看懂了。之后到了入门FreeRTOS遇到了困难,利用了stm32的官方例程,原理上的东西大致懂了,可在程序中是如何实现的呢,C语言障碍,没看懂。
首先是调度函数,函数函数是如何执行的呢?如下图,新建任务后执行调度函数,为什么没用循环,调度函数是一直运行的吗?在其C语言程序中哪里可见执行任务的代码?
捕获.PNG
SysTick中断中主要更新了任务状态,它是怎么轮询每个任务的呢,在中断中决定了下一个执行的任务吗?

可能我问的任务比较繁琐,大侠们如果有空回答重点即可,程序我还是慢慢凿吧,谢谢

最佳答案

查看完整内容[请看2#楼]

这不是调度混乱,是你理解混乱了. 在线程调用osDelay切换线程的时候,会加原子锁,就是关中断,此时就算SysTick被触发,也只有在线程切换完成后再响应. 线程在运行是肯定会周期性的被打断,转而执行SysTick,至于切换不切换线程,要看当前线程的优先级和时间片. 在线程中如果有对时间敏感的代码,请加原子锁, 线程设计为无限循环,一方面是由OS架构决定的,有的OS在给线程分配了堆栈后,就跳转执行线程服务函数,而未将线程返回地址压入线 ...
明天的你会感谢今天努力奋斗的自己
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

277

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1522
金钱
1522
注册时间
2014-5-16
在线时间
217 小时
发表于 2016-6-9 14:41:08 | 显示全部楼层
flashtt 发表于 2016-6-10 12:07
谢谢你的回答,意思是说调度函数不一定是在SysTick中断中进行的,如osDelay函数中现有的任务阻塞,会根据 ...

这不是调度混乱,是你理解混乱了.
在线程调用osDelay切换线程的时候,会加原子锁,就是关中断,此时就算SysTick被触发,也只有在线程切换完成后再响应.
线程在运行是肯定会周期性的被打断,转而执行SysTick,至于切换不切换线程,要看当前线程的优先级和时间片.
在线程中如果有对时间敏感的代码,请加原子锁,
线程设计为无限循环,一方面是由OS架构决定的,有的OS在给线程分配了堆栈后,就跳转执行线程服务函数,而未将线程返回地址压入线程栈,所以不允许线程返回,只允许显式的结束线程.另一方面,嵌入式程序中的线程,通常都是执行周期性任务,或事件性任务,都需要线程长期存在,而用临时线程也需要分配堆栈,还不如直接调用同功能的普通函数.
当然有的OS是允许线程返回的,所以在应用的时候,要仔细阅读OS的说明书.
回复

使用道具 举报

27

主题

711

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
11922
金钱
11922
注册时间
2015-11-5
在线时间
2086 小时
发表于 2016-6-9 22:20:42 | 显示全部楼层
在SysTick中断里面会轮询每条任务链表和事件列表,如果有任务就绪则根据优先级决定哪个任务该被执行,如果任务优先级相同则根据时间片来轮番调度
回复

使用道具 举报

5

主题

277

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1522
金钱
1522
注册时间
2014-5-16
在线时间
217 小时
发表于 2016-6-10 00:44:36 | 显示全部楼层
这个也没多复杂,原理就像你说的,可能是你学习的RTOS实现方法和FreeRTOS有一点点区别.
FreeRTOS我没有用过,我用过uCOS和RTX,虽然在实现上有点差别,但是在核心思想上是相近的.
你说的轮询和更新状态,一般称之为任务调度,调度会发生在几个地方:
1.时间片中断里,也就是你说的SysTick,当然也可以是其他的定时中断.
2.线程的主动释放,比如调用osDelay,osMutexWait等等.
3.中断服务返回前,有些OS会在中断服务中要求加入中断嵌套代码.
4.其他,暂时没想到
OS的切换线程上下文的函数,一般都是用汇编写的,对于CortexM内核的MCU,可能还会使用到用户模式.
osKernelStart这个函数中,会在已创建的线程中,找到一个优先级最高的线程,切换其上下文,然后跳转过去执行.
当最高优先级线程运行的时间片到达或者其主动放弃CPU,才会在SysTick中进行线程调度,或者直接调用线程调度函数,实现线程的切换.
你提到的主循环轮询和中断更新状态,这更多的是状态机程序的描述.
RTOS是基于时间片运行的,在SysTick中断服务中,你一定可以看到调度算法.
以上
回复

使用道具 举报

13

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
112
金钱
112
注册时间
2014-9-20
在线时间
8 小时
 楼主| 发表于 2016-6-10 12:07:19 | 显示全部楼层
zmingwang 发表于 2016-6-10 00:44
这个也没多复杂,原理就像你说的,可能是你学习的RTOS实现方法和FreeRTOS有一点点区别.
FreeRTOS我没有用过, ...

谢谢你的回答,意思是说调度函数不一定是在SysTick中断中进行的,如osDelay函数中现有的任务阻塞,会根据优先级立即发生线程切换,这是我的理解,但我的理解是这样的调度是不是太混乱了,是不是碰到SysTick调度又发生了,万一在任务运行中途遇到了SysTick中断怎么办,直接切换吗?这些任务为什么都要写成无限循环的形式,这是我一开始接触RTOS无法理解的部分,这样又牵涉到任务切换返回后返回位置的问题
明天的你会感谢今天努力奋斗的自己
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 16:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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