问题现象
客户使用 STM32H750VBT6,通过 QSPI 外扩了一个 4M 的 NOR FLASH,采用memory map 模式。当程序跳转运行到外设 FLASH 后,大约两个小时后程序死机。客户使用的 IDE 是 KEIL,此问题可以固定重现。 在 KEIL 调试模式下重现问题时,通过多次观察发现,程序死的位置总体上会停在两个位置,并不是同一个位置。一个是 TIM15函数的入口;另一个是进入中断函数后的一个赋值语句。
问题分析及测试
通过拜访客户,观察到死机位置处于即将进入 TIM15 中断入口处,但还未进入之时。查看客户的原理图,发现两个 VCAP 并未从外部相连,于是要求客户直接从外部将此两个引脚飞线短连。 但是,后来经测试问题仍然重现。
又观察到 PC13 连接为 GPIO 输出引脚,用于驱动一外部组件。 考虑到备份域相关的一些引脚其驱动能力相对弱一些,于是让客户将 PC13 引脚断开后再测试,结果问题仍然重现。
上面是一些硬件相关的怀疑点,经测试结果来看,与此问题无关。 看来主要可能还是软件方面的问题。
在软件上确定客户已经打开了 IO 补偿功能,但 IO 速度设置的是 HIGH,于是让客户修改成 “VERY_HIGH”,经测试问题仍然存在。
由于之前发生过一个从低功耗唤醒后死机的问题,是与 Cache 相关的问题,于是要测试下将 CACHE 关闭的情况。 这次经测试客户反馈问题没现重现 ! 但客户同时也反馈,之前的代码也存在稍微修改一处代码,问题就不再重现的现象,没有找到具体规律。 这次代码修改也没排除这种可能性。
为了让关闭 Cache 的方法更具效力,于是让客户在调试模式下通过手动关闭 CACHE的方式,代码仍然保持为原先可以重现问题的代码。
后记
有些人可能会问,NOR FLASH 的最后一个字节 CPU 真的会去访问吗 ? 客户的程序占满了整个 FLASH 空间了吗 ? 若那个地址没有代码那还会不会有这个问题。
其实勘误手册 2.4.4 节也提到了,不管 FSIZE 定义的空间最后的一个字节内容是什么,均会有此问题。 那么 CPU 为什么会去访问此地址呢 ? 其实这是 M7 内核的指令预取和分支预测的特性导致的。