大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家介紹的是i.MXRT1064片內(nèi)Flash的RESET#引腳對程序啟動和運行的影響。
上一篇文章?《i.MXRT1024/1064片內(nèi)4MB Flash的SFDP表易丟失導致的燒錄異?!?痞子衡帶大家初步了解了 i.MXRT 上片內(nèi)合封的 4MB Flash,合封 Flash 方式一般來說比外掛方式要省事省心,但前提是你充分了解了它的合封方式、信號連接等細節(jié)。如果對這些細節(jié)沒有完全掌握,合封就像是一個黑盒子,還真不一定就比外掛可靠。
近期另有一個 RT1064 客戶反饋,產(chǎn)品在運行過程中會發(fā)生極小概率的宕機,分析發(fā)現(xiàn)宕機時(不斷電情況下)內(nèi)部 Flash 讀回的程序數(shù)據(jù)竟然全是 0x00,看起來 Flash 內(nèi)容被篡改了,但是重新上電又能正常工作,這是怎么回事?今天痞子衡就和大家聊聊這個話題:
- Note:本文所述問題僅在 RT1064 上發(fā)生,不存在于 RT1024 上。
一、RT1024/1064片內(nèi)Flash連接差異
1.1 W25Q32JV不同封裝
我們知道 RT1024/RT1064 內(nèi)部合封得是 Winbond W25Q32JV 裸 Die,而 W25Q32JV 作為單獨產(chǎn)品售賣時實際上提供了非常多的封裝形式,這其中我們最熟悉得是經(jīng)典的 8 個引腳的 SOIC-8 208-mil 封裝。
從 W25Q32JV 裸 Die 本身角度來說,其一共有 9 個信號線,在 SOIC-8 上將本該單獨引出的 RESET# 信號復(fù)用到了 IO3 上(雖然這個腳本身還有一個 HOLD# 復(fù)用),而在 SOIC-16 或者 TFBGA-24 上我們就能看到這個單獨的 RESET# 信號了:
1.2 RT1024片內(nèi)RESET#連接
在 RT1024 上,內(nèi)部 Flash 的 RESET# 信號保留懸空(或其它處理),并沒有和 RT1020 之間有信號連接,這里 GPIO_AD_B1_13 被著重強調(diào),是因為 RT1024 BootROM 會根據(jù) efuse 配置情況控制這個 I/O 來復(fù)位 Flash(顯然這里是無效的)。
1.3 RT1064片內(nèi)RESET#連接
在 RT1064 上,內(nèi)部 Flash 的 RESET# 信號被連接到了 RT1060 內(nèi)部信號 GPIO_SPI_B0_13 上,當然 RT1064 BootROM 也會根據(jù) efuse 配置情況控制這個 I/O 來復(fù)位 Flash(這時就會產(chǎn)生一定作用)。
二、不處理片內(nèi)Flash RESET#信號帶來的風險
在痞子衡舊文?《深入i.MXRT系列ROM中串行NOR Flash啟動初始化流程》?一文?2.1 復(fù)位Flash芯片?小節(jié)里,我們知道如果 efuse 里 RESET# 相關(guān) bit 被燒寫使能后,RT1064 BootROM 才會初始化 GPIO_SPI_B0_13 引腳為 GPIO 輸出模式,并且拉低拉高一次來復(fù)位 Flash,等復(fù)位結(jié)束 GPIO_SPI_B0_13 會保持高電平輸出。
// RT1064 上 RESET# 相關(guān)的 fuse
fuse 0x6e0[7] ?- FLEXSPI_RESET_PIN_EN
? ? ? ? 0 - Disable
? ? ? ? 1 - Enable
fuse 0x6e0[31] - FLEXSPI_RESET_PIN_SEL
? ? ? ? 0 - GPIO_SPI_B0_00
? ? ? ? 1 - GPIO_SPI_B0_13
但是默認情況下,RT1064 芯片出廠以及客戶都不會去燒寫跟這個 RESET# 相關(guān)的 efuse,這意味著 GPIO_SPI_B0_13 內(nèi)部引腳會一直保持上電默認狀態(tài),那么默認是什么狀態(tài)呢?這從 IOMUXC_SW_PAD_CTL_PAD_GPIO_SPI_B0_13 寄存器默認值 0x10B0 可以得知其為輸入 Keeper 狀態(tài)。
我們知道 RESET# 信號對 Flash 來說也是輸入(從 Winbond 技術(shù)人員處得知,該信號內(nèi)部有 280K 歐姆上拉),兩個引腳相連,各自都是輸入狀態(tài),顯然有點不太可靠。說一種極端情況,芯片上電過程中,在 Flash 端弱上拉對 RESET# 作用讓電壓爬升到有效高電平 VCC x 0.7 之前,RT1060 的 GPIO_SPI_B0_13 端輸入 Keeper 狀態(tài)先產(chǎn)生作用,這時就會產(chǎn)生一個弱下拉,由于不同芯片的器件特性差異,這里的弱上拉/下拉都存在一定的誤差范圍,最終極有可能導致 RESET# 電平處于中間不定態(tài)。此外哪怕芯片上電過程中沒問題,實際運行中,由于片內(nèi)溫度電磁環(huán)境等各方面因素,導致 RESET# 信號發(fā)生翻轉(zhuǎn),對 XIP 程序運行穩(wěn)定性也是毀滅性打擊。
三、解決RESET#信號穩(wěn)定性的方案
為了驗證 GPIO_SPI_B0_13 信號狀態(tài)對于 RT1064 影響,痞子衡在測試 SFDP 工程里加上了這個信號的控制,當 GPIO_SPI_B0_13 輸出為低時,即 Flash RESET# 處于有效狀態(tài),此時 Flash SFDP 都不能正常讀出,更別提內(nèi)存數(shù)據(jù)讀取操作了。
- 燒錄SFDP工程:https://github.com/JayHeng/func-imxrt-sip-flash-sfdp-check
那么該如何解決這個問題呢?上述原理知道后,其實方法就特別簡單了:
- 解決啟動問題:燒寫 fuse 0x6e0[31,7] 兩個位,讓 BootROM 去初始化 GPIO_SPI_B0_13 引腳。(大約增加 750us 啟動時間)解決跑飛問題:假如芯片沒有啟動問題,但你不想額外燒寫 fuse,那么 XIP App 運行起來后第一件事就是初始化 GPIO_SPI_B0_13 為 GPIO 輸出模式,并且設(shè)為高電平。(為了可靠性,這部分代碼可以 RAMFUNC 運行)
至此,不處理i.MXRT1064片內(nèi)Flash的RESET#引腳可能會導致無法啟動或程序跑飛痞子衡便介紹完畢了,掌聲在哪里~~~