日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU启动那些事(8)- 从Raw NAND启动

發布時間:2024/4/13 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU启动那些事(8)- 从Raw NAND启动 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

  前面鋪墊了七篇啟動系列文章,終于該講具體Boot Device了,我們知道i.MXRTyyyy支持的外部Boot Device共有6種(Serial NOR&NAND、Parallel NOR&NAND、SD/eMMC、SPI NOR/EEPROM),其中最常用的是Serial NOR&NAND,目前各大社區里討論最火的也是Serial NOR/NAND啟動,有不少大神(硬漢eric2013, jicheng0622)已經寫過關于Serial NOR&NAND啟動的文章,寫得非常好,這讓痞子衡非常有壓力,因此痞子衡決定第一篇Boot Device寫較常用但還沒有人寫過的Raw(Parallel) NAND啟動,大家是不是很期待?(請配合說“是”),好,話不多說,開講。

一、支持的Raw NAND

  開門見山,i.MXRT支持加載啟動的主要是兼容ONFI 1.0標準的Asynchronous SLC Raw NAND,至于數據線寬度,x8,x16都支持(一般x8應用比較多)。關于Raw NAND基本知識請先看一下痞子衡的另一篇文章 并行接口NAND標準(ONFI)及SLC Raw NAND簡介,本文后續的很多內容均是基于充分了解Raw NAND的前提下開展的。

Note1: ONFI是最流行的NAND標準,ONFI 1.0僅針對50MB/s低速Async SDR模式NAND,從ONFI 2.x開始逐步引入133MB/s、166MB/s、200MB/s高速Sync模式NAND的支持,從ONFI 3.x開始又引入400MB/s、533MT/s(NV-DDR2)更高速NAND的支持,從ONFI 4.x開始更是加入了667MT/s、800MT/s、1066MT/s、1200MT/s(NV-DDR3)超高速NAND的支持。
Note2: 關于NAND還有一個JEDEC標準JESD230,該標準是JEDEC與ONFI組織合作制定的,主要是定義了Async SDR、Sync DDR, Toggle DDR模式NAND的互操作性。JESD230標準版本可與ONFI 3.1及其之后的版本相對應。

  Raw NAND廠商非常多,對應Raw NAND芯片型號也很多,如果你在選型時不確定到底該為i.MXRT選擇哪一款Raw NAND時,可選用下面五款芯片,痞子衡均實測過:

Macronix MX30LF4GE8AB-TI (x8 bits, 2KB Page/128KB Block/4Gb Device, 0bit ECC, 3.3V) Micron MT29F4G08ABBDAWP (x8 bits, 2KB Page/128KB Block/4Gb Device, 4bit ECC, 1.8V) Micron MT29F4G08ABAFAWP:D (x8 bits, 2KB Page/128KB Block/4Gb Device, 4bit ECC, 3.3V) Micron MT29F16G08ABACAWP:C (x8 bits, 4KB Page/512KB Block/16Gb Device, 4bit ECC, 3.3V) Winbond W29N01GVSIAA (x8 bits, 2KB Page/128KB Block/1Gb Device, 1bit ECC, 3.3V)

二、Raw NAND硬件連接

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

  i.MXRT對于Raw NAND的底層接口支持是通過內部SEMC這個IP實現的,如下是SEMC的內部模塊圖,從圖中我們可以看到,從內部數據總線來看SEMC支持AXI Bus/IP Bus兩種(此兩種方式會在后續eFUSE配置里看到),而從外部接口來看SEMC最多能支持五種設備(SDRAM, NAND, NOR, SRAM, 8080 Display),NAND是其中一種。

  雖然SEMC最多能支持五種設備,但并不是同時支持的,同一時刻僅能支持一種設備,因此SEMC接口信號必然是復用的,下表是SEMC接口復用表,關于NAND接口信號,需要特別說一下的是CE#信號,從表中我們可以看到NAND的CE6#信號有5個,即有5種配置選擇,但i.MXRT BootROM固定選擇的是SEMC_CSX[0],這點在設計NAND硬件連接時需要特別注意。

  如下是典型的NAND硬件連接設計,示例NAND芯片是MX30LF4GE8AB-TI(經典的TSOP-48封裝,芯片絲印上的L表明其是3.3V供電),其中WP#信號沒有使能,并且供電選擇同時支持3.3V和1.8V(通過R302選擇,此處應連2-3),有朋友會疑問,為什么此處要留有2路不同供電電壓?因為后期方便我們更換不同的供電輸入的NAND芯片。

三、Raw NAND加載啟動過程

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

  痞子衡在啟動系列文章的第六篇 Bootable image格式與加載(elftosb/.bd) 里的最后已經介紹過non-XIP image加載啟動過程,但實際上那個過程對于存儲在外部NAND Flash中Bootable image而言還是介紹得不夠全面,欠缺FCB/DBBT的處理流程,你肯定會疑問FCB/DBBT是什么?這得從NAND與NOR差異說起,我們知道NOR Flash中所有空間都必須是可用的(即不允許有壞塊),這意味著NOR Flash中的Bootable image數據是可以按指定地址連續存放的(即所謂的線性存儲),并且Application可以原地XIP執行;但是NAND Flash中常常是有壞塊的(出廠壞塊,使用中產生壞塊),這就導致NAND可用空間地址不可預知并且有可能不連續,因此存儲在NAND中的Bootable image數據極有可能并不是連續存放的,并且Bootable image實際存儲的起始地址也不一定就是指定的起始地址(即所謂的非線性存儲)。
  舉例來說,如果NAND的block大小為128KB,Firmware(即Bootable Image)大小為260KB,我們指定從NAND地址0x40000處(即block index = 2)開始存儲Firmware,但是很不幸的是index為2、4的block均是壞塊,那么實際上Firmware被分散存儲在了index為3、5、6三個block中,為了將來能正確地從NAND中讀回Firmware,我們需要額外記錄至少兩個信息,一是指定的Firmware起始存儲地址0x40000,二是NAND中壞塊信息block index 2、4。FCB/DBBT就是用來記錄這些額外的信息。
  FCB大小為1KB,其主要記錄了Firmware信息(地址,長度,份數),以及DBBT地址信息。DBBT大小為1056bytes,其記錄了NAND芯片中所有的壞塊個數以及位置,DBBT即所謂的壞塊表。FCB/DBBT最大可有兩份,實際應用中一般只用一份即可,后面介紹均以一份FCB/DBBT為例講解,FCB0永遠從NAND地址0x0處(即index為0的block中的第1個Page)開始存放,DBBT0一般放在index為n的block里(其實n是可設的,這在后面使用Flashloader時會講到,為求簡單我們常常設n=1),Firmware 0一般放在index為n+1的block里(Firmware只允許從index為n+1的block及其之后開始存放,Firmware最大可以有8份)。關于FCB/DBBT結構原型,后續會進一步介紹。

  有了前面的背景知識,NAND的加載啟動過程便是上電之后,BootROM先從NAND起始地址處獲取FCB0數據,再根據FCB0里的信息獲取DBBT0數據以及Firmware 0起始地址,底下便進入跟NOR Flash一樣的加載過程,只不過在加載Firmware 0的過程中需要根據DBBT0壞塊表信息自動跳過壞塊。如果在讀取Firmware 0時,發現部分Firmware數據所在的block是一個壞塊,但是這個block沒有被記錄在DBBT0中,這說明該壞塊是新產生的(該新壞塊信息會在下一次下載Application時記錄在新DBBT中),存在該壞塊中的Firmware數據被破壞了,Firmware 0便失效了,BootROM便會嘗試按同樣的流程去加載Firmware 1、2...7,直到找到有效的Firmware,這就是為什么在NAND中存儲多份Firmware的意義。

四、下載Application進Raw NAND

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

  痞子衡在啟動系列文章的第四篇 Flashloader初體驗(blhost) 和第六篇 Bootable image格式與加載(elftosb/.bd) 里分別介紹了Flashloader的基本使用以及如何將你的Application制作成Bootable image,后續內容假定你已經制作好一個Bootable image并且使用blhost工具與Flashloader建立了基本通信,正要開始將Bootable image下載進Raw NAND。
  前面講過Raw NAND中除了要有Bootable image(Firmware)之外,還需要有FCB/DBBT,并且FCB/DBBT在Raw NAND中存儲的位置是比Bootable image靠前的,因此你遇到的第一個問題便是如何下載FCB/DBBT進Raw NAND?
  首先來看FCB和DBBT的原型,如下semc_nand_fcb_t是FCB原型,semc_nand_dbbt_t是DBBT原型:
  FCB/DBBT結構體開頭都是12bytes的semc_bcb_header_t,這個bcb header由Tag、Version、CRC Checksum(CRC32-MPEG2)組成,用于驗證FCB/DBBT的完整性。
  semc_nand_fcb_t.DBBTSerachAreaStartPage標明DBBT所在位置;semc_nand_fcb_t.searchStride和semc_nand_fcb_t.searchCount用于存在2份FCB/DBBT時標明第二份位置(此處我們僅用一份,所以searchCount設為1,searchStride的值不用管);semc_nand_fcb_t.firmwareCopies記錄Firmware總份數,semc_nand_fcb_t.firmwareTable標明所有Firmware具體位置;semc_nand_fcb_t.nandConfig是Raw NAND的configuration block,大小為256bytes,記錄Raw NAND特性參數。
  semc_nand_dbbt_t.badBlockNumber記錄壞塊總個數,semc_nand_dbbt_t.badBlockTable標明所有壞塊具體位置。

#define SEMC_NAND_BAD_BLOCKS_MAX_NUM 256 #define SEMC_NAND_FW_MAX_NUM 8#define SEMC_NAND_FCB_TAG 0x4E464342U //!< ASCII: "NFCB" #define SEMC_NAND_FCB_VERSION 0x00000001 //!< Version: 1.0 #define SEMC_NAND_DBBT_TAG 0x44424254U //!< ASCII: "DBBT" #define SEMC_NAND_DBBT_VERSION 0x00000001 //!< Version: 1.0typedef struct _nand_firmware_info {uint32_t startPage;uint32_t pagesInFirmware; } nand_firmware_info_t;typedef struct _semc_bcb_header {uint32_t crcChecksum; //!< [0x000-0x003]uint32_t fingerprint; //!< [0x004-0x007]uint32_t version; //!< [0x008-0x00b] } semc_bcb_header_t;typedef struct __semc_nand_config {semc_mem_config_t memConfig; //!< [0x000-0x04f]uint8_t vendorType; //!< [0x050-0x050]uint8_t cellTechnology;uint8_t onfiVersion;uint8_t acTimingTableIndex;uint8_t enableEccCheck; //!< [0x054-0x054]uint8_t eccCheckType;uint8_t deviceEccStatus;uint8_t swEccAlgorithm;uint32_t swEccBlockBytes; //!< [0x058-0x05b]uint8_t readyCheckOption; //!< [0x05c-0x05c]uint8_t statusCommandType; //!< [0x05d-0x05d]uint16_t readyCheckTimeoutInMs; //!< [0x05e-0x05f]uint16_t readyCheckIntervalInUs; //!< [0x060-0x061]uint8_t reserved0[30]; //!< [0x062-0x07f]uint8_t userOnfiAcTimingModeCode; //!< [0x080-0x080]uint8_t reserved1[31]; //!< [0x081-0x09f]uint32_t bytesInPageDataArea; //!< [0x0a0-0x0a3]uint32_t bytesInPageSpareArea;uint32_t pagesInBlock;uint32_t blocksInPlane; //!< [0x0ac-0x0af]uint32_t planesInDevice; //!< [0x0b0-0x0b3]uint32_t reserved2[19]; //!< [0x0b4-0x0ff] } semc_nand_config_t;typedef struct _semc_nand_fcb {semc_bcb_header_t bcbHeader; //!< [0x000-0x00b]uint32_t DBBTSerachAreaStartPage; //!< [0x00c-0x00f]uint16_t searchStride; //!< [0x010-0x011]uint16_t searchCount; //!< [0x012-0x013]uint32_t firmwareCopies; //!< [0x014-0x017]uint32_t reserved0[10]; //!< [0x018-0x03f]nand_firmware_info_t firmwareTable[SEMC_NAND_FW_MAX_NUM]; //!< [0x040-0x07f]uint32_t reserved1[32]; //!< [0x080-0x0ff]semc_nand_config_t nandConfig; //!< [0x100-0x1ff]uint32_t reserved2[128]; //!< [0x200-0x3ff] } semc_nand_fcb_t;typedef struct _semc_nand_dbbt {semc_bcb_header_t bcbHeader; //!< [0x000-0x00b]uint32_t reserved0; //!< [0x00c-0x00f]uint32_t badBlockNumber; //!< [0x010-0x013]uint32_t reserved1[3]; //!< [0x014-0x01f]uint32_t badBlockTable[SEMC_NAND_BAD_BLOCKS_MAX_NUM]; //!< [0x020-0x41f] } semc_nand_dbbt_t;

  知道了FCB/DBBT結構,那么怎么生成FCB/DBBT數據并且下載進Raw NAND什么地址處呢?當然我們可以手工創建FCB/DBBT并將其下載到Raw NAND中,但其實Flashloader工具會幫我們自動做好大部分工作(生成FCB/DBBT,將FCB/DBBT下載到Raw NAND中),而我們只需要提供簡化的12byte配置數據即可。如果你還有印象的話,痞子衡在啟動系列文章的第四篇 Flashloader初體驗(blhost) 的最后介紹過下載更新Application示例(該示例適用NAND芯片MX30LF4GE8AB-TI):

// 在SRAM里臨時存儲Raw NAND配置數據 blhost -u -- fill-memory 0x2000 0x4 0xD0010101 // ONFI 1.0, non-EDO, Timing mode 0, 8bit IO, CSX0, HW ECC Check, inital HW ECC is enabled blhost -u -- fill-memory 0x2004 0x4 0x00010101 // image copy = 1, search stride = 1, search count = 1 blhost -u -- fill-memory 0x2008 0x4 0x00020001 // Firmware block index = 2, block count = 1// 使用Raw NAND配置數據去配置Raw NAND接口 blhost -u -- configure-memory 0x100 0x2000

  在上述示例里痞子衡首先使用了fill-memory命令在0x2000地址處暫存了12byte配置數據,然后通過config-memory將這12byte數據里的信息配置到Flashloader的Raw NAND接口中,實際上這4個命令成功執行后,FCB/DBBT就已經被下載進Raw NAND里面了。那么這12byte配置數據到底是怎么組織的?詳見下表:

  從上表我們可以知道,其實這12byte數據提供的配置信息還是比較多的,涵蓋NAND配置、FCB配置、Image配置,但是與FCB/DBBT原本的數據結構相比已經大幅精簡,我們還可以再進一步簡化,這12byte里真正需要注意的只有四個地方(ECC status、ECC Type、IO Port Size、EDO mode),其余可用固定配置。由于此處我們示例NAND芯片為MX30LF4GE8AB-TI,查看NAND芯片手冊可知其是x8 IO且沒有HW ECC,那么IO Port Size需設2'b01(即x8),ECC type、ECC status分別可設1'b1、1'b0(HW ECC Check,initial HW ECC is enabled,其實這樣設在沒有HW ECC的NAND芯片上的意思是不使能ECC Check),EDO mode可設1'b0(即non-EDO模式)。
  configure-memory命令執行成功之后,我們可以試著用read-memory從NAND芯片里讀回FCB,DBBT確認一下,示例NAND芯片MX30LF4GE8AB-TI的page size為2KB,block size為128KB,那么FCB應該在0x0處,DBBT應該在0x20000處,從0x0處讀回1KB數據發現其確實是有效的FCB,從FCB里找到其中DBBTSerachAreaStartPage = 0x40,即DBBT放在index為64的Page里(即index為1的Block起始Page里),再從0x20000處讀回1056bytes數據發現其也確實是有效的DBBT。

  解決了第一個問題即FCB/DBBT問題,還有另一個問題便是image應該如何下載進Raw NAND?
  其實image的下載很簡單,只需要將Bootable image從index為2的block里(與FCB里的firmwareTable[0].startPage對應)開始下載即可,示例NAND芯片MX30LF4GE8AB-TI的block size為128KB,則下載地址應為0x40000,具體步驟如下:

// 擦除Raw NAND并將image下載進Raw NAND blhost -u -- flash-erase-region 0x40000 0x20000 0x100 // Erase 1 block starting from block 2 blhost -u -- write-memory 0x40000 ivt_image.bin 0x100 // Program ivt_image.bin to block 2

  Bootable image下載成功之后,同樣我們可以試著用read-memory從NAND芯片里讀回IVT,BootData,Application確認一下,Bootable image起始地址在0x40000,那么IVT,BootData應該在0x40400,Application應該在0x42000,查看數據發現確實是有效的Bootable image。你可能會疑問,NAND的讀寫操作一般都是按page的,為何我們使用read-memory命令提供的地址參數可以不按page對齊?其實Flashloader內部會有page緩存區,Flashloader底層對NAND的訪問是按page進行的,并緩存在內部page緩存區,接口上層來讀寫NAND數據實際是在page緩存區進行的,所以不受page對齊限制。

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

五、進入Raw NAND啟動模式

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

  在進入Boot Device選擇之前,你首先需要確定BOOT_MODE[1:0]=2'b10,即芯片處于Internal Boot模式,并且確認BT_FUSE_SEL(eFUSE偏移0x460處的32bit配置數據的bit4)為1'b0,這里看不懂的朋友請溫習痞子衡前面的文章 Boot配置(BOOT Pin/eFUSE)。
  設置好正確Boot模式后,再來選擇Boot Device,Boot Device由BOOT_CFG1[7:4]這四個pin的輸入狀態決定,下圖是RT105x/RT106x硬件板的參考設計,撥碼開關SW6應撥向SW_DIP-8的7,8,11,即設置BOOT_CFG[7:4]=4'b001x(4'b001x適用于i.MXRT105x/i.MXRT106x,對于i.MXRT102x此值應為4'b01xx),此時便進入了從SEMC NAND啟動模式。

  如果想確保i.MXRT芯片一定正在從Raw NAND啟動,可在芯片上電時使用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'b00,即芯片處于Boot From Fuses模式,但此時稍微繁瑣一點,需要將BT_FUSE_SEL(eFUSE偏移0x460處的32bit配置數據的bit4)燒寫為1'b1和BOOT_CFG1[7:4](eFUSE偏移0x450處的32bit配置數據的bit7:4)燒寫成4'b001x(適用于i.MXRT105x/i.MXRT106x)。

六、配置eFUSE啟動Raw NAND

  設置好芯片啟動模式是從Raw NAND啟動之后,我們還需要最后關注一下與Raw NAND相關的具體特性配置:

  你應該記得我們在使用Flashloader下載Application的時候提供過12bytes的NAND配置數據,這12bytes的NAND配置數據是為了讓Flashloader能夠正確初始化Raw NAND接口去訪問NAND芯片(主要是寫FCB,DBBT,Bootable image),同樣BootROM上電也需要初始化Raw NAND接口去訪問NAND芯片(主要是讀FCB,DBBT,Bootable image),所以BootROM也需要類似這12bytes NAND配置數據,而BootROM的NAND配置便放在如下的eFUSE區域里(i.MXRT105x/i.MXRT102x是一樣的,i.MXRT106x與i.MXRT105x比有細微調整),與Flashloader一樣這部分配置里真正需要注意的也只有四個地方(ECC status、ECC Type、IO Port Size、EDO mode),其余可用初始配置(即0值)。

七、幾個注意事項

  • i.MXRT105x A0版本與A1版本的BootROM有很大區別,本文內容僅適用于A1版本。
  • 實測發現i.MXRT105x需要使能EDO模式方可訪問NAND(默認是AXI方式),而i.MXRT106x則不需要使能EDO模式。
  • 配置數據(Flashloader的12bytes/BootROM的eFUSE)里關于ECC的2處配置(ECC status、ECC Type)需根據實際連接的NAND芯片而定,不可隨意設置。
    3.1 對于沒有硬件ECC的NAND芯片,可有兩種設置組合:一、ECC Type=HW,ECC status=Enabled(即不用ECC check);二、ECC Type=SW,ECC status=x(即使用SW ECC check)。
    3.2 對于含有硬件ECC且默認是使能的NAND芯片,僅有一種設置組合:一、ECC Type=HW,ECC status=Enabled(即使用HW ECC check)。
    3.3 對于含有硬件ECC且默認沒使能的NAND芯片,可有兩種設置組合:一、ECC Type=SW,ECC status=x(即使用SW ECC check);二、ECC Type=HW,ECC status=Disabled(即使用HW ECC check,BootROM會自動使用set-feature命令開啟硬件ECC,目前僅支持Micron的NAND芯片)
  •   上述所有步驟全部完成之后,復位芯片你就應該能看到你放在Raw NAND里的Application已經正常地啟動了。

      至此,飛思卡爾i.MX RTyyyy系列MCU的Raw NAND啟動痞子衡便介紹完畢了,掌聲在哪里~~~

    轉載于:https://www.cnblogs.com/henjay724/p/9173425.html

    總結

    以上是生活随笔為你收集整理的痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU启动那些事(8)- 从Raw NAND启动的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。