低级错误引发的“血案”

2023-04-12 08:10:15 来源:面包芯语

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

前一段时间有个同事被离职了,现在大环境不好,没有办法。有个项目转交到我这边,这个项目马上进入MP阶段了,本以为没什么大问题,前些天测试部提出一个BUG,被这个BUG困扰了好几天,“历尽艰辛”终于把它解决了,最后只改了一点点代码,写写做个记录,当做留作纪念吧。


(资料图片仅供参考)

先说现象:我们的产品是两个处理器设计,处理器之间使用串口通讯,一主一从。在做某项功能压力测试时候,出现一个奇怪BUG,从处理器死机,无法工作,需要长时间测试才能出现,有时候一小时,有时候两小时,甚至四小时,没有规律。下面说一下分析BUG过程:

1、了解这款产品的设计思路

一般情况下主从通讯时,从机采用中断的形式接收主机数据,当进行某项功能测试时,数据量很大,从机改为DMA接收,此项功能测试完成后,更换为中断方式接收。

2、查看通讯Log

主机是linux系统,抓日志比较方便,首先分析出错日志,发现主机发送最后一包后,从机应答了一串乱码,不符合协议格式,数据长度也不够,原因未知。不知道从处理器是进入硬件错误还是卡在某处死循环了。

3、从处理器死机?

编写代码在主循环里周期性输出log,再次尝试复现问题,发现主循环还能周期输出log,由此可见处理器并没有死掉,也没有进入硬件错误,是通讯串口挂掉了,不能接收主机指令,导致看起来从机死机了。

4、通讯串口为什么挂掉了?

怎么就通讯串口挂掉了?编写代码在主循环中周期性输出通讯串口寄存器信息,实时监听,再次尝试复现问题,出问题时串口寄存器配置发生改变,不能正常接收主机数据,导致通讯串口挂掉了。

5、为什么通讯串口寄存器不是正确配置?

仔细阅读了一下代码,并没有发现逻辑错误,DMA接收完成后会重新初始化为中断模式,初始化函数也执行了,但是寄存器配置确实不正确。翻看处理器手册发现,手册明确指出串口有些寄存器是不能在串口工作时进行初始化的。猜测是串口有数据干扰影响了串口初始化。

6、究竟是什么数据干扰了串口初始化?

经过多次打log,发现DMA接收有时候会出错,数据并没有接收完,DMA接收完标志位却置位了。置位后程序校验数据包发现不完整,结束DMA流程,重新初始化串口为中断模式,此时主机仍然在发送数据,这个数据干扰了串口初始化。

7、为什么DMA没有接收完就把标志位置位了呢?

查找这个问题消耗了很长时间,不得已把所有的DMA相关的寄存器输出出来,发现出问题时DMA寄存器配置变了,目的寄存器应该是RAM地址,变成了一个外设地址。瞬间就顿悟了,肯定是某个地方修改了DMA配置,按照这外设地址查到了是QSPI接口的发送FIFO寄存器。搜索了一下和Flash相关代码,发现写Flash也使用了DMA。DMA通道竟然和通讯串口是一样的!看来是这里冲突了,更换DMA通道后问题解决了。干了几天只改了一个宏定义!

8、总结

写代码一定要仔细,不能想当然,代码中使用了什么硬件资源一定要形成文档,否则代码更换维护人员会带来很多问题。

关键词:

X 广告
公司
X 广告

Copyright   2015-2022 大河快递网版权所有  备案号:京ICP备2022022245号-75   联系邮箱:435 226 40@qq.com