痞子衡嵌入式:飛思卡爾i.MX RT系列微控制器啟動篇(3)- Serial Downloader模式(sdphost/mfgtool)

来源:https://www.cnblogs.com/henjay724/archive/2018/05/27/9096222.html
-Advertisement-
Play Games

Serial Downloader模式是一種串列下載模式,在這種模式下,BootROM通過指定的USB或者UART口來接收來自Host(恩智浦提供了上位機工具sdphost.exe或者mfgtool)的Flashloader數據,並將數據存儲在SRAM中執行,Flashloader程式可以用來將你的... ...



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

  在上一篇文章 飛思卡爾i.MX RT系列微控制器啟動篇(2)- Boot配置(BOOT Pin, eFUSE) 里痞子衡為大家介紹了i.MXRT Boot的行為配置,其中第一節里講了Boot有三種行為模式:Serial Downloader、Boot From Fuses、Internal Boot,後兩種是核心的載入啟動行為模式,而Serial Downloder看起來是個次要的模式,那麼Serial Downloader模式到底有什麼用?今天痞子衡就來詳細聊一聊Serial Downloader模式。

  痞子衡在前面已經講過Serial Downloader模式是一種串列下載模式,在這種模式下,BootROM通過指定的USB或者UART口來接收來自Host(恩智浦提供了上位機工具sdphost.exe或者mfgtool)的Flashloader數據,並將數據存儲在SRAM中執行,Flashloader程式可以用來將你的Application下載進i.MXRT支持的所有外部非易失性存儲器中,為後續從外部存儲器啟動做準備。

一、進入Serial Downloader模式

  i.MXRT上電永遠是從ROM啟動去執行BootROM程式,最頂層的Boot行為模式由BOOT_MODE[1:0] pins的狀態決定,想進入Serial Downloader模式最直接的方式便是將BOOT_MODE[1:0]輸入狀態撥成2'b01,在設計i.MXRT的硬體板時BOOT_MODE[1:0] pins應設計成可通過撥碼開關選擇輸入電平,下圖是RT1052硬體板的參考設計:

  撥碼開關SW5應撥向SW_DIP-8的8和10,即設置BOOT_MODE[1:0]=2'b01,此時便直接進入了Serial Downloader模式。
  當然如果SW5不按上面這麼設置,也有可能進入Serial Downloader模式,但是需要其他前提條件,即Boot From Fuses/Internal Boot模式下從Boot Device載入啟動失敗。

二、sdphost/mfgtool的使用

  進入了Serial Downloader模式,此時便可以用恩智浦提供的host工具與BootROM進行命令交互,host工具在 Flashloader包 里。

  下載好Flashloader包之後,在\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools下可以找到所有host工具,其中用於與BootROM通信的有兩個:sdphost.exe與MfgTool2.exe。

2.1 支持的通信外設pinout

  BootROM支持兩種通信外設,分別是USB-HID和UART,pinout如下(Pinout適用RT105x和RT102x):

Peripheral Instance PAD Port Mode
USB OTG1 USB_OTG1_DN / /
USB_OTG1_DP
USB_OTG1_VBUS
LPUART 1 GPIO_AD_B0_12 LPUART1_TX ALT2
GPIO_AD_B0_13 LPUART1_RX ALT2

2.2 sdphost用法

  sdphost.exe是命令行工具,使用sdphost既可以通過UART口也可以通過USB口與BootROM進行通信與命令交互。
  在命令行下打開sdphost.exe,輸入-?命令可以看到sdphost使用幫助,一共7條命令:

PS C:\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools\sdphost\win> .\sdphost.exe -?
usage: C:\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools\sdphost\win\sdphost.exe
                       [-?|--help]
                       [-p|--port <name>[,<speed>]]
                       [-u|--usb [[[<vid>,]<pid>]]]
                       [-t|--timeout <ms>]
                       -- command <args...>

Options:
  -?/--help                    Show this help
  -p/--port <name>[,<speed>]   Connect to target over UART. Specify COM port
                               and optionally baud rate
                                 (default=COM1,115200)
                                 If -b, then port is BusPal port
  -u/--usb [[[<vid>,]<pid>] | [<path>]]
                               Connect to target over USB HID device denoted by
                               vid/pid (default=0x15a2,0x0083) or device path
  -t/--timeout <ms>            Set packet timeout in milliseconds
                                 (default=5000)
Commands:
  // 讀指定AIPS外設寄存器值
  read-register <addr> [<format> [<count> [<file>]]]
                               Read one or more registers at address.
                               Format must be 8, 16, or 32;
                                 default format is 32.
                               Count is number of bytes to read;
                                 default count is sizeof format
                                 (i.e. one register).
                               Output file is binary;
                                 default is hex display on stdout.
  // 寫值進指定AIPS外設寄存器
  write-register <addr> <format> <data>
                               Write one register at address.
                               Format must be 8, 16, or 32.
                               Data is data value to write.
  // 寫image文件數據進指定SRAM地址
  write-file <addr> <file> [<count>]
                               Write file at address.
                               Count is size of data to write in bytes;
                                 size of file will be used by default.
  // 返回上條命令的執行狀態
  error-status                 Read error status of last command.
  // 寫DCD table進指定SRAM地址
  dcd-write <addr> <file>      Send DCD table from file.
                                 <addr> must point to a valid
                                   temporary storage area.
  // 忽略image文件中的DCD table
  skip-dcd-header              Ignore DCD table in image.
  // 跳轉執行含IVT頭的image
  jump-address <addr>          Jump to entry point of image
                                   with IVT at specified address.

  當使用串口轉USB模塊連接i.MXRT的LPUART1或者使用USB Cable連接上USB_OTG1口後可以看到PC設備管理器會識別出相關設備:

  讓我們嘗試一下使用sdphost與BootROM通信,先試一下USB通信:

PS C:\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools\sdphost\win> .\sdphost.exe -u 0x1fc9,0x0130 -- error-status

Status (HAB mode) = 1450735702 (0x56787856) HAB disabled.
Reponse Status = 858993459 (0x33333333) HAB failure.

  再接著試一下UART通信,似乎通信失敗了。需要註意的是,當使用USB通信過一次之後,BootROM已經激活USB外設,不會再去檢測UART外設,如果想使用UART通信,需要將板子reset一次,使BootROM重回外設檢測狀態。

PS C:\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools\sdphost\win> .\sdphost.exe -p COM19 -- error-status

getStatusResponse.readPacket error 5.
Status (HAB mode) = 10004 (0x2714) No response from device.

  關於sdphost其他命令具體如何組合使用,痞子衡會在後續的文章里再具體介紹。

2.3 mfgtool用法

  MfgTool2.exe是GUI工具,其實際上是在sdphost工具基礎上做了一層圖形化封裝,但功能上有一些削減,並且使用MfgTool2.exe僅能通過USB口與BootROM進行通信。
  如果板子不連USB Cable,直接打開MfgTool2.exe,可看到如下界面,顯示"No Device Connected"。

  當板子連上USB Cable後可以看到狀態變為"HID-compliant vendor-defined device",這表明軟體已可以正常使用。

  從軟體界面來看,似乎能控制的只有2個按鈕:Start和Exit,那到底如何使用這個軟體,其實秘密藏在如下兩個配置文件里:
  \Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools\mfgtools-rel\cfg.ini
  \Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools\mfgtools-rel\Profiles\MXRT105X\OS Firmware\ucl2.xml
  cfg.ini文件用於指定GUI工具工作平臺與模式(預設為chip = MXRT105X和name = MXRT105X-DevBoot),而ucl2.xml文件包含了不同模式的具體實現。以MXRT105x-DevBoot模式來說,點擊Start按鈕後,GUI會使用sdphost.exe與BootROM建立通信,首先用write-file命令將ivt_flashloader.bin文件下載進SRAM(地址是固定的0x20000000),然後使用jump-address命令跳轉到Flashloader程式中去執行(Stage 1),GUI繼續使用blhost.exe與Flashloader建立通信,先用get-property 1命令測試連接,然後使用receive-sb-file命令接收boot_image.sb文件。

<LIST name="MXRT105x-DevBoot" desc="Manufacturing with Flashloader">
<!-- Stage 1, load and execute Flashloader -->    
    <CMD state="BootStrap" type="boot" body="BootStrap" file="ivt_flashloader.bin" > Loading Flashloader. </CMD>
    <CMD state="BootStrap" type="jump"  onError = "ignore"> Jumping to Flashloader. </CMD>

<!-- Stage 2, Program boot image into external memory using Flashloader -->   
    <CMD state="Blhost" type="blhost" body="get-property 1" > Get Property 1. </CMD> <!--Used to test if flashloader runs successfully-->
    <CMD state="Blhost" type="blhost" timeout="15000" body="receive-sb-file \"Profiles\\MXRT105X\\OS Firmware\\boot_image.sb\"" > Program Boot image </CMD> 
    <CMD state="Blhost" type="blhost" body="Update Completed!">Done</CMD>
</LIST>

  關於blhost與sb文件的用法,痞子衡會在後續的文章里再具體介紹。

三、啟動Flashloader程式

  啟動Flashloader是Serial Downloader模式的核心任務,其實在上一節mfgtool工具介紹里,大家已經看見了Flashloader的身影,但是GUI工具將Flashloader的啟動操作封裝得不太直觀,這裡痞子衡用sdphost為大家直觀地再現一遍啟動Flashloader的過程。
  在\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Flashloader目錄下,有Flashloader的可執行文件(.elf格式和.srec格式),但是sdphost僅能處理純image數據文件(.bin格式),可使用IAR EWARM自帶的ielftool.exe工具將elf文件轉換成bin文件(命令為: ielftool --bin flashloader.elf flashloader.bin)。
  得到flashloader.bin文件後,便可使用sdphost的write-file命令將flashloader.bin下載進SRAM,並且使用jump-address命令跳轉到Flashloader程式中,但還需要解決兩個問題:
  第一個問題,該把flashloader.bin文件下載進SRAM的什麼地址?其實這裡的SRAM地址即是Flashloader程式的中斷向量表所在地址,這個地址包含在elf文件里,可用專門的elf文件分析工具得到。也可以通過查看.srec或者.hex文件得到,由於包里自帶了.srec文件,我們直接用文本編輯器打開.srec文件,可以得知這個地址是0x20002000。

S0130000666C6173686C6F616465722E737265638C
S31520002000705A2120914B01207B240020952E0120FF

  讓我們開始將flashloader.bin下載進SRAM的0x20002000地址處:

PS C:\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools\sdphost\win> .\sdphost.exe -u 0x1fc9,0x0130 -- write-file 0x20002000 ..\..\..\Flashloader\flashloader.bin

Preparing to send 81847 (0x13fb7) bytes to the target.
(1/1)1%Status (HAB mode) = 1450735702 (0x56787856) HAB disabled.
Reponse Status = 2290649224 (0x88888888) Write File complete.

  第二個問題,如何使用jump-address命令跳轉到Flashloader程式中?痞子衡在前面sdphost命令列表裡介紹過,jump-address只能跳轉到含IVT頭的image,現在image本身已經有了,但是IVT頭是什麼?用二進位編輯器打開\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools\mfgtools-rel\Profiles\MXRT105X\OS Firmware\ivt_flashloader.bin文件,可以發現除了前2KB之外的其他數據跟我們生成的flashloader.bin是一樣的,那麼IVT就藏在前2KB數據里,仔細看一下,你會發現除了偏移0x400的位置處有一些數據外,其餘都是0,是的IVT就在那裡。

offset(h)
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...
000003F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000400: D1 00 20 40 91 4B 01 20 00 00 00 00 00 00 00 00
00000410: 20 04 00 20 00 04 00 20 00 00 00 00 00 00 00 00
00000420: 00 00 00 20 B7 5F 01 00 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...
00001FF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00002000: 70 5A 21 20 91 4B 01 20 7B 24 00 20 95 2E 01 20
00002010: 7B 24 00 20 7B 24 00 20 7B 24 00 20 00 00 00 00
...
00015FB0: 03 80 FF 71 00 70 08 -- -- -- -- -- -- -- --

  你可能會疑問,真正有用的IVT數據只有幾十個位元組,為什麼ivt_flashloader.bin文件會留出2KB的空間來放IVT?這得分析IVT本身才能知道答案,讓我們來嘗試解析IVT,IVT的原型是如下的hab_ivt_v0結構體,一共32個byte,對應的是偏移0x400 - 0x41F處的數據,hab_ivt_v0.self = 0x20000400,由於此處self成員指定的IVT地址是0x20000400,而Flashloader本身地址是0x20002000,bin文件本身並不含地址信息數據,所以只能用0來填充占位以保證IVT數據與Flashloader數據的相對位置關係,這就是0x430 - 0x1FFF全是0的原因。hab_ivt_v0.boot_data =0x20000420,指明瞭boot data數據在0x420 - 0x42b處,boot_data結構體原型如下,一共12個byte,boot_data.start = 0x20000000,指明boot data應從0x20000000處開始存放,所謂boot data即IVT和image的統稱,看到這,你應該明白了0x0 - 0x3FF處為何全是0的原因了吧。

#define HAB_TAG_IVT0 0xd1     /**< Image Vector Table V0 */

/** @ref hab_header structure */
typedef struct hab_hdr {
    uint8_t tag;              /**< Tag field */
    uint8_t len[2];           /**< Length field in bytes (big-endian) */
    uint8_t par;              /**< Parameters field */
} hab_hdr_t;

/** @ref ivt structure */
struct hab_ivt_v0 {
    /** @ref hdr with tag #HAB_TAG_IVT0, length and HAB version fields */
    hab_hdr_t hdr;
    /** Absolute address of the first instruction to execute from the image */
    uint32_t entry;
    /** Reserved in this version of HAB: should be NULL. */
    uint32_t reserved1;
    /** Absolute address of the image DCD: may be NULL. */
    uint32_t dcd;
    /** Absolute address of the Boot Data: may be NULL, but not interpreted any further by HAB */
    uint32_t boot_data;
    /** Absolute address of the IVT.*/
    uint32_t self;
    /** Absolute address of the image CSF.*/
    uint32_t csf;
    /** Reserved in this version of HAB: should be zero. */
    uint32_t reserved2;
};

/** @ref boot_data structure */
typedef struct boot_data{
    uint32_t start;           /* Start address of the image */
    uint32_t size;            /* Size of the image */
    uint32_t plugin;          /* Plugin flag */
} BOOT_DATA_T;

  既然ivt_flashloader.bin文件里的前2KB有很多冗餘數據,那不妨我們只把有效數據(IVT和boot data,0x400 - 0x42d處共44個byte)提取出來放到ivt_bootdata.bin文件里,讓我們將ivt_bootdata.bin下載進SRAM的0x20000400地址處:

PS C:\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools\sdphost\win> .\sdphost.exe -u 0x1fc9,0x0130 -- write-file 0x20000400 ..\..\..\Flashloader\ivt_bootdata.bin

Preparing to send 44 (0x2c) bytes to the target.
(1/1)100% Completed!
Status (HAB mode) = 1450735702 (0x56787856) HAB disabled.
Reponse Status = 2290649224 (0x88888888) Write File complete.

  到這裡IVT和image均已經下載進SRAM了,可以跳轉去執行Flashloader程式了,使用jump-address命令:

PS C:\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools\sdphost\win> .\sdphost.exe -u 0x1fc9,0x0130 -- jump-address 0x20000400

Status (HAB mode) = 1450735702 (0x56787856) HAB disabled.

  至此,Flashloader就算啟動完成了,jump-address命令執行完成之後,你會發現USB設備被重新枚舉了,此時新枚舉的USB-HID設備是Flashloader里的通信外設。

  如果你試著用blhost與Flashloader通信得到如下結果,恭喜你,Flashloader已被成功啟動了。

PS C:\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools\blhost\win> .\blhost.exe -u 0x15a2,0x0073 -- get-property 1

Inject command 'get-property'
Response status = 0 (0x0) Success.
Response word 1 = 1258422528 (0x4b020100)
Current Version = K2.1.0

  至此,飛思卡爾i.MX RT系列MCU的Serial Downloader模式痞子衡便介紹完畢了,掌聲在哪裡~~~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 自從老羅搞出大爆炸之後,各家安卓都內置了類似功能。UWP怎麼能落下呢,在這裡我們就一起擼一個簡單的大爆炸實現。 ...
  • 如圖: 解決方案。第一步先卸載 Web 平臺安裝程式 5.0 第二步 將你添加配的文件刪除 第三步:重新安裝就可以了 ...
  • ASP.NET Core MVC跟ASP.NET MVC觀念是一致的,使用上也沒有什麼太大的變化。之前的ASP.NET MVC把MVC及Web API的套件分開,但在ASP.NET Core中MVC及Web API用的套件是相同的。 本篇將介紹ASP.NET Core MVC設置方式。 MVC 簡介 ...
  • AWK的數組用法跟javascript類似。 1,定義數組 2,列印一個沒有定義的數組項,值為空 3,判斷一個數組項 是否存在,用 ( 下標 in 數組 ) 4,數組也可以用關聯索引定義 5,delete:刪除一個數組項或者一個數組 6,數字,字元串都可以進行算術運算 >當一個不存在的元素,參與算術 ...
  • Linux基本命令: 大數據課程推薦: ...
  • grep 文本搜索工具,根據用戶指定的“模式”對目標文本逐行進行匹配檢查;列印匹配到的行 grep [OPTIONS] PATTERN [FILE…] –color=auto: 對匹配到的文本著色顯示 -v: 顯示不被pattern匹配到的行 -i: 忽略字元大小寫 -n: 顯示匹配的行號 -c: ...
  • vSphere 基礎物理架構中存儲是一個非常關鍵的部分,沒有好的存儲,虛擬化也就沒有存在的價值,並且它能夠決定其系統性能的高低和如vMotion等高級功能能否實現。所以本次重點介紹vSphere中的存儲和vMtion。 一、實驗拓撲圖: 二、實驗目標: 通過搭建共用存儲,實現虛擬機的遷移與管理。 三 ...
  • 用過gothub或者碼雲的同學都知道,不包含任何文件的空文件夾上傳提交時不被允許的。當然你可以在空文件下創建.keep文件(或.gitkeep文件),然後就可以上傳了。 但是如果空文件夾比較多,並且我們確實不需要這些空文件了,那本文就學習一種命令行刪除所有空文件夾的方法。並封裝成.bat批處理程式。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...