【单片机调试】mcu调试bug记录
2023.5-2023.11
待输入
2023.12-2023.2
2024.3-至今
1.spi通信问题
现象说明:
mcu与afe芯片为spi通信:①速度很慢。 ②mos控制动作总是第二次成功,偶尔一次就能成功。
调试过程:
spi速率为4kHz(确实很慢),但是第二个现象的问题,怎么也无法定位,芯片的寄存器都和代码仔细对了一遍,逻辑分析仪的spi数据都没有问题。
解决:
①afe数据手册发现,该芯片速率最高支持10Khz,确实很慢。目前代码中使用的是模拟spi,我也改为了硬件spi,依旧很慢。【教训:先看数据手册,看看人家最高能支持到多少,再修改spi驱动】。
②询问厂商,厂商回答该芯片内部是三颗单通道的afe芯片级联而成,级联方式为spi菊花链模式,spi菊花链数据写入,是将数据依次往后面的spi从机中递推(不明白的具体百度下)。而刚好该芯片的mos控制,只能由第一个spi芯片控制,我有对比了spi波形,以及数据手册中人家说明的spi写入时序,最后发现,确实spi写入时序搞反了,没有按照人家手册说明写。
教训:
①硬件spi和模拟spi都熟悉了,以及其速率计算方式。②spi菊花链通信方式。③如何使用逻辑分析仪分析spi数据。④详细按照芯片数据手册办事。
2.记一次由全局变量自动改变而引发的问题
现象说明:
一个c文件中,定义的一个全局结构体变量,总是在程序的一个固定位置,这个位置是调用freertos的延迟函数之后,该结构体的数据成员值总是发生改变。
调试过程:
① 首先,确定看是不是自己将其数值进行了改变,经过调试发现,并未是自己改变了该变量。
② 其次,可能是发生了内存覆写现象。例如,对一个数据进行越界的写入。但是,程序中并没有这种情况。
③ 最后,变量改变总是发生在调用freertos的延迟函数之后,那么可以联想,是不是因为任务堆栈分配过小,导致内存覆盖。
验证过程:
方法① 使用freertos的栈溢出检测的钩子函数
#define configCHECK_FOR_STACK_OVERFLOW 1 /* 1: 使能栈溢出检测方法1, 2: 使能栈溢出检测方法2 */
在main函数中,定义钩子函数。
void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName )
然后,在钩子函数中打断点,通过仿真可以发现,程序停在了断点处。
方法② 使用keil工具
找一个发生覆写的数据成员,不要直接使用大的结构体。右击选择Set Access…
出现下图对话框,先点击kill all将全部断点取消,然后点击1处和2处,再点击Close即可。
然后,仿真程序直接往下run即可,仿真会停在,该数据成员内存发生改变的位置。
我的程序出现问题的位置,如下图所示。很容易看出,任务堆栈的内存溢出了。
3.由于程序增加,导致Flash的覆盖问题
现象说明:
程序中定义了一个const的结构体变量,程序运行起来之后,发现数据总是不对。
调试过程:
查看该变量内存,发现其改变后的数据,很特殊。。
因为const类型的变量,是存储在falsh中,所以其地址为0x80开头。
>看到这个数据,想到程序中有一个配置信息,就是这个数据,这个配置信息是我存储到flash中的,有可能是发生了flash占用。
解决:
我将我配置信息变量的写入地址,更改之后,程序正常了。
由于程序越写越大,新定义的const变量,被我后来存入Flash的配置信息覆盖了。