单片机学习05 --- 嵌入式软件debug方法
嵌入式软件debug方法(更新中)
注意事项
1. 首先并持续的怀疑是硬件导致的问题,调试过程不能放弃对硬件的分析与质疑;
2. 除了调试看门狗之外尽可能关闭看门狗进行调试
1)开启看门狗时,有些问题导致的复位可能无法被观测到,但是如果此时关闭了看门狗,程序可能就直接跑死了;
2)不开看门狗在线调试,可以直接确定程序跑死的位置;
3. 与底层驱动相关的问题一定要看芯片手册
具体的一些调试方法
二分定位法
方法阐述:屏蔽掉一部分代码后看问题是否还存在,直到找到与问题相关联的那一行代码;
适用场景:问题毫无头绪,且问题极易复现。
该方法简单粗暴,但是耗时较长,刚发现问题时不建议立即使用,后续发现完全没有头绪、没有问题的切入点的时候可以使用。属于下下策
数据流法
方法阐述:对数据传输过程中的每一个节点进行数据捕获,查看数据或者配置是否符合预期
适用场景:数据传输链路清晰,且可以通过打印、报文等方式将数据直观地表现出来;
该方法一般用在某些接口的得到的最终数据不符合预期的情况,且该接口的整体传输链路是比较清晰的,可以通过没对一个节点进行深入研究。
CAN通信信号接收不成功(发送不成功类似)的调试方法:
1. CANH\L: 有没有信号、波特率是否正确、电平是否标准、波形是否规整;
2. CANRX: 有没有信号、收发器是否打开;
3. CAN驱动: 是否产生接受中断、ID是否正确、DLC是否正确;
4. CANIF: 是否进入到CANIF rxindicaiton、Handle号正确、有没有无法匹配的参数;
5. CanCom:是否进入到COM rxindicaiton、信号有没有拷贝到Com缓存;
6. APP:传递的信号handle对不对、信号值有没有从COM缓存拷贝到APP
隔离法
方法阐述:对于单一单元进行隔离,单独分析。给一个合理的输入看是否能得到预期的输出;
适用场景:simulink中的仿真、cdd底层某一个模块
该方法适用于已经确认问题属于哪个模块产生,但是不知道问题产生的原因。一般是模块内部的参数设置或者逻辑关系存在问题导致。
汇编法
方法阐述:对某一行代码进行反汇编操作,查看其汇编语句的运行是否正确,或者查看MCU寄存器中的数据也可以。
适用场景:已经确定了问题产生的c代码,但是从c代码上无法确定问题产生的原因,或者是一些程序跑飞、BT跳转的问题。
使用到该方法时一般是已经对C代码黔驴技穷了,属于是更深一步去查看原理行的执行过程与数据,对汇编语句了解较为深刻的朋友可以使用这个方法,如果自身能力有限也可以把对应的汇编语句交给ai处理。
此外,如果是一些十分怪异不合逻辑的问题,或者已经怀疑到编译器自身的问题也可以使用这个方法。
ABA法
方法阐述:把一套系统中的某一个组件从A切换到B,如果问题消失,在切换回A,看问题是否能够复现。
适用场景:软硬件问题的划分、程序下载失败时分析是电脑、烧写器还是板子的问题;
该方法速度很快,可用于进行快速的问题定位。此外调试的时候也可以对某些参数进行修改,来达成相同的效果。
版本回溯法
方法阐述:将软件版本回退到上一个版本,看问题是否还存在,如果不存在了可以通过比对代码的方式,查看问题出在哪;
适用场景:软件做了充分的版本管理,问题出现在软件修改后的升版,同样也是用于快速定位问题。
对于软件版本的管理,我有一点想法,首先自身要做好更新记录的维护,要能够在每一个版本中获取到版本号等信息(报文或者常量值),其次是保证每次将软件提供给硬件、试验工程师时都要做好升版操作。这样可以保证能够成功追溯每一版已经刷写出去的软件。
IO调试法
方法阐述:通过合理的设置对IO进行高低配置,并通过示波器查看IO电平来获取信息;
适用场景:无法做在线调试、无法通过Can通信向外输出信号、查看代码的执行顺序、查看某些任务的执行周期是否符合预期;
该方法是我调试过程中最常用到的方法,通过对一些常高或者常低io口的电平进行配置或者翻转,来实现一些具体信息的获取
1. 执行周期:进入某个任务后翻转io口,通过示波器查看反转的周期是否符合预期;
2. 执行逻辑:在某行代码前或者后置io,代码如果执行到这个为止,则会控制io输出预期的电平
3. 模拟输出:IO可以用来模拟uart通信,可以在CAN通信失效时,用io的方式向外传输数据
log分析法
方法阐述:通过对单片机运行过程中接收和发送报文的log进行分析。
适用场景:软件已经提供到硬件、试验、客户方,无法通过在线调试的方法分析问题,且可以获取到最原始的log文件
该部分可以参考我的另外一篇文章:
小知识记录
编译单元:某.c文件以及与关联的所有.h文件共成为一个编译单元;如果编译时上报了大量的错误,可以挨个对编译单元进行编译,来确定这些报错的产生原因;
中断标志位:MCU会关注中断标志位是否置位,如果置位就立即执行中断服务函数,如果在软件中没有做标志位的清除,那么他就会在执行完这个中断函数后,立马再次执行,直到该标志位被清除。
典型问题类型
1. 重入问题:
首先需要明确的是,什么是重入:对于某一个函数在其执行完成之前,也就是retrurn之前,又重新执行了一遍。重入并不一定是有害的,对于某些函数,无论是第几次执行它内部的状态都是不变的,所以重入对其并没有影响, 但是某些函数,每次进入时状态都有可能发生变化,比如定义了staic变量,那么对于这个函数而言,重入就是错误的。
尽可能避免中断在抢占某一个函数后,在该中断中又执行了一遍这个函数。
2. 共享资源抢占
3. 硬件问题
4. 寄存器配置错误
5. 软件逻辑错误
6. 代码时序错误
7. 栈空间溢出
后续抽时间更新
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)