FreeRTOS——空闲任务和钩子函数介绍

news2024/10/24 20:45:29

空闲任务

在前面的学习中我们提到,空闲任务会负责释放一些被删除任务的内存,在FreeRTOS中,用户分配的内存通常也是在空闲任务中释放的。空闲任务是一个特殊的任务,当没有其他任务需要运行时,系统将会调度空闲任务来执行。在空闲任务中可以执行一些低优先级的任务,比如资源的释放和内存的回收。因此,一般建议将用户分配的内存释放操作放在空闲任务中执行。这样可以确保在系统没有其他任务需要运行时,内存得到及时释放。

空闲任务的主要职责
  1. 内存管理:空闲任务负责释放那些已经被删除的任务的资源,包括任务的堆栈和任务控制块(TCB)。这是通过检查是否有任务删除了自己并由空闲任务来清理资源来实现的。

  2. 处理空闲优先级任务:当系统中存在与空闲任务相同优先级的其他任务时,空闲任务会根据配置(configIDLE_SHOULD_YIELD)决定是否立即让出CPU。这有助于确保用户任务能够获得及时的CPU时间。

  3. 执行空闲任务钩子函数:用户可以定义一个空闲钩子函数(Idle Hook),这个函数在每个空闲任务周期都会被调用。这可以用于执行如进入低功耗模式等轻量级操作。

  4. 低功耗tickless模式:在空闲周期,FreeRTOS可以停止周期性的系统节拍中断,允许微控制器进入低功耗模式,从而节省能源。

空闲任务的创建

空闲任务是在调度器启动时自动创建的。它的创建过程涉及到为其分配一个任务堆栈和任务控制块,并将其添加到就绪列表中。空闲任务的创建代码通常如下所示:

xTaskCreate( prvIdleTask, "IDLE", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, &xIdleTaskHandle );

在这段代码中,prvIdleTask 是空闲任务的入口函数,configMINIMAL_STACK_SIZE 是任务堆栈大小,tskIDLE_PRIORITY 是任务优先级(最低),xIdleTaskHandle 是任务句柄。

而静态创建空闲函数则需要在调度器启动前由用户定义一个接口函数,为空闲任务分配任务堆栈和TCB结构体的空间,如下:

 定义vApplicationGetIdleTaskMemory

//获取空闲任务地任务堆栈和任务控制块内存,因为本例程使用的
//静态内存,因此空闲任务的任务堆栈和任务控制块的内存就应该
//有用户来提供,FreeRTOS提供了接口函数vApplicationGetIdleTaskMemory()
//实现此函数即可。
//ppxIdleTaskTCBBuffer:任务控制块内存
//ppxIdleTaskStackBuffer:任务堆栈内存
//pulIdleTaskStackSize:任务堆栈大小
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, 
								   StackType_t **ppxIdleTaskStackBuffer, 
								   uint32_t *pulIdleTaskStackSize)
{
	*ppxIdleTaskTCBBuffer=&IdleTaskTCB;
	*ppxIdleTaskStackBuffer=IdleTaskStack;
	*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
}
空闲任务的实现

空闲任务的实现涉及到几个关键步骤,包括检查是否有任务需要被删除、处理与空闲任务同优先级的任务、执行空闲钩子函数,以及在适当的情况下进入低功耗模式。空闲任务的核心循环可能如下所示:

for( ;; )

{

// 检查是否有任务删除了自己

prvCheckTasksWaitingTermination();



// 如果有与空闲任务同优先级的任务,根据配置决定是否立即让出CPU

if (listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > 1)

{

taskYIELD();

}



// 调用空闲钩子函数

if( configUSE_IDLE_HOOK == 1 )

{

vApplicationIdleHook();

}



// 进入低功耗模式

if( configUSE_TICKLESS_IDLE != 0 )

{

// 相关代码省略

}

}

在这个循环中,prvCheckTasksWaitingTermination 检查是否有任务需要被删除,taskYIELD 根据配置决定是否让出CPU,vApplicationIdleHook 调用用户定义的空闲钩子函数,而低功耗模式的代码则根据具体的硬件实现可能会有所不同。

 如果删除的任务是使用动态方法创建的,那么该任务所用到的堆栈和任务控制块会被空闲任务自动回收,任务删除自身,其内存不会立即释放,会在执行空闲任务时释放该任务内存。 但是,有一点需要特别注意,那就是使用vTaskDelete ()函数的任务不能影响空闲任务的执行,否则空闲任务得不到执行,被删除的任务内存也就无法回收

总的来说,空闲任务在FreeRTOS中扮演着重要的角色,它不仅负责在系统空闲时保持CPU的忙碌状态,还负责资源的清理、低功耗模式的管理以及提供一个执行用户定义轻量级操作的地方。

钩子函数

钩子函数定义

钩子函数是操作系统(FreeRTOS)满足某些功能的机制,FreeRTOS调用钩子函数,但钩子函数的实现由开发者(用户)完成。
可以将之理解成回调函数。
大部分的钩子函数都能在“FreeRTOSConfig.h”中通过宏进行剪裁。

钩子函数的种类和使用条件

FreeRTOS提供了多种钩子函数,每种钩子函数都有其特定的使用条件和目的。以下是一些常见的钩子函数及其使用条件:

  • vApplicationIdleHook():当系统空闲时,该函数被调用。要使用它,需要在FreeRTOSConfig.h中将configUSE_IDLE_HOOK设置为1,并实现void vApplicationIdleHook()函数。

  • vApplicationTickHook():该函数在每个Tick中断发生时被调用。要启用它,需要在FreeRTOSConfig.h中将configUSE_TICK_HOOK设置为1,并实现void vApplicationTickHook()函数。

  • vApplicationStackOverflowHook():当任务栈溢出时,该函数被调用。要使用它,需要在FreeRTOSConfig.h中将configCHECK_FOR_STACK_OVERFLOW设置为1或2,并实现void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName)函数。

  • vApplicationDaemonTaskStartupHook():该函数在守护任务(如Timer服务)启动时被调用。要使用它,需要在FreeRTOSConfig.h中将configUSE_DAEMON_TASK_STARTUP_HOOKconfigUSE_TIMER都设置为1,并实现void vApplicationDaemonTaskStartupHook()函数。

钩子函数的特点和注意事项

钩子函数的运行周期和使用细节因其类型而异。例如,vApplicationIdleHook()可能会在没有其他任务运行时持续被调用,类似于主函数中的无限循环。    空闲任务的钩子函数不可以调用会引起空闲任务阻塞的API函数(例如:vTaskDelay()、带有阻塞时间的队列和信号量函数),在钩子函数内部使用协程是被允许的。

vApplicationTickHook()的调用周期由configTICK_RATE_HZ决定,通常设置为1毫秒。由于该函数在Tick中断中调用,其执行时间应尽可能短,不能包含任何延迟操作。

vApplicationStackOverflowHook()只在任务栈溢出时调用,但并非所有栈溢出都会触发该钩子函数。如果栈溢出破坏了系统栈溢出检测代码的数据,栈溢出检测可能失效,导致钩子函数无法被调用。

实现钩子函数

要实现钩子函数,开发者需要在FreeRTOSConfig.h中启用相应的宏定义,如果是想实现空闲任务的钩子函数,则需要将下面的宏置位:

并提供钩子函数的具体实现。例如,如果启用了vApplicationIdleHook(),则需要在代码中定义该函数:

void vApplicationIdleHook(void) {

// 用户自定义的空闲任务代码

}

通过实现钩子函数,开发者可以在系统空闲时执行低优先级的维护任务,或在Tick中断中执行周期性的检查,或在任务栈溢出时进行错误处理和资源回收。

        总的来说,FreeRTOS的钩子函数为开发者提供了一个强大的工具,用于增强系统的可靠性和灵活性。通过合理使用钩子函数,可以优化系统性能,提高任务管理的效率,并为系统的调试和维护带来便利。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2210812.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

硬盘格式化后能恢复数据吗?好用4款工具集锦

嘿,硬盘格式化后能恢复数据吗?咱们现在的生活,数据可是宝贝,这大家都清楚。学习用的资料、工作的文件,还有那些宝贵的照片、视频,统统都存硬盘里。万一硬盘不小心被格式化了,那感觉就像所有东西…

【GUI】使用 PySide6 开发图片左右切换软件

使用 PySide6 开发图片左右切换软件 前言 在现代软件开发中,使用 Python 开发跨平台的 GUI 应用程序变得非常普遍。今天,我们将使用 PySide6 来开发一个简单的图片浏览器,它可以实现图片左右切换的功能,并自适应按钮布局。本教程…

闭着眼学机器学习——朴素贝叶斯分类

引言: 在正文开始之前,首先给大家介绍一个不错的人工智能学习教程:https://www.captainbed.cn/bbs。其中包含了机器学习、深度学习、强化学习等系列教程,感兴趣的读者可以自行查阅。 1. 算法介绍 朴素贝叶斯是一种基于贝叶斯定理…

c++应用网络编程之十一Linux下的epoll模式基础

一、epoll模式 在前面分析了select和poll两种IO多路复用的模式,但总体给人的感觉有一种力不从心的感觉。尤其是刚刚接触底层网络开发的程序员,被很多双十一千万并发,游戏百万并发等等已经给唬的一楞一楞的。一听说只支持一两千个并发&#x…

YOLOv9分割改进 ,YOLOv9分割改进主干网络为华为EfficientNet,助力涨点

YOLOv9 分割改进前训练结果: YOLOv9 分割改进后训练结果: 摘要 卷积神经网络(ConvNets)通常在固定的资源预算下开发,然后在有更多资源时进行扩展以提高准确性。在本文中,我们系统地研究了模型扩展,并发现仔细平衡网络深度、宽度和分辨率可以带来更好的性能。基于这一…

【Python库安装】Python环境安装wrf-python库

【Python库安装】Python环境安装wrf-python库 wrf-python库概述Python中安装wrf-python库方式1:使用pip安装方式2:离线安装,使用whl文件安装另:报错 方式3:使用conda安装wrf-python另:报错 参考 wrf-python…

教育培训系统小程序的设计

教师账户功能包括:系统首页,个人中心,课后习题测试管理,观看进度管理,论坛管理,网课信息管理,公告信息管理,学生管理,试卷管理,测试管理 微信端账号功能包括…

RK3568学习之Nginx移植+RTMP推流

1.下载 Nginx 源码 进入到 Ubuntu 系统的某个目录下,下载 Nginx 源码: wget http://nginx.org/download/nginx-1.20.0.tar.gz这里我们下载的是 1.20 版本,这是比较新的版本了。下载完成之后将得到一个名为 nginx-1.20.0.tar.gz的压缩包文件…

嵌入式中数据库sqlit3基本使用方法与现象

大家好,今天主要给大家分享一下,数据库的使用方法,观察对应的效果。 第一:数据库sqlit3基本安装方法 sqlite3 安装 使用 Ubuntu # 安装软件 sudo apt-get install sqlite3# 查看版本 sqlite3 -version# 安装编译工具包 sudo apt-get install sqlite3-dev# 安装可视化工具…

为何2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者?

近日,2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者,这是历史上首次出现这样的情况。这项奖项原本只授予对自然现象和物质的物理学研究作出重大贡献的科学家,如今却将全球范围内对机器学习和神经网络的研究和开发作为了一种能…

html css js 生成随机颜色

起因&#xff0c; 目的: 整理文件&#xff0c;发现之前写的一个小工具。 效果图 点击按钮会生成新的格子。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"wi…

3.计算机网络_端口号

端口号的由来 运输层的作用&#xff1a; 在计算机网络中&#xff0c;运输层处在用户功能的最底层、通信部分的最高层的位置&#xff0c;也就是说运输层是用户数据和实际网络通信的桥梁。因此运输层屏蔽了网络的实现部分&#xff0c;以协议的方式向用户层提供了接口&#xff…

结构体 超详解

目录 1. 结构体的声明与创建 1.1 结构体类型的定义声明&#xff08;类型&#xff09; 1.2 结构体变量的创建和初始化&#xff08;变量&#xff09; 1.3 结构体变量的特殊声明&#xff08;类型和变量&#xff09; 1.3.1 定义时创建变量 1.3.2 结构体的不完全声明&#xff…

SpaceWire原理介绍及FPGA实现

SpaceWire原理及介绍 spacewire特点 SpaceWire 总线具有高速、全双工、点对点、串行传输的特点。它由欧洲航 空局&#xff08;European Space Agency&#xff0c;简称 ESA&#xff09;联合欧洲航空公司等共同发起&#xff0c;由 Dundee 大学制定&#xff0c;以 IEEE-1355 接口…

大数据治理:挑战与实践

目录 大数据治理&#xff1a;挑战与实践 1. 大数据治理的基本概念 2. 大数据治理的关键要素 3. 大数据治理实施框架 3.1 策略与目标制定 3.2 数据治理工具 3.3 数据生命周期管理 4. 大数据治理的挑战与解决方案 5. 大数据治理的价值与未来趋势 5.1 提升决策质量 5.2…

MySQL初识

在了解什么是MySQL前&#xff0c;我们先了解一下什么是数据库&#xff1f;&#xff1f; 1. 数据库简介 1.1 什么是数据库 数据库是20世纪60年代末发展起来的⼀项重要技术&#xff0c;已经成为计算机科学与技术的⼀个重要分⽀。数据库技术主要是⽤来解决数据处理的⾮数值计算问…

【MATLAB代码,带TDOA数据导入】TDOA最小二乘求三维下的位置(1主锚点、3副锚点),多个时间点、输出位置图像

此TDOA&#xff08;Time Difference of Arrival&#xff09;最小二乘法三维定位 MATLAB 工具是一个先进的定位解决方案&#xff0c;专为需要高精度位置计算的工程师、研究人员和开发者设计。此工具可以通过多个时间点的测量数据&#xff0c;结合主锚点和副锚点的配合&#xff0…

Hi3061M——不定长串口接收实现

这里写目录标题 前言串口接收流程串口中断函数ReadITCallBack1中断接收函数 补充结果展示 前言 Hi3061M给了很多相关的串口案例&#xff0c;但大多数是定长的&#xff0c;指定长度进行接收读取&#xff0c;而实际需求往往需要用到不定长的接收。 串口接收流程 首先介绍下Hi3…

Android终端GB28181音视频实时回传设计探讨

技术背景 好多开发者&#xff0c;在调研Android平台GB28181实时回传的时候&#xff0c;对这块整体的流程&#xff0c;没有个整体的了解&#xff0c;本文以大牛直播SDK的SmartGBD设计开发为例&#xff0c;聊下如何在Android终端实现GB28181音视频数据实时回传。 技术实现 Andr…

C++——红黑树(带头结点)

红黑树 红黑树的概念红黑树的定义红黑树的性质红黑树的优点操作原理例图&#xff1a; 红黑树的实现红黑树的框架红黑树的插入实现头结点的作用红黑树的插入步骤&#xff08;简易理解版带图&#xff09; 红黑树的插入具体代码详解红黑树的旋转代码红黑树的查验 红黑树的概念 红…