模拟时间片轮转调度算法-vtor3478
【01】传统while做法
在一般的裸机程序中,一般是while(1)作为main中最后的一段语句
如下图中,就是while(1)内一直运行taskHandle以处理逻辑事务
在这时,如果希望加上一个led作为指示灯,说明程序正在运行,
修改成如下所示,led1每隔500毫秒变化一次状态,问题随之而来,
taskHandle的响应时间最大为1000ms,不利已处理实时性很高的事务。
再进一步优化,使用dWhileCnt对while进行计数,且taskHandle实时性大大提高,最大只有1毫秒的响应时间,
好像解决了问题,但如果还有led2需要间隔2秒变化一次呢,
如果还有串口要求1分钟打印一条消息呢,很明显,这个框架就不适用了
【02】模拟时间片轮询法
【0201】时间片结构体
其参数依次为,当前模拟时间片(以下简称时间片)的回调函数
当前时间片的运行间隔
当前时间片的时间,如果大于等于时间间隔,那么即将启动本时间片
当前时间片回调函数是否该运行
当前时间片回调函数的运行次数
【0202】时间片任务示范
此处共有6个时间片,其中TaskBask是时间片基,用于调度其他时间片,在下文会有讲解。
【0203】时间片基
在此模拟时间片轮询法中,需要一个稳定的定时器,在本方案中使用tim2产生1毫秒中断,并进入时间片基函数TaskBase以调度其他时间片
如图所示,在定时器回调函数HAL_TIM_PeriodElapsedCallback内,执行了TaskBase时间基,
在TaskBase时间基内,对其他时间片的curTime进行累加,如果curTime大于interval时
说明该任务需要纳入到运行任务的队列内,同时将curTime清零,再将runFlag置1
【0204】运行时间片
如图所示,在main函数的while(1)内,需要对其他时间片进行轮询判断
如果其runFlag为1,说明将要执行此任务,
先将runFlag清零,防止重复执行此任务
再将runCnt次数加1,可以用于以后统计任务次数
最后是执行handle函数,handle函数如下,分别执行了不同占空比的pwm输出,实现了led间隔1000毫秒翻转状态,实现了oled显示部分信息。
【03】总结
经过验证,此方案能很好地在裸机上实现时间片功能,能非常方便地添加时间片,
且能基本保证各个时间片的运行次数,能基本均匀调度各个任务,且都达到实时性要求。
以上是《模拟时间片轮询调度算法》,2022年9月15日星期四,全文完。