解決全局變量被覆寫的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,沒有觸發覆寫的邊界條件,幸運的避開了這個問題。配置

相關文章
相關標籤/搜索