NMI interrupt trigger issue
前言
客戶使用STM32G491MCT6料號,但遇到試產階端有部分料件在讀Flash會卡住,這邊因在一般測試都沒有遇到,只能靠經驗摸索,使用PC counter最後發現所提的位置都在NMI interrupt,這個問題找尋資料偏少,由此紀錄一下。
NMI Interrupt介紹
在計算中,不可屏蔽中斷(NMI)是一種硬件中斷,系統的標準中斷屏蔽技術無法忽略它。這樣做通常是為了警告不可恢復的硬件錯誤。某些 NMI 可能會被屏蔽,在這種情況下,您應該使用您自己的特定於特定 NMI 的方法。 當響應時間至關重要或在正常系統操作期間不應禁用中斷時,通常會使用 NMI。此類用途包括報告不可恢復的硬件錯誤、系統調試和分析以及處理系統重置等特殊情況。
可以看到圖表會觸發NMI中斷的有SRAM parity error/Flash ECC/HSE CSS
Case1:Clock security (CSS)
configuring HSE and CSS in RCC, and shorting one of the HSE pins to something else, but it might void your warranty.
SCB->ICSR |= SCB_ICSR_NMIPENDSET;
這邊解法基本上就是去看HSE等硬體問題
Case2:SRAM parity error
The parity bits are computed and stored when writing into the SRAM. Then, they are
automatically checked when reading. If one bit fails, an NMI is generated.
這邊解法:Reset MC或檢查硬體問題(但這部分目前還沒遇到有遇到後續再補上相關解法)
Case3:Flash ECC
當在使用者程式中,對某一特定FLASH區域進行擦寫和再寫入,就會機率性觸發該錯誤。
觸發ECCD錯誤後,即便在NMI中斷中清零ECCD的標誌位,退出中斷後又會馬上觸發,就算程式中根本沒有用到問題區域的數據,造成死循環。 如果不觸發ECCD錯誤的話,也會大概率觸發ECCC錯誤;更多的一種情況是,沒有觸發ECCC錯誤(標誌位為0),但是ADDR_ECC的值改變了,指向的也確實是有問題的區域 ;
- 只擦寫而不再寫入的話不會觸發;
- 對其他區域進行操作不會觸發,問題區域大概10~20個位元組以內;
- 問題跟隨PCBA,其他PCBA不會觸發。
解法
- 最小限度依賴flash數據。 讀取flash發生ECCC/ECCD錯誤進入NMI中斷時,清除中斷標誌位,並執行Flash擦除指令。
- 在 1的基礎上使用預設參數恢復flash資料。 讀取FLASH時發生NMI中斷,在中斷中清除中斷標誌位後,可以在NMI中斷中設定一個標誌位,當程式回到Main後,檢查該標誌位,如果被置位了,表示發生了ECC錯誤 ,需要使用預設參數(預設參數可以使用固定位址的陣列來組織到C語言原始碼中)來恢復Flash的資料。
- 寫Flash發生NMI中斷。 在NMI中斷中重新擦寫Flash,直到資料寫入正確,或根據產品編寫其他實作邏輯。