关注+星标公众,不错过精彩内容

转自 | 麦克泰技术

在FreeRTOS中,每个任务都拥有自己的堆栈,该堆栈的大小由创建任务时xTaskCreate函数的函数参数所决定。

但当任务所使用的堆栈空间超出分配给它的空间时,则会发生堆栈溢出,堆栈溢出可能修改超过合法访问地址范围外的数据,严重时会导致Hardfault令系统崩溃。

如何设定合理的任务堆栈大小以避免发生堆栈溢出问题呢?

首先我们需要根据任务函数运行过程中的理论堆栈使用最大值,在任务创建时设定一个合理的任务堆栈大小,并实际运行程序进行测试,来确保系统运行过程中不会发生堆栈溢出。

FreeRTOS中的任务堆栈溢出检测机制:

在FreeRTOS中,也提供了一些API函数用来检测任务堆栈的使用情况,例如:

uxTaskGetStackHighWaterMark (TaskHandle_t xTask)——返回自任务运行以来剩余可用堆栈空间的最小值

要使用上述函数,需要在FreeRTOSConfig.h头文件中使能宏“#define INCLUDE_uxTaskGetStackHighWaterMark      1”。该函数会返回任务运行过程中剩余可用堆栈空间的最小值,即任务运行过程中堆栈最大使用量时还剩余多少空间,如果函数返回0则说明可能发生了任务堆栈溢出。在应用中调用该函数可以帮助了解任务堆栈的一个实际使用情况。

FreeRTOS中还提供了两种堆栈溢出检测方式,需要在FreeRTOSconfig.h头文件中通过宏#define configCHECK_FOR_STACK_OVERFLOW  来进行选择使能:

两种检测方式在检测原理上存在一些差别,检测方式1是检测运行过程中的任务栈指针,检测方式2则是检测初始化后的数据在运行过程中是否被修改。

如果任务堆栈溢出检测函数检测到发生了堆栈溢出,则会调用对应的钩子函数(钩子函数需用户手动创建),用户可以在钩子函数中执行想要的操作例如打印发生错误的任务名等。

内核在什么时候执行任务堆栈溢出检测:

在FreeRTOS源码 tasks.c 文件中可以查到taskCHECK_FOR_STACK_OVERFLOW在 void vTaskSwitchContext( void )函数中被调用,也就是在任务上下文切换的时候做检测。从这点可以看出软件检测栈溢出的方式具有一定的滞后性,需要在任务发生上下文切换时才会进行,任务堆栈溢出时并不能马上检测到问题。

任务堆栈溢出检测存在的局限性:

如上文所述,只有在发生任务上下文切换时才会执行任务堆栈溢出检测,发生如下错误情形时则无法检测到了:

•     任务执行的过程中出现过栈溢出,但任务切换前栈指针又恢复到了正常水平。

•     任务栈末尾的 16 个字节没有用到,即不会被修改,但是任务栈已经溢出了

•     任务栈溢出后,把系统中的重要数据修改了导致系统直接进入Hardfault

FreeRTOS提供的堆栈溢出检测会引入任务上下文切换的开销,因此仅推荐在应用开发或者测试阶段使用。虽然存在一定的局限性,但大多常见情况下这些检测机制依然是非常实用的功能,可以帮助用户减少代码中的错误并提高应用程序代码的质量。

声明:本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。

------------ END ------------

●嵌入式专栏精选教程

●精选汇总 | ST工具、下载编程工具

●精选汇总 | 嵌入式软件设计与开发

●精选汇总 | STM32、MCU、单片机

迎关注我的公众号回复“加群”按规则加入技术交流群,回复“1024”查看更多内容。

欢迎关注我的视频号:

点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。

FreeRTOS中的任务堆栈溢出检测机制相关推荐

  1. 嵌入式编程中的堆栈溢出检测

    在嵌入式编程中,栈是一个很重要的概念,不管是裸机编程还是基于RTOS编程.函数形参.局部变量.函数调用现场的保护及返回地址.中断函数执行前线程保护及中断嵌套的现场的保护都依赖于栈空间.栈空间不足,程序 ...

  2. linux线程堆栈溢出检测,GCC栈溢出检测技术

    前一段时间在写ucontext的协程库的时候,遇到了栈空间溢出问题,然后就想到要研究一下堆栈溢出检测的相关技术. 欢迎批评指正,如果对汇编有一个语法问题可以看我之前的一片文章,协程:posix::uc ...

  3. STM32 堆栈溢出检测

    前言 在单片机中,栈stack由编译器自动分配释放,用于存放函数调用,局部变量等数据.堆heap用于动态内存分配.堆栈可以在启动文件或者链接脚本中指定大小,但在实际开发中,尤其工程量较大的项目中难以确 ...

  4. 程序编译保护堆栈溢出保护机制

    目录 一,前言 二,堆栈溢出原理 三,操作系统内置的安全机制 四,参考 一,前言 缓冲区溢出(buffer-overflow)是一种非常普遍.同时非常危险的漏洞,在各种操作系统.应用软件中广泛存在.缓 ...

  5. FreeRTOS 任务栈大小确定及其溢出检测

    以下转载自https://www.cnblogs.com/yangguang-it/p/7123727.html FreeRTOS 的任务栈设置 不管是裸机编程还是 RTOS 编程,栈的分配大小都非常 ...

  6. FreeRTOS中的堆栈计算

    1.栈的重要性 其实不管是普通的程序还是Freertos程序,分配的栈的大小是很重要的,要不然带不动程序,就容易造成程序的崩溃. 函数调用时的现场保护和返回地址,函数的形参,进入中断函数前和中断嵌套等 ...

  7. python堆栈溢出的原因_堆栈溢出一般是什么原因

    堆栈是一个在计算机科学中经常使用的抽象数据类型.堆栈中的物体具有一个特性: 最后一个放入堆栈中的物体总是被最先拿出来, 这个特性通常称为后进先出(LIFO)队列. 堆栈中定义了一些操作. 两个最重要的 ...

  8. python读取文件数据堆栈溢出的原因_堆栈溢出一般是什么原因?

    堆栈是一个在计算机科学中经常使用的抽象数据类型.堆栈中的物体具有一个特性: 最后一个放入堆栈中的物体总是被最先拿出来, 这个特性通常称为后进先出(LIFO)队列. 堆栈中定义了一些操作. 两个最重要的 ...

  9. python堆栈溢出的原因_堆栈溢出一般是什么原因?

    堆栈是一个在计算机科学中经常使用的抽象数据类型.堆栈中的物体具有一个特性: 最后一个放入堆栈中的物体总是被最先拿出来, 这个特性通常称为后进先出(LIFO)队列. 堆栈中定义了一些操作. 两个最重要的 ...

最新文章

  1. 后台开发经典书籍--代码大全
  2. git概念篇(remote,base,local)的含义
  3. python tkinter输入框_python TKinter获取文本框内容的方法
  4. Java调用Lua脚本(热载实现)
  5. C语言课后习题(8)
  6. 由浅入深,解决三道【只出现一次的数】!
  7. 0005-Windows Kerberos客户端配置并访问CDH
  8. Mysql5.7中文乱码
  9. Redis和Memcached区别
  10. 达梦数据库表被锁住后解锁方法
  11. MSP430F149TIMER_A的连续计数模式
  12. vue 美食杰项目 登录验证
  13. 图片处理或背景创建网站 + 在线ps(photopea)使用
  14. 小程序CMS(开通预览)
  15. Windows 系统磁盘克隆
  16. 模糊测试工具-peachFuzzer
  17. 手把手实战 Redis 教学
  18. 如何选择laravel的身份认证系统
  19. 电脑桌面右键无新建选项
  20. 《Groovy官方教程》Grape依赖管理器

热门文章

  1. kali2021安装GVM(openVAS)
  2. Understanding Human Behaviors in Crowds by Imitating the Decision-Making Process
  3. 输出数组中满足条件元素的坐标
  4. 模拟电路单片机硬件比例运算放大器LM358通过PROTUES演示
  5. L0范数、L1范数和L2范数的区别
  6. htop 进程管理工具
  7. 人民币对美元汇率中间价报6.7615元 下调73个基点
  8. org.springframework.dao.InvalidDataAccessApiUsageException:The given object has a null identifi的解决方案
  9. 微信整合CRM系统的好处
  10. 3-AltiumDesignerPCB设计