1.問(wèn)題現(xiàn)象
客戶使用 STM32H750VBT6,通過(guò) QSPI 外擴(kuò)了一個(gè) 4M 的 NOR FLASH,采用memory map 模式。當(dāng)程序跳轉(zhuǎn)運(yùn)行到外設(shè) FLASH 后,大約兩個(gè)小時(shí)后程序死機(jī)。
客戶使用的 IDE 是 KEIL,此問(wèn)題可以固定重現(xiàn)。在 KEIL 調(diào)試模式下重現(xiàn)問(wèn)題時(shí),通過(guò)多次觀察發(fā)現(xiàn),程序死的位置總體上會(huì)停在兩個(gè)位置,并不是同一個(gè)位置。一個(gè)是 TIM15函數(shù)的入口;另一個(gè)是進(jìn)入中斷函數(shù)后的一個(gè)賦值語(yǔ)句。
2.問(wèn)題分析及測(cè)試
通過(guò)拜訪客戶,觀察到死機(jī)位置處于即將進(jìn)入但還未進(jìn)入的TIM15 中斷入口處。查看客戶的原理圖,發(fā)現(xiàn)兩個(gè) VCAP 并未從外部相連,于是要求客戶直接從外部將此兩個(gè)引腳飛線短連。但是,后來(lái)經(jīng)測(cè)試問(wèn)題仍然重現(xiàn)。
又觀察到 PC13 連接為 GPIO 輸出引腳,用于驅(qū)動(dòng)一外部組件。考慮到備份域相關(guān)的一些引腳其驅(qū)動(dòng)能力相對(duì)弱一些,于是讓客戶將 PC13 引腳斷開(kāi)后再測(cè)試,結(jié)果問(wèn)題仍然重現(xiàn)。
上面是一些硬件相關(guān)的懷疑點(diǎn),從測(cè)試結(jié)果來(lái)看,與此問(wèn)題無(wú)關(guān)??磥?lái)主要可能還是軟件方面的問(wèn)題。在軟件上確定客戶已經(jīng)打開(kāi)了 IO 補(bǔ)償功能, IO 速度設(shè)置的是 HIGH,即使讓客戶修改成 “VERY_HIGH”,經(jīng)測(cè)試問(wèn)題仍然存在。
由于之前發(fā)生過(guò)一個(gè)從低功耗喚醒后死機(jī)的問(wèn)題,是與 Cache 相關(guān)的問(wèn)題,于是測(cè)試將 CACHE 關(guān)閉的情況。這次經(jīng)測(cè)試客戶反饋問(wèn)題沒(méi)再重現(xiàn) !
但客戶同時(shí)也反饋,之前的代碼也存在稍微修改一處代碼,問(wèn)題就不再重現(xiàn)的現(xiàn)象,沒(méi)有找到具體規(guī)律。
這次代碼修改也沒(méi)排除這種可能性。為了讓關(guān)閉 Cache 的方法更具說(shuō)服力,于是讓客戶在調(diào)試模式下通過(guò)手動(dòng)關(guān)閉 CACHE的方式,代碼仍然保持為原先可以重現(xiàn)問(wèn)題的代碼。如下圖所示 :

如上圖所示,在代碼運(yùn)行到使用 CACHE 后一行設(shè)置斷點(diǎn),當(dāng)程序停下來(lái)后,打開(kāi) Sys Ctrl/Cfg 窗口(菜單 view->system viewer->Core peripherals->system control and configuration),將對(duì)應(yīng)的位去掉。最終客戶反饋,關(guān)閉 DC,或者 IC 任何一個(gè)或者兩個(gè)都關(guān)閉,問(wèn)題現(xiàn)象消失。至此可以確定地是,此問(wèn)題與 CACHE 相關(guān) !
于是查看客戶的 MPU 相關(guān)配置,并將 Cube 包里的 H750 示例工程中的 MPU 配置發(fā)給客戶測(cè)試下,但問(wèn)題仍然存在。
接下來(lái)查看勘誤手冊(cè),發(fā)現(xiàn) 2.4.4 節(jié)有 QSPI 相關(guān)的內(nèi)容:

這里有提到在 QSPI 外設(shè) FLASH 并工作在 memory-mapped 模式的時(shí)候,當(dāng)讀取由FSIZE 定義的最后一個(gè)字節(jié)的時(shí)候,不管內(nèi)容如何,有可能會(huì)導(dǎo)致 AXIs 總線 STALL 掉。
并同時(shí)給出了三種規(guī)避措施。其中第一種是將 FSIZE 定義得比實(shí)際大,以留有足夠的裕量。于是讓客戶修改代碼:在 QSPI 初始化時(shí)將 size 設(shè)置成大一倍:
面紅色部分表示的 nor flash 設(shè)置成實(shí)際的兩倍大小。
同時(shí)考慮到此處定義了實(shí)際兩倍大小的 FLASH,多出來(lái)的另外一半實(shí)際是不存在的,為了避免 CPU 意外訪問(wèn)這個(gè)實(shí)際不存在的區(qū)域,使用 MPU“告訴”CPU 這多出來(lái)的一半?yún)^(qū)間是不可訪問(wèn)的。
于是 MPU 按如下來(lái)配置:
使用串口終端工具,分別連接 USART1,USART3,發(fā)送對(duì)應(yīng)的 UART Bootloader 命令,得到下圖 3 的命令交互。

圖3.MPU 配置
客戶再次測(cè)試,問(wèn)題不再重現(xiàn)。為了進(jìn)一步驗(yàn)證問(wèn)題,客戶嘗試按原先的代碼直接讀取 NOR FLASH 的最后一個(gè)字節(jié),問(wèn)題還會(huì)重現(xiàn),再次驗(yàn)證此方法的有效性,至此問(wèn)題解決。
3.后記
有些人可能會(huì)問(wèn),NOR FLASH 的最后一個(gè)字節(jié) CPU 真的會(huì)去訪問(wèn)嗎 ? 客戶的程序占滿了整個(gè) FLASH 空間了嗎 ? 若那個(gè)地址沒(méi)有代碼那還會(huì)不會(huì)有這個(gè)問(wèn)題。
其實(shí)勘誤手冊(cè) 2.4.4 節(jié)也提到了,不管 FSIZE 定義的空間最后的一個(gè)字節(jié)內(nèi)容是什么,均會(huì)有此問(wèn)題。那么 CPU 為什么會(huì)去訪問(wèn)此地址呢 ? 其實(shí)這是 M7 內(nèi)核的指令預(yù)取和分支預(yù)測(cè)試探性訪問(wèn)導(dǎo)致的。
在 M7 編程手冊(cè)中可以找到如下內(nèi)容:

正是上述特性才導(dǎo)致 CPU 會(huì)提前訪問(wèn) NOR FLASH 上的地址,即使當(dāng)前 PC 指針還未指到那里。我們可以通過(guò)合適的MPU配置防止因試探性訪問(wèn)外存而導(dǎo)致問(wèn)題。
參考文獻(xiàn):
1. PM0235:STM32F7 Series and STM32H7 Series Cortex?-M7 processor programming manua.
2. ES0396:STM32H750xB and STM32H753xI device limitations.
3. AN4838:Managing memory protection unit in STM32 MCUs.
4. AN4893:Level 1 cache on STM32F7 Series and STM32H7 Series.
來(lái)源:STM32單片機(jī)
免責(zé)聲明:本文為轉(zhuǎn)載文章,轉(zhuǎn)載此文目的在于傳遞更多信息,版權(quán)歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權(quán)問(wèn)題,請(qǐng)聯(lián)系小編進(jìn)行處理
審核編輯 黃宇
-
FlaSh
+關(guān)注
關(guān)注
10文章
1747瀏覽量
155482 -
STM32H750
+關(guān)注
關(guān)注
1文章
16瀏覽量
2499
發(fā)布評(píng)論請(qǐng)先 登錄
程序運(yùn)行在STM32H750的外擴(kuò)FLASH上兩小時(shí)后死機(jī)該如何處理
評(píng)論