大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家介紹的是超級下載算法開發(fā)筆記(4)之輪詢Flash配置參數(shù)。
文接上篇 《超級下載算法(RT-UFL)開發(fā)筆記(3) - 統(tǒng)一FlexSPI驅(qū)動訪問》,現(xiàn)在超級下載算法中已經(jīng)集成了BootROM版本的統(tǒng)一FlexSPI驅(qū)動,原則上BootROM能支持啟動的所有串行NOR Flash型號,超級下載算法都可以對其進(jìn)行擦寫操作。BootROM雖然可以支持很多種不同的Flash,但其需要依賴用戶提供一個名為FDCB的配置結(jié)構(gòu)體放置在Flash固定偏移處,BootROM先配置FlexSPI為1bit SDR低速模式去訪問Flash獲取到FDCB,然后從FDCB中得到當(dāng)前Flash的全部屬性再去重新初始化FlexSPI外設(shè)。然而超級下載算法沒法從用戶處獲取到Flash的信息,只能自力更生,使用輪詢的方法去不斷嘗試,直到試出合適的配置參數(shù)。
本篇是開發(fā)筆記第四篇,咱們就重點聊聊如何讓超級下載算法適用不同廠商生產(chǎn)的不同屬性串行NOR Flash。
一、BootROM對Flash的支持(FDCB)
前言里講了BootROM對Flash的支持是靠不同的FDCB結(jié)構(gòu)體配置值來實現(xiàn)的,這個FDCB一共512bytes,原型及各byte定義在i.MXRT1xxx參考手冊System Boot章節(jié)里 Serial NOR configuration block (512 bytes) 一小節(jié)有詳細(xì)介紹。這個FDCB主要是用于配置FlexSPI外設(shè)的,咱們超級下載算法的 flexspi_nor_flash_init() 函數(shù)的一個主要參數(shù) flexspi_nor_config_t 其實就是FDCB。
status_t flexspi_nor_flash_init(uint32_t instance, flexspi_nor_config_t *config);
關(guān)于這個FDCB具體如何賦值,恩智浦官網(wǎng)有一些應(yīng)用筆記,這些應(yīng)用筆記介紹了一些典型的Flash型號應(yīng)該匹配什么樣的FDCB值,從這些應(yīng)用筆記里我們可以大概了解FDCB用法。
上面的應(yīng)用筆記里列舉了一些BootROM支持的Flash型號,這些型號僅僅是恩智浦工程師驗證過的型號,而客戶在實際項目中用到的Flash型號遠(yuǎn)遠(yuǎn)不止這些。從Flash型號本身角度來看,不同廠商的不同型號是獨特且唯一的,但從FDCB角度而言,很多同類型Flash型號其實是一樣的配置值。
二、快速生成FDCB的方法(config option)
那么我們現(xiàn)在是不是直接在超級下載算法中窮舉不同的FDCB值去輪詢呢?要知道FDCB有512bytes,這是個不小的結(jié)構(gòu)體,輪詢一遍太費時且低效了。我們需要進(jìn)一步提煉FDCB,將其精簡一下,只輪詢那些跟Flash類型緊密相關(guān)的參數(shù)。這個工作其實也不需要我們做了,恩智浦ROM研發(fā)小組已經(jīng)做好了,那便是8bytes的config option配置結(jié)構(gòu)體,這個配置結(jié)構(gòu)體也是超級下載算法的 flexspi_nor_get_config() 函數(shù)的一個主要參數(shù) serial_nor_config_option_t。
status_t flexspi_nor_get_config(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option);
其實這個神奇的8bytes的config option配置結(jié)構(gòu)體不止一次地出現(xiàn)過痞子衡之前的文章里:《導(dǎo)致串行NOR Flash在i.MXRT下無法正常下載/啟動的常見因素之SFDP》、《導(dǎo)致串行NOR Flash在i.MXRT下無法正常下載/啟動的常見因素之QE bit》、《FlexSPI NOR啟動時間(RT1170)》、《MCUBootUtility v2.3發(fā)布,這次不再放過任何一款Flash》,它非常精煉地概括了市面上主要的串行NOR Flash特性(都要符合JESD216規(guī)范),只要你提供config option,經(jīng)過 flexspi_nor_get_config() 函數(shù)執(zhí)行后便可以自動生成相對應(yīng)的完整FDCB。
在i.MXRTxxx參考手冊Non-Secure Boot ROM章節(jié)里你可以找到如下典型Flash型號對應(yīng)的參考config option值:
三、利用config option來做輪詢
直接利用512bytes的FDCB去輪詢太難,但利用8bytes的config option去輪詢就簡單多了。我們順著上文中提及的ufl_target_desc_t結(jié)構(gòu)體,在其中新增幾個成員(FlexSPI外設(shè)編號/基址/映射地址,config option),其中輪詢主要跟config option有關(guān)。
typedef struct _target_desc
{
uint32_t imxrtChipId;
uint32_t flexspiInstance; // 新增
uint32_t flexspiBaseAddr; // 新增
uint32_t flashBaseAddr; // 新增
serial_nor_config_option_t configOption; // 新增
flexspi_nor_flash_driver_t flashDriver;
flexspi_bsp_driver_t flexspiBsp;
} ufl_target_desc_t;
然后我們定義一個config option型的數(shù)組 s_flashConfigOpt[],里面存放一些經(jīng)典的config option值。當(dāng)前痞子衡的設(shè)計是僅輪詢這些經(jīng)典的config option值,并沒有窮舉config option,這也是從超級下載算法的執(zhí)行效率角度考慮,這些經(jīng)典的config option值足以覆蓋80%以上的Flash型號了(后期如果要提高Flash覆蓋率,會考慮轉(zhuǎn)到窮舉法的)。
static const serial_nor_config_option_t s_flashConfigOpt[] = {
// For Normal Quad, eg. IS25LP064A, GD25LB256E
{.option0.U = 0xc0000001, .option1.U = 0x00000000},
// For Normal Octal, eg. MX25UM51345G
{.option0.U = 0xc0403001, .option1.U = 0x00000000},
{.option0.U = 0xc1503051, .option1.U = 0x20000014},
// For Normal HyperBus, eg. S26KS512S, IS26KS512S
{.option0.U = (0xc0233000 + kSerialNorCfgOption_MaxFreq), .option1.U = 0x00000000},
// For Normal Octal, eg. MX25UM51245G
{.option0.U = 0xc0403031, .option1.U = 0x00000000},
// For Normal Octal, eg. MT35X
{.option0.U = 0xc0603001, .option1.U = 0x00000000},
// For Normal Octal, eg. ATXP032
{.option0.U = 0xc0803001, .option1.U = 0x00000000},
// For Normal 1-bit SDR
{.option0.U = FLASH_CONFIG_OPT_1BIT_SDR, .option1.U = 0x00000000},
};
關(guān)于具體輪詢操作,源碼在 RT-UFL 項目中的ufl_auto_probe_flash.c 文件里,痞子衡就不再貼出了,只講一下幾個要點:
- 要點 1: 對于一些SIP版本的i.MXRT型號,沒有必要再輪詢了,直接給預(yù)設(shè)的config option值即可。要點 2: config option參數(shù)輪詢成功的判斷標(biāo)準(zhǔn)是,執(zhí)行初始化->擦->寫操作均正常(或許還要加入回讀校驗)。要點 3: 當(dāng)前config option參數(shù)輪詢失敗進(jìn)到下一個option值前需要對FlexSPI外設(shè)進(jìn)行復(fù)位(有條件的話還要對Flash進(jìn)行復(fù)位)。要點 4: 不同F(xiàn)lash型號支持的最大速度不同,輪詢時總是先從最低速開始,慢慢增速到最大支持的速度(當(dāng)前是100MHz,后期會調(diào)整)。要點 5: 為了照顧沒有SFDP表的Flash(或不符合JESD216規(guī)范),輪詢過程里增加了一個1bit SDR屬性的FDCB表作為最后一個保底輪詢。
至此,超級下載算法開發(fā)筆記(4)之輪詢Flash配置參數(shù)痞子衡便介紹完畢了,掌聲在哪里~~~