你們好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給你們介紹的是飛思卡爾i.MX RTyyyy系列MCU的Serial Downloader模式。html
在上一篇文章 Boot配置(BOOT Pin, eFUSE) 裏痞子衡爲你們介紹了i.MXRT Boot的行爲配置,其中第一節裏講了Boot有三種行爲模式:Serial Downloader、Boot From Fuses、Internal Boot,後兩種是核心的加載啓動行爲模式,而Serial Downloder看起來是個次要的模式,那麼Serial Downloader模式到底有什麼用?今天痞子衡就來詳細聊一聊Serial Downloader模式。app
痞子衡在前面已經講過Serial Downloader模式是一種串行下載模式,在這種模式下,BootROM經過指定的USB或者UART口來接收來自Host(恩智浦提供了上位機工具sdphost.exe或者mfgtool)的Flashloader數據,並將數據存儲在SRAM中執行,Flashloader程序能夠用來將你的Application下載進i.MXRT支持的全部外部非易失性存儲器中,爲後續從外部存儲器啓動作準備。編輯器
i.MXRTyyyy上電永遠是從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加載啓動失敗。測試
進入了Serial Downloader模式,此時即可以用恩智浦提供的host工具與BootROM進行命令交互,host工具在 Flashloader包 裏。ui
下載好Flashloader包以後,在\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools下能夠找到全部host工具,其中用於與BootROM通訊的有兩個:sdphost.exe與MfgTool2.exe。this
BootROM支持兩種通訊外設,分別是USB-HID和UART,pinout以下(Pinout適用RT105x和RT102x):spa
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 |
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其餘命令具體如何組合使用,痞子衡會在後續的文章裏再具體介紹。
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是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就藏在前8KB數據裏,仔細看一下,你會發現除了偏移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文件會留出8KB的空間來放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文件裏的前8KB有不少冗餘數據,那不妨咱們只把有效數據(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的關係才分步將本身建立的flashloader.bin和ivt_bootdata.bin下載進SRAM,其實你能夠直接將Flashloader包裏現成的ivt_flashloader.bin下載進SRAM便可:
PS C:\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools\sdphost\win> .\sdphost.exe -u 0x1fc9,0x0130 -- write-file 0x20000000 ..\..\mfgtools-rel\Profiles\MXRT105X\OS Firmware\ivt_flashloader.bin
Preparing to send 90039 (0x15fb7) bytes to the target. (1/1)1%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 RTyyyy系列MCU的Serial Downloader模式痞子衡便介紹完畢了,掌聲在哪裏~~~