大家好,我是痞子衡,是正經搞技術的痞子,今天痞子衡給大家分享的是FlexSPI復位方式不當會導致i.MXRT系列下OTFAD加密啟動失敗問題,
本篇是《系統時鐘配置不當會導致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中離線啟動(正常模式,不加密),打開串口除錯助手看到如下結果:

這個結果是例程預期結果,你可能會對這個XIP build也能擦寫Flash感到奇怪,按說板載Flash沒有RWW功能,擦寫Flash操作不能在Flash里原地執行,但是例程的鏈接檔案里已經將涉及Flash擦寫代碼的源檔案直接放在RAM里了,因此例程是可以正常執行的,

現在讓我們根據《系統時鐘配置不當會導致i.MXRT1xxx系列下OTFAD加密啟動失敗》 文中操作使能OTFAD加密,將整個App空間都加密,記得要修復系統時鐘配置限制問題,這時候再離線啟動,看到串口除錯助手沒有任何輸出,說明例程執行失敗了,查看工程源代碼,main()函式里第一句列印前呼叫了 flexspi_nor_flash_init(EXAMPLE_FLEXSPI);, 看起來OTFAD加密后這個Flash初始化函式執行不太正常,
為了定位問題方便,我們回到不加密模式,給 flexspi_nor_polling_transfer 工程加上一些輔助除錯的列印資訊,主要是FlexSPI相關API函式呼叫前加上列印資訊,注意:需要將如下三個源檔案也放到RAM中才能看到控制臺完整輸出,
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,代碼無法繼續執行,
KEYDONE位為1 - 表明OTFAD決議KeyBlob已正常完成;
KEYDONE位為0 - 表明OTFAD正在決議KeyBlob程序中;

FlexSPI->MCR0[SWRESET]位存在于任何一款i.MXRT芯片型號中,其功能是復位FlexSPI外設,在下面幾個場景都可以去做一次FlexSPI外設復位,不用擔心,這個外設復位并不影響FlexSPI配置暫存器里的值,不過比較遺憾的是在此時的OTFAD加密啟動使能情形下,不能再用MCR0[SWRESET]位去做復位了 ,
場景一:初始化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主頁、知乎主頁、微信公眾號 平臺上,
微信搜索"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機上第一時間看了哦,

轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/266190.html
標籤:其他
