找回密码
 立即注册
查看: 697|回复: 1

STC32G FreeRTOS入门(7):抢占式任务调度

[复制链接]

该用户从未签到

63

主题

703

回帖

1万

积分

荣誉版主

积分
10898
发表于 2023-8-6 23:49:48 | 显示全部楼层 |阅读模式
本文用前面介绍的入门(4):实时任务和入门(5):软件延时函数的程序来演示FreeRTOS是如何按照优先级来调度任务的,演示高优先级任务时如何抢占低优先级任务的。同时也展示实时任务的四种状态:挂起、就绪、运行和定时休眠。
(1)本文范例的程序,除了“uCx51_3Tasks.c”和增加了“uCx51_System_STC32G.c”外其余的与入门(4)的相同。其中“uCx51_System_STC32G.c”仅包含了入门(5)定义的软件延时函数,因此本文只给出“uCx51_3Tasks.c”的相关部分进行讨论,其余的就不再进行展示和说明了。
本文将前两个实时任务修改如下:
Fig_X01_TaskA.jpg
图1 实时任务A
(2)实时任务0。实时任务0如图1中第50行到第61行程序所示,它是一个空任务,空任务的意思是这个任务什么事也不做。虽然可以不建立空任务,但是为什么建立了它又不让它做任何事?其实这与先建好一栋大型展览馆,在做某个具体展览时空着某几个展厅一样。
笔者认为RTOS的编程者应该有超前的规划,先建立几个具有固定数目实时任务的框架,然后在做每个具体项目时挑一个合适的框架来实现。就像应该先建好几个不同规模的比赛馆,碰到具体赛事就挑一个合适的去举行比赛一样,而不是每个赛事都建一个比赛馆。
建议读者先建立具有3个、7个、11个或者15个实时任务的RTOS框架作为备选,读者可以自己试试。
(3)空任务。空任务程序应该像图1中那样保持基本的设置和无限循环部分,只是在循环中加入第57行程序。该行程序中的“uCx51_Task_Suspend”任务挂起函数是我们应该掌握的第一个实时任务调度函数,它在FreeRTOS系统的函数名是“vTaskSuspend”,由第22行程序来映射:
#defineuCx51_Task_Suspend    vTaskSuspend
由于同样功能的函数在不同的RTOS操作系统中有不同的函数名,用宏定义的方法将它们映射为自己熟悉的同样的函数名是一种常用的方法。
(4)任务挂起状态。FreeRTOS在执行任务挂起函数时,将任务句柄参数指定任务的状态设置为“挂起状态”。对于处于挂起状态的任务,任务调度管理器在执行任务调度时就会忽略它,不再分配CPU控制权给它。
FreeRTOS在执行任务挂起函数时,如果挂起的不是任务自己,就退出该函数继续执行下一行程序,如果挂起的是任务自己,则该函数不会退出,会进入到任务调度管理过程,去寻找当前就绪任务中优先级最高的那个任务,然后把CPU控制权交给该任务去执行该任务程序。
(5)实时任务A。实时任务A函数如图1中的第63行到第80行程序所示。其主循环包括四个步骤:
1)第71和72行点亮OUT_DEV_D0和OUT_DEV_D1两个LED灯(下拉式,低电平亮)。
2)第73行延时100毫秒。在这100毫秒内,两个LED灯保持发光状态。
3)第74和75行熄灭OUT_DEV_D0和OUT_DEV_D1两个LED灯。
4)第76行的“uCx51_Task_Sleep_MS”任务休眠函数是我们应该掌握的第二个实时任务调度函数,它在FreeRTOS系统的函数名是“vTaskDelay”,由第21行程序来映射:
#define uCx51_Task_Sleep_MS   vTaskDelay
(6)任务定时休眠状态。FreeRTOS在执行任务休眠函数时,将任务自己立即挂起,进入一个特殊的“挂起状态”——“任务定时休眠状态”。
首先对于处于定时休眠状态的任务,任务调度管理器在执行任务调度时就会忽略该它,不会分配CPU控制权给它。
其次,FreeRTOS的系统核心管理程序会每毫秒1次的检查这些处于定时休眠状态的任务,将它们的休眠时间计数减1。如果某个休眠任务的计数减到0,表示该任务休眠时间完成了,核心管理程序就会将该任务的转为“就绪状态”。
对于任务A的第76行程序,任务A立即进入定时休眠状态,500毫秒后会被唤醒,转为就绪状态。
(7)运行状态任务。对于单核的单片机,比如STC32G8K128单片机是单个CPU的内核,因此在某一时刻,只有也只能有一个实时任务在使用CPU执行任务程序,处于运行状态,这个任务称为当前任务。
由于每个实时任务都有一个无限循环,所以正在运行的当前任务,要么自己放弃CPU控制权,要么被抢夺CPU控制权,任务才会被挂起退出运行状态,否则将保持运行状态,一直运行不停止。
(8)就绪状态任务。一个任务处于就绪状态表示这个任务已经具备了继续执行任务的全部条件,等待分配CPU控制权来执行继续任务程序。
对于FreeRTOS多任务系统,正在运行的任务只能有一个,但就绪的任务可以不止一个。到底就绪的多个任务中该挑哪个来执行,就由任务调度程序来完成。
(9)任务调度。正常情况下,FreeRTOS每毫秒启动一次任务调度程序。调度程序依次(按任务表链)检查所有就绪任务,找出优先级最高的就绪任务来,然后与当前正在运行的任务的优先级进行比较,如果当前任务就是就绪任务中优先级最高的,那么调度程序就让当前任务继续执行,让其他就绪任务继续等待,等待下一毫秒的任务调度。
如果当前任务的优先级不是就绪任务中最高的,那么调度程序就让剥夺当前任务的CPU控制权,保存执行现场后,让优先级最高任务掌握CPU的控制权。调度程序剥夺当前任务的CPU控制权后将它的状态设置为“就绪状态”(注意被剥夺CPU控制权的运行任务,其执行条件全部具备,所以它将进入就绪状态而不是挂起状态),与其他就绪任务一起开始等待,等待下一毫秒的任务调度。

(10)实时任务B。下面是对原第三个任务修改的实时任务B的程序:
Fig_X02_TaskB.jpg
图2 实时任务B
实时任务B是一个5节拍的跑马灯程序,LED3到LED7依次闪烁发光,每次每个LED闪烁400毫秒,闪烁的周期为20毫秒。采用闪烁而不是采用实时任务A那样的单纯发光的方式是让各个LED发光的电平在下面的逻辑分析图上看得明显些。
(11)RTOS程序中软件延时函数与任务休眠函数的区别。同样是延时,软件延时函数不放弃CPU控制权,只是单纯地让CPU空转消耗时间,在此期间当前任务保持运行状态。而任务休眠函数放弃CPU控制权,让CPU去执行其他就绪的任务,有效利用CPU资源,实现多个任务同时运行。
(12)永远就绪任务。一个实时任务的程序没有像前面的任务挂起或者任务休眠等放弃CPU控制权的任务管理语句,那么这个任务就永远处于就绪状态。实时任务B就是这样一个永远就绪任务。
显然如果一个任务是永远就绪任务,那么优先级比它低的实时任务即使就绪也永远没有运行的机会,因为每次任务调度按优先级来,这个任务永远就绪,竞争得过比它优先级低的任务。
PS:虽然FreeRTOS有解决这类问题的“分时任务调度”机制,但本系列不准备讨论这个机制,有兴趣的读者可以自己参考相关文献了解。

(13)实时任务B优先级大于实时任务A的运行效果。按照前面第44行和45行的映射,实时任务B对应于“Task1”,实时任务A对应于“Task2”,由于“Task1”任务的优先级大于“Task2”任务的,所以只有实时任务B能够被运行,实时任务A永远不会被运行。下面为实际的运行效果:

从视频中可以看到5个LED依次闪烁,但LED0和LED0一直不发光。

下图是逻辑分析仪得到的时序图,可以清楚地看出这个依次闪烁的过程:
Fig_X03_时序A.jpg
(14)实时任务A优先级大于实时任务B的运行效果。如果将上面程序修改为下图:
Fig_X04_Task.jpg
按照前面第47行和48行的映射,实时任务A优先级大于实时任务B,实际的运行效果为:

从视频中可以看到在5个LED依次闪烁的过程中,LED0和LED0周期地发光,说明实时任务A得到了执行,周期地放弃CPU控制权让实时任务B得以执行,又周期地抢夺了实时任务B的CPU控制权,获得程序执行权,执行发光程序,发光100毫秒后再放弃CPU控制权。

在实时任务A中LED0和LED1发光时,实时任务B的跑马灯是被暂停的,这个效果在视频中不容易看出来,但在下面的逻辑分析仪时序图上就很清楚了:
Fig_X05_时序B.jpg
最上面两个通道代表的LED0和LED1在每次发光(低电平)时,都会打断某个LED(下面的5个通道代表)的闪烁过程,延长这个闪烁的闪烁时间。
(15)总结:本文介绍了FreeRTOS的两个任务调度函数:任务挂起“vTaskSuspend”函数和“vTaskDelay”任务定时休眠函数的用法和效果,介绍了FreeRTOS实时任务的4种状态:“任务挂起”、“任务就绪”、“任务运行”和“任务定时休眠状态”,介绍了FreeRTOS每毫秒一次按优先级调度任务的过程。

(16)提高:有兴趣者可以试一试将实时任务0改为使得LED2每秒闪烁一次的程序,并且不影响实时任务A和实时任务B的执行。
下面是本文范例的程序:
FreeRTOS_007_抢占式任务调度.rar (819.84 KB, 下载次数: 75)
回复 送花

使用道具 举报

  • TA的每日心情
    开心
    昨天 08:14
  • 签到天数: 46 天

    [LV.5]常住居民I

    1

    主题

    7

    回帖

    74

    积分

    注册会员

    积分
    74
    发表于 2023-12-15 16:55:01 | 显示全部楼层
    写的非常好,居然看懂了,给作者赞一个
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-5-14 04:51 , Processed in 0.058088 second(s), 35 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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