解决全局变量被覆写的BUG

最近在维护一个基于STM32F4 Discovery的USB Audio项目,以前在Mac OSX环境下测试正常,但今天在Windows10上测试了下没有声音输出。
使用Keil Debug了下发如今Windows 10 USB链接下有个关于DMA配置的全局变量被莫名其妙的改写成其余值,致使I2S DMA传输出错。数组

能够发现DMA_InitStructure被改写的面目全非,难怪要出现DMA Tranfer Error了。测试

添加断点发现只要一进USB中断DMA_InitStructure就会被改写,先怀疑是中断致使的重入问题,由于这里面涉及到I2S DMA和USB 2个中断处理都会对这个全局变量进行写操做,因此屏蔽了全部对DMA_InitStructure的写操做,问题依旧。spa

后来想一想刚开始思路不对,在Mac OSX上是能正常工做的,为何在Windows10上不行呢?那必定是USB Host驱动不一样致使的问题。因而用USB分析仪对比了二者的交互流程:code

二者之间明显的区别是Windows每次第一个发起的setup token包中请求的长度都是255(应该是它能处理的最大长度),而Mac OSX则是用8, 2,9这类小的长度进行试探,这无可厚非,或许Windows更喜欢采用一次性到位的策略吧。比较了USB的整个交互过程没发现其余不一样。token

又想了想,仍是看看编译出来的map文件或许能有新的发现。果真:it

sampleBuffer                           0x20000e48   Data       57600  usbd_audio_out_if.o(.bss)
USBD_StrDesc                         0x2000ef48   Data          50  usbd_req.o(.bss)
DMA_InitStructure                  0x2000ef7c   Data          60  stm32f4_discovery_audio_codec.o(.bss)

AUDIO_MAL_DMA_InitStructure0x2000efb8   Data          60  stm32f4_discovery_audio_codec.o(.bss)io

根据经验颇有可能USBD_StrDesc越界致使把DMA_InitStructure改写了,看了下USBD_StrDesc被填充的值的末尾数据:编译

00530046不正是被改写的值吗?看了下大小是66,在代码中check了下发现USBD_StrDesc被定义为50字节的数组,难怪会出现问题,将USBD_StrDesc大小改大问题果真被解决了。变量

但一开始为何在Mac OSX上是正常的呢?是由于DMA_InitStructure是放在第一次setup token里面实现的,因为Mac OSX第一次发起的请求的长度是2,没有触发覆写的边界条件,幸运的避开了这个问题。配置

相关文章
相关标签/搜索