大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是恩智浦i.MX RT1xxx系列MCU的Serial Downloader模式

  在上一篇文章 Boot配置(BOOT Pin, eFUSE) 里痞子衡为大家介绍了i.MXRT1xxx 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.MXRT1xxx支持的所有外部非易失性存储器中,为后续从外部存储器启动做准备。

一、进入Serial Downloader模式

  i.MXRT1xxx上电永远是从ROM启动去执行BootROM程序,最顶层的Boot行为模式由BOOT_MODE[1:0] pins的状态决定,想进入Serial Downloader模式最直接的方式便是将BOOT_MODE[1:0]输入状态拨成2'b01,在设计i.MXRT1xxx的硬件板时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.MXRT1xxx的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就藏在前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 RT1xxx系列MCU的Serial Downloader模式痞子衡便介绍完毕了,掌声在哪里~~~

欢迎订阅

文章会同时发布到我的 博客园主页CSDN主页微信公众号 平台上。

微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

痞子衡嵌入式:飞思卡尔i.MX RT系列MCU启动那些事(3)- Serial Downloader模式(sdphost/MfgTool)的更多相关文章

  1. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(4)- OTP及其烧写方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的OTP. 在i.MXRTxxx启动系列第二篇文章 Boot配置(ISP Pin, OTP) 里痞子 ...

  2. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(1)- Boot简介

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的BootROM功能简介. 截止目前为止i.MX RTxxx系列已公布的芯片仅有一款i.MXRT60 ...

  3. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(2)- Boot配置(ISP_Pin, OTP)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的Boot配置. 在上一篇文章 Boot简介 里痞子衡为大家介绍了Boot基本原理以及i.MXRTx ...

  4. 痞子衡嵌入式:飞思卡尔i.MX RT系列MCU启动那些事(1)- Boot简介

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RT系列MCU的BootROM功能简介. 截止目前为止i.MX RT系列已公布的芯片有三款i.MXRT105x, i. ...

  5. 痞子衡嵌入式:飞思卡尔i.MX RT系列MCU启动那些事(2)- Boot配置(BOOT Pin/eFUSE)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RT系列MCU的Boot配置. 在上一篇文章 Boot简介 里痞子衡为大家介绍了Boot基本原理以及i.MXRT Bo ...

  6. 痞子衡嵌入式:飞思卡尔i.MX RT系列MCU启动那些事(4)- Flashloader初体验(blhost)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RT系列MCU的Flashloader. 在上一篇文章 Serial Downloader模式(sdphost, mf ...

  7. 痞子衡嵌入式:飞思卡尔i.MX RT系列MCU启动那些事(6)- Bootable image格式与加载(elftosb/.bd)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RT系列MCU的Bootable image格式与加载过程. 在i.MXRT启动系列第三篇文章 Serial Down ...

  8. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(13.A)- LPSPI NOR启动时间(RT1170)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RT1170 1bit SPI NOR恢复启动时间. 本篇是i.MXRT1170启动时间评测第三弹了,前两篇分别给大家评 ...

  9. 痞子衡嵌入式:飞思卡尔i.MX RT系列MCU启动那些事(5)- 再聊eFUSE及其烧写方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RT系列MCU的eFUSE. 在i.MXRT启动系列第二篇文章 Boot配置(BOOT Pin, eFUSE) 里痞子 ...

随机推荐

  1. PHP通过经纬坐标计算两个地址的距离

    <?php /** *求两个已知经纬度之间的距离,单位为米 * *@param lng1,lng2 经度 * *@param lat1,lat2 纬度 * *@return float 距离,单 ...

  2. tyflow雨滴在物体上滑落测试

    http://docs.tyflow.com/download/

  3. Redis安装、命令以及设置密码遇到的问题

    一.下载Redis 如果没有 安装wget先安装wget和gcc(使用make的时候会用上) wget http://download.redis.io/releases/redis-4.0.8.ta ...

  4. hive-issue-inserting-records-to-partitioned-table

    hive-issue-inserting-records-to-partitioned-table Hi Sam, Recently we upgraded our cluster from HDP2 ...

  5. django 利用pillow 进行简单的设置验证码(python)

    1.导入模块 并定义一个验证状态 from PIL import Image, ImageDraw, ImageFont from django.utils.six import BytesIO de ...

  6. Java作业九(2017-11-6)

    /*圆的类*/ public class R { private double radius; // 构造方法,有参构造 public R(double radius) { this.radius = ...

  7. Kotlin基础

    1.函数也是对象,可以作为参数和返回值 2.使用驼峰命名,尽量避免下划线 3.public函数应当有说明文档 4.lambda中花括号内前后都应该有空格 5.空值安全检查  var s: String ...

  8. 请不要在JDK7及以上用Json-lib了

    [Json-lib 介绍] Json-lib 是以前 Java 常用的一个 Json 库,最后的版本是 2.4,分别提供了 JDK 1.3 和 1.5 的支持,最后更新时间是 2010年12月14日. ...

  9. 【RL-TCPnet网络教程】第27章 DNS域名系统基础知识

    第27章      DNS域名系统基础知识 本章节为大家讲解DNS(Domain Name System,域名系统),通过前面章节对TCP和UDP的学习,需要大家对DNS也有个基础的认识. (本章的知 ...

  10. 【计算机篇】Office 2016 for Mac 安装和破解教程

    免责声明 请亲们支持正版.这教程旨在分享,供参考. 为啥写这篇文章 对于大多数使用 Mac 的用户而言,虽然有苹果自家的办公软件,但功能少,用起来不舒服.而 Offer 2016 版的需要登录激活购买 ...