关于解决裸机\stm32开发中一些奇怪的程序死机问题

Article Version: BK1:最初版本

关于解决裸机\stm32开发中一些奇怪的程序死机问题

可能的现象:
1. 无缘无故死机,hardfault
2. 死机的位置很奇怪,每次都不同。
3. 稍微修改了一些看似无关紧要的代码,死机的位置和现象会完全不一样。
4. 有些函数前面调用正常,运行一会儿就在其中挂了。
5. 正常调用子函数,但是return / BX LR时无缘无故hardfault

非常坑爹的可能原因

@关注是否使用了C++的malloc()。
MDK中的微库中的microlib中的malloc()在申请失败时可能不会返回0,而是返回当前堆栈的地址。如果返回堆栈地址,那么就会导致内存溢出。

Bug解决过程

我接触stm8s,stm32f1,f4开发已经有了3年了,虽然代码写了很多,但是总会遇到一些很奇怪的死机问题。特别是开发了嵌入式OS,这种死机情况更是变得越来越怪(可能的死机现象如前述)。虽然也有找出一些代码问题,但是最终因为有些bug的可重现性太弱而最终不了了之。直到近期项目需要一个非常精简的抢占式内核。开始了解具体的堆栈寄存器操作后才发现了问题。因为内核抢占式调度后,无缘无故的死机现象越来越频繁,然而这些Code在windows C++上已经稳定使用,Code本身逻辑出现问题的可能性极小,因此我开始利用MDK的联机调试来慢慢地地位bug。最终发现无一例外都是指针错误导致,有的分布于全局变量,有点分布于内存缓冲区中的结构体中,分得很散,出错的时间也不定。找到了直接原因却一直没找到根本原因。直到有一天看到了 机载软件适航标准(RTCA DO-178B))中明确提出不允许使用malloc()函数,我才突然明白问题所在。然后去检查malloc(),结果发现。使用MDK的microlib中的函数,malloc()有些bug。它的失败后的返回值不一定是0,而是直接返回当前堆栈指针。这真的是非常坑,普通Windows上的代码使用" if( ! ptr ) "来检查malloc()是否成功。但是在这里是有bug的。
关于解决裸机\stm32开发中一些奇怪的程序死机问题_第1张图片
内存溢出也正好能够解释上述各种奇怪的死机和bug的原因。后来我也是通过重写了内存管理函数,彻底解决了所有奇怪的bug问题。搞了这么久的嵌入式,我感觉这个bug真的是非常坑爹。对于像我一样从PC端转到嵌入式的人,可能会有多少都会有些过于信赖C库的可靠性,都不曾怀疑malloc()可能会有问题。
处理了这个问题后,我也总结出了一个调试技巧:即遇到一些问题飘忽不定的情况或者函数组件时而正常时而不正常的问题。可以针对性地考虑内存溢出的问题。其实细想也知道,内存溢出也是最容易导致死机现场不时第一现场的情况的。举个例子,若程序A正常。A用了内存区域MA,存一个结构体,主要使用其中的指针。前期运行正常。然后程序B用了内存MB,MA,MB存在交错。而B刚好写入到MB,该操作溢出越界篡改了A所需的数据。那么A从MA中读取会得到一个错误的数据,根据A的程序逻辑的不同,最终导致死机的位置是不确定的,多变的。甚至有可能代码稍微修改,导致内存布局改变,死机的位置和附加影响也会不同。

你可能感兴趣的:(STM32/MDK)