Flashloader程式主要是用來將你的Application下載進i.MXRT支持的所有外部非易失性存儲器中,為後續從外部存儲器啟動做準備。BootROM只有啟動Application功能,沒有下載更新Application功能,而Flashloader最核心的就是下載更新Application... ...
大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是飛思卡爾i.MX RT系列MCU的Flashloader。
在上一篇文章 飛思卡爾i.MX RT系列微控制器啟動篇(3)- Serial Downloader模式(sdphost, mfgtool) 里痞子衡為大家介紹了i.MXRT Boot的Serial Downloader模式,這種模式主要是用來引導啟動Flashloader,那麼Flashloader到底具有哪些功能?這是本篇文章痞子衡要為大家解惑的主題。
痞子衡在前面提過Flashloader程式主要是用來將你的Application下載進i.MXRT支持的所有外部非易失性存儲器中,為後續從外部存儲器啟動做準備。BootROM只有啟動Application功能,沒有下載更新Application功能,而Flashloader最核心的就是下載更新Application功能,所以Flashloader是BootROM的完美補充。你可能會疑問,為什麼不把Flashloader的下載更新Application的功能也放進BootROM里?痞子衡個人覺得應該是晶元成本問題,ROM的空間是96KB(RT102x/RT105x)/128KB(RT106x),如果把Flashloader功能也放進BootROM里,勢必要擴大ROM空間,從而導致晶元成本上升,做成二級Flashloader既不占ROM空間,也方便Flashloader程式自身的維護升級(目前RT1050的Flashloader版本是1.1,你看,這不顯然升級過嘛)。
一、進入Flashloader程式
1.1 官方程式包
恩智浦提供了 Flashloader程式包,你首先需要下載這個Flashloader包,Flashloader所有相關資源全在包裡面。註:每個i.MXRT子系列均有一個以子系列名字命名的Flashloader包,即Flashloader程式並不是通用的(偷偷告訴你,其實RT105x與RT106x是通用的),此處以RT1050系列為例:
Flashloader程式是\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Flashloader\flashloader.elf
Flashloader工具在\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools目錄下
1.2 三種引導方式
其實引導啟動Flashloader的方式並不唯一,Flashloader就是一段運行在SRAM中的應用程式而已,只要能有工具將Flashloader下載進SRAM,並將CPU的PC指針指向Flashloader的程式入口便可啟動Flashloader。下麵痞子衡分別介紹3種引導方式:
1.2.1 標準方式:通過sdphost
第一種引導方式是通過BootROM的Serial Downloader模式和sdphost.exe工具,這是恩智浦官方推薦的方式,這種方式在上一篇文章里已經詳細介紹過了,這裡不再贅述。
這種方式的優點是不需要外接調試器,缺點是涉及到BootROM啟動以及IVT的知識,需要有BootROM相關知識儲備。
1.2.2 簡便方式:通過J-Link Commander
第二種引導方式是通過外接J-Link調試器和J-Link Commander工具(JLink.exe)。i.MXRT晶元JTAG口連接上J-Link調試器後,安裝好Jlink驅動(痞子衡安裝的是v6.30e版本),打開J-Link Commander(即\SEGGER\JLink_V630e\JLink.exe),連接上i.MXRT的Core,按順序執行如下JLink命令:
J-Link>loadfile C:\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Flashloader\flashloader.srec
Downloading file [C:\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Flashloader\flashloader.srec]... O.K.
J-Link>mem32 0x20002000 2
20002000 = 20215A70 20014B91
J-Link>wreg MSP 20215A70
MSP = 0x20215A70
J-Link>wreg PSP 20215A70
PSP = 0x20215A70
J-Link>SetPC 20014B91
J-Link>g
到這裡Flashloader就已經被成功啟動了,有朋友看不懂上面的一串JLink命令,痞子衡為大家解釋一下:
- loadfile命令用於將Flashloader程式數據(.srec格式,含地址信息)下載進SRAM(0x20002000)中;
- mem32命令用於從起始下載地址(0x20002000)讀回部分數據(8位元組)確認上一步的下載操作是否成功,並且獲取Flashloader的起始SP和PC值。
- wreg命令用於設置R13(MSP/PSP)寄存器的值,使其等於Flashloader的初始SP值。
- SetPC命令用於設置R15(PC)寄存器的值,使其指向Flashloader的初始PC。
- g命令用於讓Core開始執行代碼(Flashloader程式)。
這種方式的優點是不需要藉助BootROM(你可以不用瞭解BootROM相關工具用法),缺點是需要額外準備一個J-Link調試器。
Note:關於JLink命令的詳細解釋請查閱JLink驅動軟體安裝目錄下\SEGGER\JLink_V630e\Doc\UM08001_JLink.pdf文檔里的3.2 J-Link Commander (Command line tool)一節。
1.2.3 高級方式:通過Ozone
前兩種引導方式都是把Flashloader程式當做黑盒子,只需要將其啟動運行即可,接下來痞子衡介紹的引導方式可以讓你看到Flashloader源代碼並且可以讓你調試Flashloader。這第三種引導方式還是通過外接J-Link調試器,但還需要一個特殊的軟體,即SEGGER公司提供的Ozone軟體,去SEGGER先下載Ozone軟體(痞子衡下載的版本是v2.56c),下載安裝後打開Ozone軟體,第一步選擇CM7,第二步選擇SWD,第三步選擇elf文件時要選擇Flashloader下載包里的flashloader.elf
確認elf文件後,點擊“Download & Reset Program”
此時Flashloader程式已經被下載進i.MXRT中,並且在Disassembly視窗可以看到Flashloader彙編源程式,底下你就可以開始調試執行Flashloader程式。由於下載包里的flashloader.elf文件並沒有包含所有Flashloader工程的信息(至少沒有包含C代碼信息,應該是恩智浦官方故意這麼做的),所以我們使用Ozone軟體調試看不到C代碼,稍微有點遺憾。
1.3 支持的通信外設pinout
Flashloader支持的通信外設與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 |
Note: 如果硬體板上UART_RX引腳沒有接上拉電阻,可能會導致USB-HID設備枚舉成功率降低,因為UART_RX懸空輸入會有干擾數據使得Flashloader誤以為UART是active peripheral,所以安全起見,請保證UART_RX引腳連接上拉電阻。
二、blhost/elftosb/mfgtool的使用
Flashloader配套上位機工具有3個,elftosb.exe用於生成sb格式文件(這個工具後續會詳細介紹),mfgtool是GUI軟體(上一篇文章已經介紹過,其主要配合sb文件使用),blhost.exe是痞子衡在這裡要著重介紹的軟體。
blhost.exe是命令行工具,使用blhost既可以通過UART口也可以通過USB口與Flashloader進行通信與命令交互。
在命令行下打開blhost.exe,輸入-?命令可以看到blhost使用幫助,相比sdphost,blhost支持的命令更多:
PS C:\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools\blhost\win> .\blhost.exe -?
usage: C:\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\Tools\blhost\win\blhost.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,57600)
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,0x0073) or device path
-t/--timeout <ms> Set packet timeout in milliseconds
(default=5000)
Memory ID:
Internal Memory Device internal memory space
0 Internal Memory
(Default selected memory)
Mapped External Memory The memories that are remapped to internal space,
and must be accessed by internal addresses.
(IDs in this group are only used for flash-erase-all and
configure-memory, and ignored by write-memory, read-memory,
flash-erase-region and flash-image(use default 0))
1 QuadSPI Memory
8 SEMC NOR Memory
9 FlexSPI NOR Memory
Unmapped External Memory Memories which cannot be remapped to internal space,
and only can be accessed by memories' addresses.
(Must be specified for all commands with <memoryId> argument)
256 (0x100) SEMC NAND Memory
257 (0x101) SPI NAND Memory
272 (0x110) SPI NOR/EEPROM Memory
273 (0x111) I2C NOR/EEPROM Memory
288 (0x120) uSDHC SD Memory
289 (0x121) uSDHC MMC Memory
** Note that not all memories are supported on all
Kinetis Bootloader platforms.
Command:
reset Reset the chip
get-property <tag> [<memoryId> | <index>]
1 Bootloader version
2 Available peripherals
7 Available commands
10 Verify Writes flag
11 Max supported packet size
12 Reserved regions
14 Start of RAM, <index> is required
15 Size of RAM, <index> is required
23 QuadSpi initialization status
24 Target version
25 External Memory Attrubutes, <memoryId> is required.
set-property <tag> <value>
10 Verify Writes flag
flash-erase-region <addr> <byte_count> [memory_id]
Erase a region of flash according to [memory_id].
flash-erase-all [memory_id] Erase all flash according to [memory_id],
excluding protected regions.
read-memory <addr> <byte_count> [<file>] [memory_id]
Read memory according to [memory_id] and write to file
or stdout if no file specified
write-memory <addr> [<file>[,byte_count]| {{<hex-data>}}] [memory_id]
Write memory according to [memory_id] from file
or string of hex values,
e.g. data.bin (writes entire file)
e.g. data.bin 8 (writes first 8 bytes from file)
e.g. "{{11 22 33 44}}" (w/quotes)
e.g. {{11223344}} (no spaces)
fill-memory <addr> <byte_count> <pattern> [word | short | byte]
Fill memory with pattern; size is
word (default), short or byte
receive-sb-file <file> Receive SB file
execute <addr> <arg> <stackpointer>
Execute at address with arg and stack pointer
call <addr> <arg> Call address with arg
configure-memory <memory_id> <internal_addr>
Apply configuration block at internal memory address
<internal_addr> to memory with ID <memory_id>
flash-image <file> [erase] [memory_id]
Write a formated image <file> to memory with ID
<memory_id>. Supported file types: SRecord
(.srec and .s19) and HEX (.hex). Flash is erased
before writing if [erase]=erase. The erase unit
size depends on the target and the minimum erase
unit size is 1K.
list-memory List all on-chip Flash and RAM regions, and off-chip
memories, supported by current device.
Only the configured off-chip memory will be list.
efuse-program-once <addr> <data>
Program one word of OCOTP Field
<addr> is ADDR of OTP word, not the shadowed memory address.
<data> is hex digits without prefix '0x'
efuse-read-once <addr>
Read one word of OCOTP Field
<addr> is ADDR of OTP word, not the shadowed memory address.
generate-key-blob <dek_file> <blob_file>
Generate the Blob for given Dek Key
<dek_file> - input, a binary Dek Key (128 Bits) generated by CST tool.
<blob_file> - output, a generated blob (72 Bytes) in binary format.
** Note that not all commands/properties are supported on all
Kinetis Bootloader platforms.
讓我們嘗試一下使用blhost與Flashloader通信(通過USB-HID),如果能得到如下結果,說明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
三、下載更新Application示例
因為BootROM支持啟動的外部存儲器很多,所以Flashloader支持下載更新的外部存儲器也與BootROM一一對應。在上一節blhost的命令幫助里,我們可以看到Memory ID里已經給各種外部儲存器分配了ID號,在使用blhost命令時使用不同的ID號即可操作相應外部存儲器。
其實Flashloader已經把外部存儲器的下載更新Application操作封裝得很簡單也很統一,我們其實只需要3步操作即可完成Application的下載。以Block Size為128KB的Raw NAND為例(即SEMC NAND Memory,Memory ID=0x100):
// 在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 // block index = 2, block count = 1
// 使用Raw NAND配置數據去配置Raw NAND介面
blhost -u -- configure-memory 0x100 0x2000
// 擦除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
其中image.bin是包含IVT的Application鏡像數據,關於上述命令的具體意義痞子衡會在後續Raw NAND啟動的文章里詳盡解釋,這裡只是給大家一個初步體驗。
至此,飛思卡爾i.MX RT系列MCU的Flashloader痞子衡便介紹完畢了,掌聲在哪裡~~~