代码调试总体可分为两大块:时间(时序)调试,空间(分块)调试。
1.时间(时序)调试:
仔细分析整个代码执行的正常逻辑顺序,假如一个任务执行分为5个步骤,则依次排查每个步骤,找出有问题的步骤,以为modbus主站发送流程为例,假如出现主站通讯速度很慢,要想定位到具体原因,则需要把整个主站通讯的时序流给梳理出来: 1.请求线程打包报文->2.发出发送请求->3.中断发送->4.等待从机回应->5.中断接收报文->6.接收完成一帧->7.拆报文解析。 则可以使用调试工具和实时在线监测工具,依次检查各环节,哪里存在耗时操作,则能进一步找到原因。说白了就是从时间上将一个问题拆分成若干时序小问题,再逐个排查找到问题。
2.空间(分块)调试:
就是首先通过思考和分析,导致的问题可能有哪几大块代码或者线程,或者中断影响,依次通过调试每个分块或者采用最简单的 注释掉部分代码的方式来定位到问题出现在哪一小块,然后又在小块中进一步定位到某个函数或者某行代码。还是以上面的 modbus主站通讯速度慢为例子,当通过前面的时序调试发现问题:出现在中断接收到报文->接收完成一帧上面。 因为中断接收到一帧报文是通过T3.5超时判断的,在T3.5超时中断中给POLL线程发通知,通知其接收到一帧了,准备处理,也就是说T3.5中断发出通知,到POLL线程收到通知存在耗时。通过分析,可能出现在:1.某个中断一直进入,导致线程没法运行,耗时很长。 2.比POLL优先级高的线程一直占据CPU资源没有释放,POLL线程没法快速响应,耗时很长。 3.T3.5发出通知,到POLL线程执行并且获取到事件的等待时间很长。 这样就把问题分成了几大块:中断,线程,事件响应,则可以通过依次调试每个小块来确定具有原因。
下面还有1点调试技巧:
1. 测试某个线程或者某段代码执行时间:
在线程开始处或者代码开始处获取1个时间,在线程结束处或者代码结束处获取1个时间,二者
相减,则得到具体时间。(前提是时间计数器很大,不会溢出)
举例:
time_start=Hal_GetTick();
...(1)
...(2)
...(3)
use_time=Hal_GetTick()-time_start;
则可以获取(1)-(3)段代码或者线程执行时间