首页 > 其他分享 >FreeRTOS——空闲任务和钩子函数介绍

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

时间:2024-10-13 11:46:17浏览次数:8  
标签:调用 函数 FreeRTOS 钩子 任务 内存 空闲

空闲任务

在前面的学习中我们提到,空闲任务会负责释放一些被删除任务的内存,在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的钩子函数为开发者提供了一个强大的工具,用于增强系统的可靠性和灵活性。通过合理使用钩子函数,可以优化系统性能,提高任务管理的效率,并为系统的调试和维护带来便利。

标签:调用,函数,FreeRTOS,钩子,任务,内存,空闲
From: https://blog.csdn.net/weixin_74209413/article/details/142895078

相关文章

  • Nuxt.js 应用中的 ready 事件钩子详解
    title:Nuxt.js应用中的ready事件钩子详解date:2024/10/12updated:2024/10/12author:cmdragonexcerpt:ready钩子是Nuxt.js中一个重要的生命周期事件,它在Nuxt实例初始化完成后被调用。当Nuxt已经准备好并准备开始处理请求或渲染页面时,这一钩子会被触发。cate......
  • GD32F303移植FreeRTOS-Plus-CLI
    FreeRTOS移植好是没有命令行交互的,刚好系统提供了相关的代码,那么就方便多了。示例基于FreeRTOS-Kernel-9.0.0.zip,再次之前需要把系统移植完毕。移植FreeRTOS-Plus-CLI需要干好几件事串口初始化串口终端服务函数添加自己定制的命令下面讲添加哪些文件新建一个分组,放CLI相......
  • Freertos应用与源码分析:临界区
    目录一、概述二、应用三、源码分析1、进入临界区2、退出临界区3、中断临界区(1)应用(2)进入中断临界区(3)退出中断临界区四、注意事项一、概述        当一个任务在使用某个资源的过程中,即还没有完全结束对资源的访问时,便被切出运行态,使得资源处于非一致,不完整......
  • Nuxt.js 应用中的 kit:compatibility 事件钩子详解
    title:Nuxt.js应用中的kit:compatibility事件钩子详解date:2024/10/11updated:2024/10/11author:cmdragonexcerpt:kit:compatibility是处理浏览器兼容性问题的有效工具。正如本篇文章中所述,合理地利用这一钩子可以提升用户体验,并确保应用在不同环境中都能稳定运行......
  • React中useEffect钩子
    副作用:渲染以外的操作:像后端获取数据、操作DOM参数:副作用方法、依赖(改变时重新执行)调用时间:渲染JSX之后/依赖改变useEffect 是React中的一个Hook,用于在函数组件中执行副作用操作。副作用操作包括数据获取、订阅或手动更改React组件中的DOM等。useEffect 使得在函数......
  • Nuxt.js 应用中的 page:transition:finish 钩子详解
    title:Nuxt.js应用中的page:transition:finish钩子详解date:2024/10/10updated:2024/10/10author:cmdragonexcerpt:page:transition:finish是Nuxt.js中的一个事件钩子,专门用于处理页面过渡效果结束后的逻辑。这一钩子在页面过渡的onAfterLeave事件之后被调用,允......
  • 解释 Vue 3 中的 `errorCaptured` 钩子的用途和使用方法。
    Vue3中的errorCaptured钩子的用途和使用方法在Vue3中,errorCaptured是一个生命周期钩子,它允许你捕获并处理组件内部或子组件中发生的错误。这个钩子可以在组件的任何级别上使用,并且对于全局错误处理非常有用。errorCaptured的用途全局错误处理:你可以在Vue应用......
  • SVN提交约束(钩子脚本)Windows环境
    将check.py和pre-commit.bat文件放到svn路径下的hooks文件夹下,其中check.py为格式 pre-commit.bat为windows环境下执行脚本文件校验正则格式为:r'^项目:.+\n修改内容:.+\n修改时间:\d{4}-\d{2}-\d{2}\n修改人:.+$check.py内容:importreimportsysmessage=sys.stdin.re......
  • Nuxt.js 应用中的 page:finish 钩子详解
    title:Nuxt.js应用中的page:finish钩子详解date:2024/10/9updated:2024/10/9author:cmdragonexcerpt:page:finish是Nuxt.js中用于处理页面加载完成事件的钩子,特别是与Suspense机制相关。这个钩子允许开发者在页面加载完成后执行自定义操作,以优化用户体验或进行......
  • Nuxt.js 应用中的 page:start 钩子详解
    title:Nuxt.js应用中的page:start钩子详解date:2024/10/8updated:2024/10/8author:cmdragonexcerpt:page:start是一个关键的钩子,可以在页面加载时执行必要的逻辑,以提升用户体验。通过合理地使用这个钩子,可以创建流畅的页面导航体验,并提供用户反馈。categories:......