你們好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給你們分享的是FlexSPI復位方式不當會致使i.MXRT系列下OTFAD加密啓動失敗問題。html
本篇是《系統時鐘配置不當會致使i.MXRT1xxx系列下OTFAD加密啓動失敗》 的後續篇,咱們爲i.MXRT1010解決了OTFAD時鐘配置限制問題後,加密的App就必定能正常跑了嗎?其實並不必定,若是你的App跟IAP有關(即會調用FlexSPI驅動去擦寫Flash),免不了會在FlexSPI驅動裏操做FlexSPI外設寄存器的軟復位位,軟復位操做方式使用不當可能會致使App沒法正常運行,今天痞子衡就來好好聊一聊這個FlexSPI復位小限制:微信
- Note1: 雖然i.MXRT1170也包含OTFAD,可是本文中的FlexSPI復位限制問題在i.MXRT1170上並不存在。
- Note2: 三位數系列i.MXRT600一樣包含OTFAD,且也受本文中的FlexSPI復位限制影響。
從恩智浦官網下載一個SDK包(痞子衡下的是v2.9.1),選擇其中 flexspi 例程 \SDK\boards\evkmimxrt1010\driver_examples\flexspi\nor\polling_transfer\ 。編譯這個 flexspi_nor_polling_transfer 工程(選擇 flexspi_nor_debug build,即XIP工程),獲得可執行文件,將其下載到 MIMXRT1010-EVK 板載Flash中離線啓動(正常模式,不加密),打開串口調試助手看到以下結果:app
這個結果是例程預期結果,你可能會對這個XIP build也能擦寫Flash感到奇怪,按說板載Flash沒有RWW功能,擦寫Flash操做不能在Flash裏原地執行,可是例程的連接文件裏已經將涉及Flash擦寫代碼的源文件直接放在RAM裏了,所以例程是能夠正常執行的。函數
如今讓咱們根據《系統時鐘配置不當會致使i.MXRT1xxx系列下OTFAD加密啓動失敗》 文中操做使能OTFAD加密,將整個App空間都加密,記得要修復系統時鐘配置限制問題,這時候再離線啓動,看到串口調試助手沒有任何輸出,說明例程執行失敗了。查看工程源代碼,main()函數裏第一句打印前調用了 flexspi_nor_flash_init(EXAMPLE_FLEXSPI);, 看起來OTFAD加密後這個Flash初始化函數執行不太正常。flex
爲了定位問題方便,咱們回到不加密模式,給 flexspi_nor_polling_transfer 工程加上一些輔助調試的打印信息,主要是FlexSPI相關API函數調用前加上打印信息。注意:須要將以下三個源文件也放到RAM中才能看到控制檯完整輸出。ui
initialize by copy { object fsl_debug_console.o, object fsl_adapter_lpuart.o, object fsl_lpuart.o, };
有了輔助打印信息,咱們如今再回到OTFAD加密模式,能夠看到代碼停在 FLEXSPI_UpdateLUT() 函數就沒有繼續執行下去了。本文不是爲了講述如何一步步找到問題的方法,痞子衡其實知道就是 FLEXSPI_SoftwareReset() 函數惹的禍(沒有停在這個函數,是因爲系統buffer的緣故),至因而什麼緣由,詳見下節。加密
static inline void FLEXSPI_SoftwareReset(FLEXSPI_Type *base) { base->MCR0 |= FLEXSPI_MCR0_SWRESET_MASK; while (0U != (base->MCR0 & FLEXSPI_MCR0_SWRESET_MASK)) { } }
老規矩,痞子衡直接給答案,這是OTFAD對FlexSPI外設復位的小限制,當OTFAD被使能時,若是被加密的app代碼是XIP執行,app裏利用FlexSPI->MCR0[SWRESET]位作復位時,這個swreset復位功能會同時清掉FlexSPI->INTR[KEYDONE]位,而FlexSPI的運行依賴OTFAD解析KeyBlob的結果,當FlexSPI->INTR[KEYDONE]位是0時,對Flash的AHB訪問會被禁掉,故而發生CPU lockup,代碼沒法繼續執行。.net
KEYDONE位爲1 - 代表OTFAD解析KeyBlob已正常完成; KEYDONE位爲0 - 代表OTFAD正在解析KeyBlob過程當中;
FlexSPI->MCR0[SWRESET]位存在於任何一款i.MXRT芯片型號中,其功能是復位FlexSPI外設,在下面幾個場景均可以去作一次FlexSPI外設復位,不用擔憂,這個外設復位並不影響FlexSPI配置寄存器裏的值。不過比較遺憾的是在此時的OTFAD加密啓動使能情形下,不能再用MCR0[SWRESET]位去作復位了 。debug
場景一:初始化FlexSPI,打開MCR0[MDIS]位使能模塊時 場景二:更新了FlexSPI的LUT表後 場景三:切換了FlexSPI的工做模式後(好比使能Flash四線) 場景四:完成了FlexSPI的擦、寫命令後
不少時候FlexSPI->MCR0[SWRESET]位更可能是被用來清除AHB TX/RX Buffer(尤爲是在Flash擦寫以後),在i.MXRT1010 FlexSPI外設的AHBCR寄存器裏其實新增了單獨的CLRAHBTXBUF和CLRAHBRXBUF控制位,用以實現AHB TX/RX Buffer的清除。所以咱們爲了不影響OTFAD加密啓動,可使用AHBCR[CLRAHBTXBUF/CLRAHBRXBUF]位來代替MCR0[SWRESET]位去作復位。調試
所以在 flexspi_nor_polling_transfer 工程裏,將FLEXSPI_SoftwareReset()函數調用所有改爲以下的FLEXSPI_ClearAhbBuffer()函數調用就能夠保證工程正常運行了。
static inline void FLEXSPI_ClearAhbBuffer(FLEXSPI_Type *base) { #if defined(FSL_FEATURE_SOC_OTFAD_COUNT) && defined(FLEXSPI_AHBCR_CLRAHBRXBUF_MASK) base->AHBCR |= FLEXSPI_AHBCR_CLRAHBRXBUF_MASK | FLEXSPI_AHBCR_CLRAHBTXBUF_MASK; base->AHBCR &= ~(FLEXSPI_AHBCR_CLRAHBRXBUF_MASK | FLEXSPI_AHBCR_CLRAHBTXBUF_MASK); #endif }
至此,FlexSPI復位方式不當會致使i.MXRT系列下OTFAD加密啓動失敗問題痞子衡便介紹完畢了,掌聲在哪裏~~~
文章會同時發佈到個人 博客園主頁、CSDN主頁、知乎主頁、微信公衆號 平臺上。
微信搜索"痞子衡嵌入式"或者掃描下面二維碼,就能夠在手機上第一時間看了哦。