这几天调试程序,发现看门狗叫了,因为是偶发的,就没怎么理,后面发现叫得越来越厉害,有80%以上的概率,决定还是把它解决掉。
锁定提交代码
一般之前的代码都是没看门狗叫的现象的,至少刚加看门狗的时候肯定不会有这种现象,刚加的时候至少要把看门狗弄到基本不会叫的。
于是回退代码,从之前的某一笔开始,确定这一笔没有看门狗叫的现象,然后用二分法往新的时间逐渐锁定提交时间,最后发现是自己最近提交的更新CAN矩阵的代码引起的,但是肉眼看每一行修改,似乎并没有太大的问题。
查看问题log
因为看门狗叫都在启动的时候,这个比较好锁定,看到有个error提示,说一个互斥锁被占用了。
代码里面对这个互斥锁申请了500ms,一般不至于连500ms别人都在用着,这个现象非常异常。
看到这个互斥锁是在仪表MCU对SOC通讯模块里面用到的,就是将SOC发过来的数据进行解析,说明有问题的代码大概率在仪表接收模块。
回退代码
将出问题那笔代码的仪表接收模块的修改改回去,再运行,发现看门狗就不叫了,说明就是这里的问题导致的。
代码分析
信号编号 | 信号长度 | 信号数值 |
SOC发送的信号按照上表格式进行发送,发一个信号就要发它的信号编号、信号长度和信号数值,MCU按照进行解析之后决定接下来的动作。如果MCU解析成功,就回复ACK,SOC接收到ACK之后不做动作。如果MCU解析失败或者丢帧,就不回复,SOC就会一直发,发到接收到MCU的ACK为止。报互斥锁被占用的进程是仪表接收解析的其中一个进程,仪表接收解析有4个进程:配置数据、普通数据、申请链接、心跳。
由于更新CAN矩阵的时候,有一些信号被删除了,但是在仪表那里还有接口,我就顺势把仪表接收SOC信号的接口给删除了。删除的接口是配置数据,只需要在上电的时候发。这下就导致了上电的时候SOC发给MCU的信号没有被正常解析,MCU不回复ACK,SOC一直发,再加上上电的时候需要发的配置、申请链接、心跳,处理普通数据的进程就一直申请不到互斥锁,一直堵在那里了。
解决办法
如果不删除那些接口其实并不影响功能的正常使用,顶多就是信号从SOC发到MCU,MCU只是保存在RAM里面占点空间而已,所以把删掉的接口加回来就行。