大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家介紹的是導(dǎo)致串行 NOR Flash 在 i.MXRT 下無(wú)法正常下載 / 啟動(dòng)的常見因素之 SFDP。
i.MXRT 系列 MCU 發(fā)布已兩年多了,基于 i.MXRT 的客戶產(chǎn)品也越來(lái)越多,可以說(shuō)是全面開花了。痞子衡作為 i.MXRT 產(chǎn)品線的系統(tǒng)應(yīng)用工程師,早期的時(shí)候還可以盡情做參考設(shè)計(jì),現(xiàn)在基本大量時(shí)間都被客戶支持占據(jù)了。
因?yàn)?i.MXRT 系列都沒有內(nèi)置 Flash(RT1064, RT1024 等 SIP 型號(hào)除外),因此為其搭配一塊串行 NOR Flash 去啟動(dòng)是客戶項(xiàng)目的第一個(gè)頭等大事,而串行 NOR Flash 廠商非常多,客戶選擇余地很大,因此我們不得不與客戶一起同茫茫 Flash 型號(hào)打交道,痞子衡也常常調(diào)侃自己已淪為 Flash 測(cè)試工程師。
痞子衡在支持客戶解決串行 NOR Flash 下載啟動(dòng)問(wèn)題過(guò)程中主要遇到幾個(gè)常見因素,這幾個(gè)因素可能會(huì)影響 Flash 在 i.MXRT 下無(wú)法正常使用,今天痞子衡就重點(diǎn)跟大家聊聊 SFDP 這個(gè)因素。
一、SFDP 標(biāo)準(zhǔn)簡(jiǎn)介
SFDP 又叫 JESD216,是 JEDEC 協(xié)會(huì)于 2011 年開始推出的串行 Flash 接口標(biāo)準(zhǔn),類似于 CFI 在并行 NOR Flash 上的標(biāo)準(zhǔn)。SFDP 發(fā)展至今已經(jīng)誕生了如下版本:
時(shí)間 | 標(biāo)準(zhǔn) |
---|---|
2011 | JESD216 |
2013.07 | JESD216A |
2014.05 | JESD216B |
2018.08 | JESD216C |
2018.11 | JESD216D |
2019.08 | JESD216D.01 |
?
我們知道串行 Flash 廠商非常多,在 2011 年之前,大家都是各自玩,沒有明確的統(tǒng)一標(biāo)準(zhǔn)(雖然幾個(gè)領(lǐng)頭廠商起了示范作用,但各家在具體細(xì)節(jié)上還是會(huì)有差異),這對(duì)于 Flash 用戶來(lái)說(shuō)就比較麻煩了,需要把各家 Flash 手冊(cè)仔細(xì)研讀,不能漏掉任何一個(gè)細(xì)節(jié)。
隨著串行 Flash 市場(chǎng)需求越來(lái)越強(qiáng)烈,各個(gè)廠商也在鉚足勁給自家 Flash 加特性,這時(shí)候 JEDEC 站出來(lái)了,拉了幾個(gè)主要的 Flash 廠商一起訂個(gè) SFDP 標(biāo)準(zhǔn),有了這個(gè)標(biāo)準(zhǔn),F(xiàn)lash 用戶就方便多了,尤其是軟件設(shè)計(jì)人員,開發(fā) Flash 驅(qū)動(dòng)從此有標(biāo)準(zhǔn)可依,甚至一套驅(qū)動(dòng)可以用在所有支持 SFDP 標(biāo)準(zhǔn)的 Flash 上,實(shí)現(xiàn)各廠商 Flash 之間輕松切換。
二、部分 Flash 型號(hào)不支持 SFDP
因?yàn)?SFDP 標(biāo)準(zhǔn)是 2011 年才開始推出,新興 Flash 廠商(比如兆易創(chuàng)新)的產(chǎn)品基本都是支持 SFDP 標(biāo)準(zhǔn)的,而部分老牌 Flash 廠商(比如華邦)則存在老型號(hào)和新型號(hào)共存的問(wèn)題。老型號(hào)都是 2011 年前設(shè)計(jì)生產(chǎn)的,不支持 SFDP;2011 年之后設(shè)計(jì)的新型號(hào)基本都是支持 SFDP 的。
華邦目前是串行 Flash 第一大廠商,痞子衡遇到好幾個(gè) i.MXRT 客戶,選用的華邦 NOR Flash,但 Flash 里不支持 SFDP,因此客戶支持稍微復(fù)雜一些。關(guān)于 SFDP 支持問(wèn)題,痞子衡特別聯(lián)系過(guò)華邦銷售人員,得到了他們的答復(fù),華邦 NOR Flash 家族里 W25QxxJV 和 W25QxxJW 系列都是新型號(hào),全部支持 SFDP;而 W25QxxFV 和 W25QxxFW 系列屬于老型號(hào),大多沒有 SFDP,但是也有如下部分型號(hào)支持 SFDP:
雖然我們可以在后續(xù)開發(fā)的過(guò)程中也能正常使用非 SFDP 標(biāo)準(zhǔn)的 Flash 以及能通過(guò)讀 SFDP 命令查詢出芯片是否支持 SFDP,但最好在 Flash 選型前就能明確知道其 SFDP 情況,這個(gè)需要跟 Flash 廠商銷售溝通好??傊?,痞子衡推薦大家選用各廠商支持 SFDP 標(biāo)準(zhǔn)的新型號(hào)。
三、不支持 SFDP 的 Flash 如何適用 i.MXRT 下載
如果你認(rèn)真看過(guò)痞子衡寫的 i.MXRT 啟動(dòng)系列文章,你應(yīng)該知道 i.MXRT 之所以能夠支持市面上幾乎所有的串行 NOR Flash 啟動(dòng)是靠的 512 byte 的 FDCB 結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體原型即 flexspi_nor_config_t,它可以描述啟動(dòng)所需的所有 Flash 參數(shù)信息。
i.MXRT 在啟動(dòng)時(shí)首先會(huì)用 1bit SDR 時(shí)序模式去獲取用戶放在 Flash 開始或偏移 0x400 處(因 i.MXRT 型號(hào)而異)的 FDCB,然后根據(jù) FDCB 里的信息去進(jìn)一步配置啟動(dòng),因此 Flash 里有無(wú) SFDP 其實(shí)不影響啟動(dòng),只要在 FDCB 里描述清楚即可。
但是 Flash 里有無(wú) SFDP 非常影響在 i.MXRT 相關(guān)配套工具下的擦寫操作(俗稱下載),因?yàn)樗泄ぞ撸↗Link、各 IDE、ROM 配套 Flashloader、痞子衡的 MCUBootUtility)默認(rèn)都是基于 SFDP 來(lái)設(shè)計(jì) Flash 下載算法的。
僅以 ROM 配套 Flashloader 為例,其上位機(jī)工具是 blhost.exe,它有如下經(jīng)典的命令序列。這個(gè)序列就是利用用戶提供簡(jiǎn)化的串行 Flash 配置值 0xc0000007(描述一般的四線 QSPI)來(lái)初始化 FlexSPI 以及 Flash,為后續(xù)擦寫操作做準(zhǔn)備。
blhost -u -- fill-memory 0x20202000 4 0xc0000007
blhost -u -- configure-memory 0x9 0x20202000
configure-memory 命令底層到底是什么樣的邏輯呢?讓我們找到任何一個(gè) SDK 包,在 SDK_2.x.x_MIMXRTxxxx-EVKmiddlewaremcu-bootsrcmemorysrcflexspi_nor_memory.c 里可以找到如下函數(shù) flexspi_nor_mem_config(),它就是其底層邏輯,在這個(gè)函數(shù)里我們可以看到,F(xiàn)lashloader 會(huì)判斷傳來(lái)的 config 值到底是簡(jiǎn)化的 serial_nor_config_option_t,還是完整的 flexspi_nor_config_t。
?
如果 config 是簡(jiǎn)化的 serial_nor_config_option_t,F(xiàn)lashloader 會(huì)調(diào)用 flexspi_nor_get_config()函數(shù)去自動(dòng)填充生成完整的 flexspi_nor_config_t,你可以繼續(xù)去看 flexspi_nor_get_config()函數(shù)的實(shí)現(xiàn),對(duì)于普通四線 QSPI,其就是根據(jù) Flash 里讀回的 SFDP 表內(nèi)容來(lái)做的填充,因此這種方式下 SFDP 不可缺。
?
status_t flexspi_nor_mem_config(uint32_t *config)
{
? ? status_t status = kStatus_InvalidArgument;
? ? bool isNorConfigOption = false;
? ? serial_nor_config_option_t *option = (serial_nor_config_option_t *)config;
? ? flexspi_nor_config_t *norConfig = (flexspi_nor_config_t *)config;
? ? if (option->option0.B.tag == kSerialNorCfgOption_Tag)
? ? {
? ? ? ? status = flexspi_nor_get_config(s_flexspiNorContext.instance, &s_flexspiNorConfigBlock, option);
? ? ? ? // ...
? ? ? ? isNorConfigOption = true;
? ? }
? ? else if (norConfig->memConfig.tag == FLEXSPI_CFG_BLK_TAG)
? ? {
? ? ? ? memcpy(&s_flexspiNorConfigBlock, norConfig, sizeof(flexspi_nor_config_t));
? ? ? ? isNorConfigOption = true;
? ? }
? ? // ...
? ? if (isNorConfigOption)
? ? {
? ? ? ? status = flexspi_nor_flash_init(s_flexspiNorContext.instance, &s_flexspiNorConfigBlock);
? ? ? ? // ...
? ? }
? ? return status;
}
上面這種 0xc0000007 搞定一切四線 QSPI 的方式僅適用于含 SFDP 的 Flash,對(duì)于不含 SFDP 的 Flash 怎么辦呢。其實(shí)上面已經(jīng)給了解決方法,那就是直接提供完整的 FDCB,因此 i.MXRT 相關(guān)配套工具下載算法都需要相應(yīng)改一下,痞子衡在兩個(gè)項(xiàng)目上都做了非 SFDP Flash 支持:
- J-Link 下載算法源工程,可以參考 /boards/msft_rt600_xproject/flash_algo_b0_silicon/Keil_JLink 這個(gè)源工程
- MCUBootUtility v2.3 更新,參看文章 《MCUBootUtility v2.3 發(fā)布,這次不再放過(guò)任何一款 Flash》 第 2.3 節(jié)
至此,導(dǎo)致串行 NOR Flash 在 i.MXRT 下無(wú)法正常下載 / 啟動(dòng)的常見因素之 SFDP 痞子衡便介紹完畢了,掌聲在哪里~~~