vtor 发表于 2022-9-15 15:07

嵌入式模拟时间片轮询调度算法

本帖最后由 vtor 于 2022-9-15 15:13 编辑

嵌入式模拟时间片轮询调度算法污钞vtor
模拟时间片轮转调度算法-vtor3478


【01】传统while做法在一般的裸机程序中,
一般是while(1)作为main中最后的一段语句如下图中,
就是while(1)内一直运行taskHandle以处理逻辑事务
https://img2022.cnblogs.com/blog/2472635/202209/2472635-20220915144455614-400139989.png
在这时,如果希望加上一个led作为指示灯,
说明程序正在运行,修改成如下所示,led1每隔500毫秒变化一次状态,
问题随之而来,taskHandle的响应时间最大为1000ms,不利已处理实时性很高的事务。
https://img2022.cnblogs.com/blog/2472635/202209/2472635-20220915144444648-1885533889.png
再进一步优化,使用dWhileCnt对while进行计数,
且taskHandle实时性大大提高,最大只有1毫秒的响应时间,
好像解决了问题,但如果还有led2需要间隔2秒变化一次呢,
如果还有串口要求1分钟打印一条消息呢,很明显,这个框架就不适用了


【02】模拟时间片轮询法
【0201】时间片结构体
https://img2022.cnblogs.com/blog/2472635/202209/2472635-20220915144639700-2047596181.png
其参数依次为,当前模拟时间片(以下简称时间片)的回调函数
当前时间片的运行间隔当前时间片的时间,
如果大于等于时间间隔,那么即将启动本时间片
当前时间片回调函数是否该运行
当前时间片回调函数的运行次数

【0202】时间片任务示范
https://img2022.cnblogs.com/blog/2472635/202209/2472635-20220915144651596-1416421671.png
此处共有6个时间片,其中TaskBask是时间片基,用于调度其他时间片,在下文会有讲解。


【0203】时间片基
在此模拟时间片轮询法中,需要一个稳定的定时器,
在本方案中使用tim2产生1毫秒中断,并进入时间片基函数TaskBase以调度其他时间片
https://img2022.cnblogs.com/blog/2472635/202209/2472635-20220915144658739-1528205941.png
如图所示,在定时器回调函数HAL_TIM_PeriodElapsedCallback内,执行了TaskBase时间基,
在TaskBase时间基内,对其他时间片的curTime进行累加,
如果curTime大于interval时说明该任务需要纳入到运行任务的队列内,同时将curTime清零,再将runFlag置1【0204】运行时间片
https://img2022.cnblogs.com/blog/2472635/202209/2472635-20220915144715491-450673058.png
如图所示,在main函数的while(1)内,需要对其他时间片进行轮询判断
如果其runFlag为1,说明将要执行此任务,先将runFlag清零,防止重复执行此任务
再将runCnt次数加1,可以用于以后统计任务次数
最后是执行handle函数,handle函数如下,
分别执行了不同占空比的pwm输出,
实现了led间隔1000毫秒翻转状态,
实现了oled显示部分信息。
https://img2022.cnblogs.com/blog/2472635/202209/2472635-20220915144737513-1773049007.png


【03】总结经过验证,此方案能很好地在裸机上实现时间片功能,
能非常方便地添加时间片,
且能基本保证各个时间片的运行次数,
能基本均匀调度各个任务,
且都达到实时性要求。


以上是《模拟时间片轮询调度算法》,2022年9月15日星期四,全文完。

guohuanxian 发表于 2022-9-15 16:17

学习学习

Light紫星 发表于 2022-9-15 18:09

感谢分享,受益匪浅

blfiag 发表于 2022-9-15 19:16

感觉就是在主循环设置延迟1s后,计数count,每隔mod(count, n)=0秒执行 fcn_n_sec() 。不必定义那些时间***结构体吧。

cube 发表于 2022-9-15 19:21

我以为是个提问帖,看着看着,我心咯噔一下.莫非这是个技术分享帖?接着往下看,果不其然.

vtor 发表于 2022-9-16 08:46

cube 发表于 2022-9-15 19:21
我以为是个提问帖,看着看着,我心咯噔一下.莫非这是个技术分享帖?接着往下看,果不其然.

我发布的分区是《学习笔记》
所以自然是技术分享贴啊~
不知道对你有没有帮助,哈哈哈哈

vtor 发表于 2022-9-16 08:50

blfiag 发表于 2022-9-15 19:16
感觉就是在主循环设置延迟1s后,计数count,每隔mod(count, n)=0秒执行 fcn_n_sec() 。不必定义那些时间*** ...

如果在while内这么做,无论delay多久,都有cpu性能被浪费掉
如果希望不浪费cpu性能,必须在定时器内执行递增操作
       但又因为定时器增加,不能使用取余,因为不清楚定时器会执行几次,数值会增加多少
       所以必须是大于预设值   之后,flag置为1,所以建议使用完整结构体,可以更好地操作

vtor 发表于 2022-9-16 08:57

cube 发表于 2022-9-15 19:21
我以为是个提问帖,看着看着,我心咯噔一下.莫非这是个技术分享帖?接着往下看,果不其然.

编程语言区版规说:学习笔记,求助等要发布到《编程语言讨论求助区》
不过 编程语言讨论求助区又说: 总结和好文章发送到《编程语言区》
我也不确定我这篇,到底是属于学习笔记,还是技术分享,还是好文章

blfiag 发表于 2022-9-16 11:38

vtor 发表于 2022-9-16 08:50
如果在while内这么做,无论delay多久,都有cpu性能被浪费掉
如果希望不浪费cpu性能,必须在定时器内执行 ...

感谢解惑!
页: [1]
查看完整版本: 嵌入式模拟时间片轮询调度算法