| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> 1252_FreeRTOS_堆栈溢出检查方法与测试 -> 正文阅读 |
|
[嵌入式]1252_FreeRTOS_堆栈溢出检查方法与测试 |
全部学习汇总: GreyZhang/g_FreeRTOS: learning notes about FreeRTOS. (github.com) 参考API这次先不看,先从堆栈溢出的角度看一下。开启这个功能需要配置configCHECK_FOR_STACK_OVERFLOW这个参数。如果这个参数不为0的时候,就要提供上面的hook函数。这里写得是不为0,不知道是非零有多种含义还是含义全都相同呢? 堆栈的检查功能肯定会增加上下文切换的负载率,因此推荐在开发和测试的时候使用,产品中这个功能不要开启。 前面刚刚出现的疑问在这里接着找到了答案,configCHECK_FOR_STACK_OVERFLOW的配置不同的数值是有不同含义的。从上面的信息,结合FreeRTOS可以提供两种堆栈检查方法可以知道这个参数可以有3种数值选择。结合下面的信息,参数值可以是0、1、2。 回到针对第一个方法的梳理。堆栈的检查一般是在OS完成了上下文切换之后,因为这个时候由于现场保护,上下文的信息需要存储到任务堆栈之中。此时的系统可能有着最大的任务stack消耗。这个时候,查一下stack指针是否有超出最大边界的情况就可以知道是否有stack的溢出了。 优点:快! 缺点:出现问题不一定百分百全都可以捕捉到。 第二个方法,使用的时候配置参数需要设置为2。当任务从运行状态切换出去的时候,检查堆栈的情况。检查的方法是检查存储信息,这样就需要在任务创建的时候在任务stack中填充固定的已知数据。之后检查的时候检查任务stack最后的16个字节。 优点: 检查可靠性高,但是也不是百分之百。 缺点:比第一种方法慢,但是也不是很慢。 之前,看过一点RT-Thread的代码,看到了任务stack初始化的时候填充了DEADBEAF。可能也是要完成类似的功能,16个字节就是2组DEADBEAF。 这是之前运行过的QEMU的例程,在FreeRTOS.h中有这样的信息。也就是说,如果不增加配置的话,默认会不启用这个检查功能。一般,OS的类似的功能配置都是在FreeRTOSConfig.h中。而FreeRTOS.h包含了这个头文件,因此如果有定义的话,第一段预处理的代码就不会展开。 以上,是现在用户代码中的配置信息。 main.c中有检查hook函数的定义。接下来,注释掉这段代码,看看编译是否报错。按照前面的说明,现在的这个函数是必须要提供的。 实际的测试跟描述是相符的,也就是说现在的这个示范工程中这个检查功能是生效的。修改配置值为1,也是一样的效果。当修改成0的时候,编译链接通过。 查看了一下,这个检查所用的hook在stack_macros.h中定义的。根据我现在的工程配置,方法选择2,以上是生效的代码。判断的条件有2个,一个是检查的方法,另一个是stack增长的方向。这里,刚刚是检查了4个32bit的数据,也就是16个字节。按照4字节检查其是否是0xa5a5a5a5。 如果stack的增长方向相反,那么检查是按照字节来处理的。检查的效果其实是一样的,但是按照增长顺序检查,可以便捷使用库函数。 设计上面的测试代码,在RX的任务中调用。 以上是增加的测试代码调用。为了能够让测试时间短一些,我修改了几个时间相关的参数。接下来,测试两种stack溢出检查的效果。 这是使用方法1检测的时候出现的提示,感觉stack的溢出没有检查到。 最终停在了上图中的3033,为了找到触发原因,增加了2个printf。 看了一下打印的log,其实这个接口只有这里调用了一次。 这是上面的两个信息的解释,从解释看的话,这个数值肯定是错误的,绝对不会这么大。可能的原因是存储异常,而stack溢出很可能是其中的一个原因。 加入了类似上面的信息,捕捉到了在哪个接口出现的问题。 这么看,就是前面截图的代码中出现了问题。 进一步,找到了这里,看起来可能是发送队列信号的时候出现了异常。但是,异常肯定是发送之前产生的。那么,按照这个软件的执行规律,肯定是前面的Timer发送了队列信号,触发了计算后导致了stack异常。接下来,进行新的周期性调度发送发现内存异常。这个能够解释的清楚,但是也看得出来这个stack的溢出检测并不准确。 接下来,看看第二种堆栈溢出的测试。 当使用第二种堆栈溢出的检查方法的时候,成功找到了堆栈溢出的任务。这么看,第二种方式的确是准确一些。 |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 1:29:32- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |