STM32f4xx/Cortex-M4 芯片内存被随机修改问题

我在STM32f405芯片上开发蓝牙接收功能,发现从发送端过来的数据,居然会被随机修改。非常诡异的是,我的实验发现,缓存数组经常是某个位置如i的数据不对,而i-1和i+1的位置和其他位置都是正确的。为排查该问题,

我首先怀疑蓝牙数据传送出错。后来问AI得知蓝牙传输物理层面因为有空口确实有可能有出错,但是模块本身有纠错和重传机制,对于应用层不用考虑这个问题。另外,我通过调试信息发现在DMA接收中断的时刻,绑定的接收circular buffer中的数据是完全正确的。我用的方法是发送方从0开始,不断加1发送数据,接收端同样从0开始接收,预期下一个接收到的字节是上一个+1。数据完全对的上,这就排除了蓝牙模块的问题。

但是从DMA绑定的circular buffer拷贝到程序另开的缓存buffer,仅仅是memcpy,完后再查这个缓存buffer,发现数据就有随机不正确的。我也通过头尾指针比较排除了由于数据来得太快,缓存来不及处理的overflow问题。memcpy也很稳定,不可能出现拷贝出错。

那这个问题很奇怪,我从AI中获得了提示,有可能是stack太小了,出现了stack overflow。

芯片的stack size在 startup_stm32f405xx.s中定义,

;* <<< Use Configuration Wizard in Context Menu >>>

;

; Amount of memory (in bytes) allocated for Stack

; Tailor this value to your application needs

; <h> Stack Configuration

; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>

; </h>

Stack_Size EQU 0x0400

stack size只有1024 byte,但我的代码里有这么一段:

void Bt_Task(void)

{

u8 batch_bufBT_STREAM_FIFO_LEN;

其中,BT_STREAM_FIFO_LEN 是1024。因为batch_buf是这个函数的local变量,它会分配在stack里,stack本身只有1K Byte,这样立马就stack overflow了,内容会拓展到其他内存空间,出现unexpected error就很正常了。

解决方案:

  1. 把stack空间改大。因为改芯片的SRAM有128K Bytes,把stack空间增加到4K Bytes问题不大。

Stack_Size EQU 0x1000

  1. 不创建大容量local数组,把数组移到全局变量,全局变量不占用stack空间。

这么改以后,内存中的数据就完全正常了。