大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是通过USB Device Path来唯一指定i.MXRT设备进行ROM/Flashloader通信。
i.MXRT系列高性能微控制器从2018年发布至今已有2年多了,如今这个家族系列已经完全开枝散叶了(RT500/600/1010/1020/1050/1060/1170),型号从入门到高阶铺得挺齐全(当然仍在继续发展),很多i.MXRT客户项目也已经处于量产阶段了。
关于量产,除了使用第三方独立Flash烧录器/编程器之外,也可以使用恩智浦官方提供的配套上位机GUI工具软件(Mfgtool2 / MCUBootUtility / MCUBootFlasher / MCUX Secure Privisioning Tool 等)连接i.MXRT芯片进行在线量产。但是呢,还是有一些客户会选择自己设计量产脚本进行定制化批量下载操作。
说到定制化批量下载操作就离不开恩智浦官方提供的i.MXRT配套命令行工具(sdphost/blhost),借助这两个命令行工具,我们就可以通过UART/USB口与I.MXRT ROM/Flashloader进行数据通信完成应用程序下载了,不需要额外硬件。
如果是串口下载,那板卡批量操作倒不会有什么问题,毕竟每个串口设备在PC上都会被分配到唯一的COM号。但是UART速度不太高,所以我们往往会选择USB高速下载,i.MXRT的USB下载主要支持USB-HID协议,配套命令行工具如果仅通过vid,pid来识别设备,那多块板卡操作肯定没法同时进行,因为所有板卡的vid,pid都是一样的,那该怎么办?痞子衡今天要介绍的USB Device Path就是解决这个问题的。
一、sdphost/blhost使用方法
i.MXRT系列中均有BootROM,BootROM里集成了上位机通信协议(i.MXRT1xxx是SDPHost协议,i.MXRTxxx是blhost协议),i.MXRT1xxx下载还需搭配Flashloader(Flashloader里上位机通信协议是blhost协议),因此与i.MXRT进行量产下载通信离不开sdphost/blhost工具。
关于sdphost/blhost工具用法,痞子衡写过详细介绍文章:《sdphost使用方法》、《blhost使用方法》。如果是单块板卡的操作,那么仅需vid,pid信息即可完成命令行操作,毕竟在PC端通过提供的vid,pid可以找到唯一的i.MXRT设备。
命令格式:sdphost.exe -u vid,pid -- command arg
命令示例:sdphost.exe -u 0x1fc9,0x0130 -- write-file 0x20002000 flashloader.bin
命令格式:blhost.exe -u vid,pid -- command arg
命令示例:blhost.exe -u 0x15a2,0x0073 -- write-memory 0x60000000 bt_image.bin
但是如果是多块板卡同时操作,仅仅vid,pid信息就不够用了,因为这些板卡的vid,pid是一样的,PC端没法具体识别脚本里的命令对应的是哪块板卡(所以可能会随机指定,但这样失去了意义,我们做不到精确控制下载每一块板卡),此时我们需要给命令行工具提供usb device path来代替usb vid,pid:
命令格式:sdphost.exe/sdphost.exe -u device_path -- command arg
二、什么是USB Device Path?
Windows操作系统通过一个“设备路径”来唯一“标识”接入系统中的USB设备/接口,这个"设备路径"就是USB Device Path。USB Device Path 常常被传入 Win32 的API函数 CreatFile() 来与USB设备建立通信。更多解释参见 Windows USB Device Path 。
三、获取USB Device Path的方法
现在的问题就是如何找到这个USB Device Path,我们以MIMXRT1020-EVK板卡为例来实战,将板卡调成SDP启动模式,将USB连接到PC后可在设备管理器里看到新枚举的 HID-compliant vendor-define device 设备,这就是BootROM里集成的USB通信功能在起作用。
3.1 借助pywinusb库
第一种方式是借助Windows经典的WinUSB库,WinUSB是从XP-SP2起微软提供的一个类似libusb与usb设备通信的中间件,通过它我们就不需要再费奏折的研究和编写USB驱动了。为了简便起见,我们不直接用C版本的WinUSB,而用下面的Python版本库pywinusb来替代:
- pywinusb地址: https://pypi.org/project/pywinusb/
安装好Python以及pywinusb库后,执行下面非常简单的几句代码便可找到USB Device Path:
import pywinusb.hid as hid
vid = 0x1fc9
pid = 0x0130
_filter = hid.HidDeviceFilter(vendor_id = vid, product_id = pid)
hid_device = _filter.get_devices()
if len(hid_device) > 0:
print(hid_device[0].device_path)
3.2 通过MCUBootFlasher工具
如果你不熟悉Python,觉得上一种方法麻烦,那么推荐你第二种方法,直接使用一次 MCUBootFlasher 工具,这个工具就是借助 USB Device Path 进行的多板卡量产操作。我们可以在工具GUI后面的控制台窗口里看到实际的命令序列,序列里有你想要的USB Device Path值:
3.3 看设备管理器和系统注册表
如果你觉得第二种方法还是麻烦,不想额外安装软件,得了,那就直接在Windows里查看吧。打开设备管理器,找到vid,pid是0x1fc9,0x0130(其他i.MXRT型号可能不是这个,具体查看芯片参考手册System Boot章节)的设备,右击属性里找到 Device instance path,别急,这还不是全部的USB Device Path。
在系统命令行里输入 "regedit" 打开系统注册表,在里面搜索 "HumanInterfaceDevice",可以找到 {4d1e55b2-f16f-11cf-88cb-001111000030},这是Windows本身对HID设备的类型标识(这个其实是确定的,记住就好,不用每次都查找一次)。
最终 USB Device Path 组成格式是:\\?\(第一部分,固定的), hid#vid_1fc9&pid_0130#a&2eb8245&0&0000(第二部分,即Device instance path,\用#替换), #{4d1e55b2-f16f-11cf-88cb-001111000030}"(第三部分,HID类型标识值前加个#)。另外注意在脚本里写入此参数时需要用双引号括起来,即如下:
"\\?\hid#vid_1fc9&pid_0130#6&20AC856D&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
至此,通过USB Device Path来唯一指定i.MXRT设备进行ROM/Flashloader通信痞子衡便介绍完毕了,掌声在哪里~~~
欢迎订阅
文章会同时发布到我的 博客园主页、****主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。