1. 程式人生 > >痞子衡嵌入式:飛思卡爾i.MX RT系列微控制器啟動篇(9)- 從Parallel NOR啟動

痞子衡嵌入式:飛思卡爾i.MX RT系列微控制器啟動篇(9)- 從Parallel NOR啟動

16bit erase section cloud 你會 命令執行 選型 兩個 寬度


  大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是飛思卡爾i.MX RT系列MCU的Parallel NOR啟動

  上一篇講i.MXRT從Raw NAND啟動的文章 飛思卡爾i.MX RT系列微控制器啟動篇(8)- 從Raw NAND啟動 一經放出,深入廣大網友喜愛,短時間內閱讀量飆升,這讓痞子衡深入鼓舞,所以趁熱打鐵繼續把從Parallel NOR啟動也順便一起講了,為什麽說是順便呢?因為Parallel NOR與Raw NAND都是並行接口,屬於同一門派,且這兩種外存設備在i.MXRT內部是通過同一IP(SEMC)實現底層接口通信的,所以了解了Raw NAND啟動,再來看Parallel NOR啟動會覺得簡單很多。話不多說,開講。

一、支持的Parallel NOR

  依舊開門見山,i.MXRT支持加載啟動的主要是兼容CFI標準且內置EPSCD命令集的ADM SLC Parallel NOR,至於數據線寬度,x8,x16都支持;關於時鐘模式,i.MXRT105x/i.MXRT102x僅支持Asynchronous,i.MXRT106x既支持Asynchronous也支持Synchronous。關於Parallel NOR基本知識請先看一下痞子衡的另一篇文章 並行接口NOR標準(CFI)及SLC Parallel NOR簡介。
  Parallel NOR廠商非常多,對應Parallel NOR芯片型號也很多,如果你在選型時不確定到底該為i.MXRT選擇哪一款Parallel NOR時,可選用下面三款芯片,痞子衡均實測過:

Micron MT28EW128ABA1LPC-0SIT    (x8/x16 bits, 32B Page/128KB Block/128Mb Device,   Non-ADM, Asynchronous)
Winbond W29GL128CH9T            (x8/x16 bits, 64B Page/128KB Sector/128Mb Device,  Non-ADM, Asynchronous)
Spansion S29GL128S90TFI020      (x16 bits,    512B Page/128KB Sector/128Mb Device, Non-ADM, Asynchronous)

Note: ADM即地址線與數據線復用,為了減少pin腳,有些Parallel NOR芯片會將低bit地址線與數據線復用,但目前市面上主流Parallel NOR芯片還是Non-ADM(即地址與數據是不復用的)居多,i.MXRT雖不能直接連接Non-ADM NOR芯片,但在i.MXRT與Non-ADM NOR芯片之間使用一片74系列鎖存器橋接一下便能正常工作。

二、Parallel NOR硬件連接

  確定了Parallel NOR芯片選型後,底下便進入Parallel NOR硬件電路設計及與i.MXRT的信號連接環節:

  i.MXRT對於Parallel NOR的底層接口支持是通過內部SEMC這個IP實現的,SEMC最多能支持五種設備(SDRAM, NAND, NOR, SRAM, 8080 Display),但SEMC接口信號是復用的,所以同一時刻僅能支持一種設備。下表是SEMC接口復用表,關於NOR接口信號,需要特別說一下的是CE#信號和地址線寬度,從表中我們可以看到NOR的CE4#信號有6個,即有6種配置選擇,但i.MXRT BootROM固定選擇的是SEMC_CSX[0],至於地址線寬度,SEMC本身最大可支持28bits地址寬度,但是i.MXRT BootROM裏最大只支持24bits地址寬度(即A0-A23,最大128Mb),這2點在設計NOR硬件連接時需要特別註意。

Note: 對於小容量Paralle NOR芯片(比如512KB,地址線A0-A18),i.MXRT當然也可以支持,SEMC未用的地址線(此處為A19-A23)可不用管。

技術分享圖片

  如下是典型的NOR硬件連接設計,示例NOR芯片是MT28EW128ABA1LPC-0SIT,該NOR芯片為Non-ADM,所以我們使用了一片74ALVT16373鎖存器橋接了一下,當WEIM_ADV_B信號為高電平時,鎖存器Dx會輸出給Qx,即此時WEIM_DATA[15:0]作為地址線輸出給A[15:0],而WEIM_ADV_B信號為低電平時,WEIM_DATA[15:0]就是數據線(即此處WEIM_ADV_B作為ADV#信號是高有效,這在後續配置NOR eFUSE時會涉及到)。

技術分享圖片

三、Parallel NOR加載啟動過程

  確保Parallel NOR硬件相關設計無誤之後,底下便是下載更新Bootable Image進Parallel NOR以供BootROM加載啟動了,在下載Bootable image之前有必要先了解Parallel NOR的加載啟動過程:

  痞子衡在啟動系列文章的第六篇 飛思卡爾i.MX RT系列微控制器啟動篇(6)- Bootable image格式與加載(elftosb/.bd) 裏的最後已經介紹過non-XIP image加載啟動過程,但實際上那個過程主要適用於存儲在外部NAND Flash中Bootable image加載啟動,對於存儲在外部Parallel NOR的Bootable image而言有一些區別,我們知道NOR Flash是支持XIP執行的,所以從NOR啟動有兩種選擇,一種是Non-XIP,另一種是XIP。
  對於Non-XIP啟動而言,其基本流程與第六篇裏介紹的non-XIP image加載啟動過程類似,只有兩點區別,第一個區別是存儲在NOR Flash裏的Bootable image中IVT偏移地址是固定在0x1000(對於NAND Flash,偏移固定是0x400);第二個區別是BootROM加載initial image的大小為12KB(對於NAND Flash,initial image是4KB),且這個initial image的加載不需要經過OCRAM緩存,BootROM是直接從NOR對應的SEMC map region去獲取的
  對於XIP啟動而言,其基本流程與non-XIP image加載啟動過程差異就比較大了,因為整個Bootable image都不需要搬運,BootROM直接從NOR對應的SEMC map region去獲取IVT,BootData,Application,而BootROM中分配給SEMC NOR的XIP空間為0x90000000 - 0x90FFFFFF,所以XIP執行的Application需要鏈接在這個空間裏。

技術分享圖片

  有了前面的背景知識,NOR的加載啟動過程便是上電之後,BootROM先從NOR起始地址處加載initial image數據(12KB),再根據initial image裏的IVT獲取Application起始地址,如Application地址是鏈接在SRAM裏,便認為這是個Non-XIP Application,然後再將Application拷貝到相應SRAM裏去啟動;如Application地址是鏈接在SEMC NOR XIP空間裏,則不需要拷貝,直接原地XIP執行啟動。

四、下載Application進Parallel NOR

  理解了Parallel NOR加載啟動過程,我們便可以開始使用Flashloader下載Application進Parallel NOR芯片中:

  痞子衡在啟動系列文章的第四篇 飛思卡爾i.MX RT系列微控制器啟動篇(4)- Flashloader初體驗(blhost) 和第六篇 飛思卡爾i.MX RT系列微控制器啟動篇(6)- Bootable image格式與加載(elftosb/.bd) 裏分別介紹了Flashloader的基本使用以及如何將你的Application制作成Bootable image,但那裏面制作的Bootable image主要是用於NAND啟動,而對於NOR啟動,其用於生成Bootable image的BD文件稍有不同。
  先來看Non-XIP的情況,下面是一個Non-XIP的BD文件示例,ivtOffset必須設0x1000,因為startAddress = 0x8000, initialLoadSize = 0x3000,所以Application只讀段應從0xb000處開始鏈接:

options {
    flags = 0x00;
    # Note: This is an example address, it can be any non-zero address in ITCM region
    startAddress = 0x8000;
    ivtOffset = 0x1000;
    initialLoadSize = 0x3000;
    # Note: This is required if the default entrypoint is not the Reset_Handler 
    #       Please set the entryPointAddress to Reset_Handler address 
    // entryPointAddress = 0xd531;
}

sources {
    elfFile = extern(0);
}

section (0)
{
}

  再來看XIP的情況,下面是一個XIP的BD文件示例,ivtOffset也必須設0x1000,因為startAddress = 0x90000000, initialLoadSize = 0x3000,所以Application只讀段應從0x90003000處開始鏈接:

options {
    flags = 0x00;
    startAddress = 0x90000000;
    ivtOffset = 0x1000;
    initialLoadSize = 0x3000;
    # Note: This is required if the default entrypoint is not the Reset_Handler 
    #       Please set the entryPointAddress to Reset_Handler address 
    // entryPointAddress = 0x90005531;
}

sources {
    elfFile = extern(0);
}

section (0)
{
}

  假定你已經制作好Bootable image並且使用blhost工具與Flashloader建立了基本通信,正要開始將Bootable image下載進Parallel NOR。
  與Raw NAND啟動一樣,Parallel NOR也支持configuration block,只不過configuration block對於BootROM啟動而言不是必需的,configuration block必須放在NOR Flash起始地址處,下面是其結構原型(如果你還有印象的話,你會發現它跟Raw NAND的semc_nand_config_t很像),如果想使能configuration block,你需要手動創建這256bytes數據,並且用其覆蓋bootable image的前256bytes,在本文裏暫不使能configuration block。

#define SEMC_NOR_INIT_IMG_SIZE (12u * 1024)
#define SEMC_NOR_MAX_SIZE (16U * 1024 * 1024)

#define SEMC_MEM0_BASE (0x80000000u)
#define SEMC_MEM1_BASE (0x90000000u)
#define SEMC_MEM2_BASE (0xA0000000u)
#define SEMC_MEM3_BASE (0xC0000000u)
#define SEMC_MEM_NOR_AXI_BASE SEMC_MEM1_BASE

typedef struct __semc_nor_config
{
    semc_mem_config_t memConfig; //!< [0x000-0x04f]
    uint8_t vendorType;          //!< [0x050-0x050]
    uint8_t acTimingMode;        //!< [0x051-0x051]
    uint8_t deviceCommandSet;    //!< [0x052-0x052]
    uint8_t reserved0[77];       //!< [0x053-0x09f]
    uint32_t pageSizeInBytes;    //!< [0x0a0-0x0a3]
    uint32_t blockSizeInBytes;   //!< [0x0a4-0x0a7]
    uint32_t blockCount;         //!< [0x0a8-0x0ab]
    uint32_t reserved1[21];      //!< [0x0ac-0x0ff]
} semc_nor_config_t;

  前面鋪墊了這麽多,終於來到關鍵地方了,到底怎麽樣將Bootable image數據下載進Parallel NOR中呢?當然還是靠Flashloader工具,我們只需要提供簡化的4byte配置數據即可。下面是一種Application下載更新示例(該示例適用於第二節裏介紹的NOR硬件連接):

// 在SRAM裏臨時存儲Parallel NOR配置數據
blhost -p COMx -- fill-memory 0x2000 0x4 0xD0000600 (Configure to CSX0, ADV high active, 16bits IO, safe AC timing mode)

// 使用Parallel NOR配置數據去配置Parallel NOR接口
blhost -p COMx -- configure-memory 0x8 0x2000

  在上述示例裏痞子衡首先使用了fill-memory命令在0x2000地址處暫存了4byte配置數據,然後通過config-memory將這4byte數據裏的信息配置到Flashloader的Parallel NOR接口中,實際上這2個命令成功執行後,你就可以開始使用Flashloader下載Bootable image了。那麽這4byte配置數據到底是怎麽組織的?詳見下表:

技術分享圖片

  從上表我們可以知道,其實這4byte數據提供的配置信息主要是NOR配置,這4byte裏真正需要註意的只有兩個地方(ADV# Polarity、Data Port Size),其余可用固定配置。
  configure-memory命令執行成功之後,底下image的下載很簡單,只需要將Bootable image從SEMC NOR起始map地址開始下載即可,具體步驟如下:

// 擦除Parallel NOR並將image下載進Parallel NOR
blhost -p COMx -- flash-erase-region 0x90000000 0x20000
blhost -p COMx -- write-memory 0x90000000 ivt_image.bin

Note: 實測發現,RT1050 Flashloader 1.1裏使用USB接口去下載Parallel NOR會報kStatus_SemcNOR_ProgramVerifyFailure錯誤,而使用UART接口下載則正常,應該是USB下載對NOR的支持有缺陷,期望在後續版本的Flashloader裏修復這個問題。

  Bootable image下載成功之後,我們可以試著用read-memory從NOR芯片裏讀回IVT,BootData,Application確認一下,Bootable image起始地址在0x90000000,那麽IVT,BootData應該在0x90001000,Application應該在0x90003000:
  Non-XIP Bootable image讀回情況如下,檢查初始PC可知其鏈接在SRAM空間
技術分享圖片

  XIP Bootable image讀回情況如下,檢查初始PC可知其鏈接在SEMC NOR map空間

技術分享圖片

Note: 如果Application是XIP在SEMC NOR空間,其時鐘初始化代碼不能覆蓋BootROM裏對於SEMC的相關配置,否則XIP可能會失敗。

  至此,Application的下載工作便結束了。

五、進入Parallel NOR啟動模式

  Application已經被成功下載進Parallel NOR芯片之後,此時我們便可以開始設置芯片從Parallel NOR啟動:

  在進入Boot Device選擇之前,你首先需要確定BOOT_MODE[1:0]=2‘b00,即芯片處於Boot From Fuses模式,並且將BT_FUSE_SEL(eFUSE偏移0x460處的32bit配置數據的bit4)燒寫為1‘b1,這裏看不懂的朋友請溫習痞子衡前面的文章 飛思卡爾i.MX RT系列微控制器啟動篇(2)- Boot配置(BOOT Pin/eFUSE)。
  設置好正確Boot模式後,再來選擇Boot Device,,你還需要將BOOT_CFG1[7:4](eFUSE偏移0x450處的32bit配置數據的bit7:4)燒寫成4‘b0001,此時便進入了從SEMC NOR啟動模式。
  如果想確保i.MXRT芯片一定正在從Parallel NOR啟動,可在芯片上電時使用Jlink調試器或者借助Flashloader讀取芯片內部2個寄存器的值,這2個寄存器分別是SRC_SBMR1/2, 我們設的關於啟動模式的BOOT_MODE pins/BOOT_CFG pin/eFUSE偏移0x450配置值在上電時會自動加載到SRC_SBMR1/2寄存器裏,BootROM主要是根據SRC_SBMR1/2寄存器的值來判斷啟動模式的。

技術分享圖片

  PS: BOOT_MODE[1:0]也可以設為2‘b10,即芯片處於Internal Boot模式,此時需要確保BT_FUSE_SEL(eFUSE偏移0x460處的32bit配置數據的bit4)為1‘b0和BOOT_CFG1[7:4]這四個pin的輸入狀態設為4‘b0001。

六、配置eFUSE啟動Parallel NOR

  設置好芯片啟動模式是從Parallel NOR啟動之後,我們還需要最後關註一下與Parallel NOR相關的具體特性配置:

  你應該記得我們在使用Flashloader下載Application的時候提供過4bytes的NOR配置數據,這4bytes的NOR配置數據是為了讓Flashloader能夠正確初始化Parallel NOR接口去訪問NOR芯片(主要是寫Bootable image),同樣BootROM上電也需要初始化Parallel NOR接口去訪問NOR芯片(主要是讀Bootable image),所以BootROM也需要類似這4bytes NOR配置數據,而BootROM的NOR配置便放在如下的eFUSE區域裏:

技術分享圖片

技術分享圖片

七、幾個註意事項

  1. 市面上Parallel NOR從內置命令集角度分為兩大類,一類是以Micron MT28EW系列為代表的EPSCD命令集,另一類是以Micron MT28GU為代表的SFMCD命令集,BootROM本身對於這兩類NOR芯片都是支持的,但Flashloader目前只支持內置EPSCD命令集的NOR芯片。

  至此,飛思卡爾i.MX RT系列MCU的Parallel NOR啟動痞子衡便介紹完畢了,掌聲在哪裏~~~

痞子衡嵌入式:飛思卡爾i.MX RT系列微控制器啟動篇(9)- 從Parallel NOR啟動