找回密码
 立即注册
查看: 824|回复: 0

STC32G FreeRTOS入门(8):空闲任务与任务恢复

[复制链接]

该用户从未签到

63

主题

703

回帖

1万

积分

荣誉版主

积分
10898
发表于 2023-8-7 00:08:49 | 显示全部楼层 |阅读模式
1)低功耗RTOS。当RTOS中的所有任务都处于挂起状态(包括休眠挂起状态)不需要CPU来执行程序时,CPU用来干什么呢?如果这时让单片机硬件系统处于休眠/停机状态,等待有任务就绪了再让单片机硬件工作起来,这种类型的RTOS称为“低功耗RTOS”。FreeRTOS具备这种软件系统功能,STC32G系列单片机也具有这种硬件功能,但是作为入门系列文章,不讨论这种情况的编程方法。
2)空闲任务。正常情况下,RTOS专门设立了一个空闲任务,它的优先级低于所有的实时任务,当所有实时任务都挂起的时候,空闲任务才得以执行。同时在全部程序中编程者都不能使用任何挂起空闲任务的任务调度函数,这样空闲任务将永远就绪,它也被称为“守护任务”。
FreeRTOS程序中使用空闲任务,首先要在“FreeRTOSConfig.h”配置文件中,设置“configUSE_IDLE_HOOK”的值为1(对于“低功耗RTOS”应该设置为0,不需要空闲任务):
#defineconfigUSE_IDLE_HOOK   1
下图为用户的空闲任务程序:
Fig_X01_程序.jpg
图中第47到第58行为空闲任务。对于实际应用情况,空闲任务的主循环只需要有第53行一行程序,软件延时1毫秒。作为范例程序增加了第52行程序,用LED7灯输出一个500Hz的方波,供逻辑分析仪使用。
3)恢复任务函数。前文介绍了可以用挂起任务函数“uCx51_Task_Suspend”将某个任务挂起来,让其不再就绪,不再获得运行的机会,这时称该函数的下一行程序为“挂起点”。
对于挂起的任务,也可以用设置任务就绪“uCx51_Task_Ready”函数(在FreeRTOS中为“vTaskResume”)来恢复其状态,设置该任务的状态为就绪,将其加入到就绪任务的队列中,等待任务调度器来启动,从挂起点开始再次运行。

本范例通过恢复和挂起任务函数,将实时任务0、实时任务1和实时任务2编程为按照0120…的次序循环运行,用户也可以改变设置使得这三个任务以任意的次序运行。下图为这三个实时任务的程序:
Fig_X02_程序.jpg
Fig_X03_程序.jpg
4)运行效果。范例中实时任务0的一个循环是使得LED0LED67LED灯分左右两组交替发光三次。实时任务1的一个循环是使得LED0LED67LED灯从右到左按跑马灯依次闪光。实时任务2的一个循环是使得LED0LED67LED灯从左到右按流水灯依次点亮发光。下面是实际运行的视频效果:

从视频中可以看到这三个任务依次运行的效果。

5)时序图分析。下面是各个任务运行的时序图:
Fig_X04_时序图.jpg
在时序图上低电平代表LED发光,从图中可以看到实时任务0LED0LED6的方波状信号,可以看到实时任务17LED的闪光低电平从上到下逐个输出的负脉冲,也可以看到实时任务27LED的发光电平从下到上逐个变低的过程。最下面一行的是空闲任务的很密集的500Hz方波信号。将其放大后见下图:
Fig_X05_时序图.jpg
由于各个实时任务的延时都采用的放弃任务控制权的“uCx51_Task_Sleep_MS”任务休眠方法,只有LED电平改变时任务才掌握CPU控制权来执行程序,因此各个任务绝大部分时间都处于休眠状态,这时空闲任务可以连续地执行。上图中间部分显示了执行实时任务0程序中第72行的情况,LED7突然出现了一个负脉冲。这不是任务切换造成的,它是程序的一个BUG造成的。第72行程序的变量“m”的值不是LED7当前的值,而是500毫秒前的值!正确的程序是将第69行程序在第71和第72行之间再重复一次。

下面是本文范例的程序:
FreeRTOS_008_空闲任务.rar (820 KB, 下载次数: 58)
回复 送花

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-14 04:54 , Processed in 0.055239 second(s), 31 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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