WebUSB通讯协议
一、说明
WebUSB是Vllink产品中预留的专用接口,其数据通过
端点0传输,可以与其他上位机同时使用,甚至能实现访问目标芯片的功能本文所有数据结构皆为小端模式,为方便撰写,部分内容以伪代码或者C语言呈现
1.1 适用硬件
Vllink Basic2,且固件版本>=
V00.40
1.2 查找接口
{vendorId, productId} :{0x1209, 0x6666} 或者 {0x0d28, 0x0204}
interfaceClass == 0xFF
interfaceSubclass == 0x03
满足上述条件后,
claimInterface,检查:interfaceName == "WebUSB: CMSIS-DAP"
1.3 接口参数
控制传输、端点0
包最大长度为512字节,且DAP请求及应答长度都限制在512字节
1.4 限制
本接口为专用单一接口,未防止出现多主机干扰,通讯前需要
claimInterface,独占该接口
二、通讯
读
bRequestType == (USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_IN)
bRequest 为 命令,见协议章节
wValue 为 命令参数,见协议章节
wIndex 为 "1.2节中获得的接口号"
wLength 为 数据长度,不得超过512,可以统一为512字节,USB设备会返回实际长度
写
bRequestType == (USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT)
bRequest 为 命令,见协议章节
wValue 为 命令参数,见协议章节
wIndex == "1.2节中获得的接口号"
wLength 为 数据长度,不得超过512
三、协议
3.1 读命令
3.1.1 调试器查询 bRequest == 0x00
获取调试器及其已连接的无线调试器信息,数据结构如下:
struct { uint8_t select_idx; uint8_t reserved[27]; struct { uint64_t us; uint32_t delay_us; uint8_t alias[32]; } local, remote[10]; } __attribute__((packed)) debugger_info;
debugger_info.select_idx表示选定的调试器debugger_info.local.us表示应答时间戳,单位为微秒,每次应答时更新debugger_info.remote[i].us表示远端建立连接时的时间戳,单位为微秒,建立连接时更新;若为0,表示未连接debugger_info.*.delay_us表示DAP命令响应延迟,基于简易查询命令测量,仅对已选定的调试器测量debugger_info.*.alias表示调试器的别名
3.1.2 DAP应答 bRequest == 0x10
wValue无意义获取DAP应答,应答数据在
DAP请求完成后更新此命令需配合DAP查询使用
数据格式遵循DAP协议
3.1.3 DAP查询 bRequest == 0x11
wValue无意义获取DAP请求的结果,数据结构如下:
struct { int16_t result; } dap_result;
dap_result.result < 0表示DAP请求错误,无应答数据dap_result.result == 0表示DAP请求未完成dap_result.result > 0表示DAP请求完成,可以继续执行DAP应答注意:
dap_result.result > 0时,dap_result.result的值可以作为DAP应答的最大长度,但实际应答长度可能小于此最大长度,甚至为0
3.2 写命令
3.2.1 调试器选定 bRequest == 0x00
wValue数据结构如下:union { uint16_t wValue; struct { uint8_t select_idx; uint8_t reserved; }; } debugger_select;
debugger_select.select_idx == 0表示选定有线调试器debugger_select.select_idx > 0表示选定无线调试器,对应调试器查询命令中的debugger_info.remote[select.select_idx - 1],且要求debugger_info.remote[select.select_idx - 1].us != 0
3.2.2 DAP请求 bRequest == 0x10
通过
wValue指定调试器,数据结构如下:union { uint16_t wValue; struct { uint8_t select_idx; uint8_t reserved; }; } req_select;
支持
req_select.select_idx == 0,表示DAP请求传递给有线调试器支持
req_select.select_idx == debugger_info.select_idx,表示DAP请求传递给当前选定的调试器发送DAP请求
数据格式遵循DAP协议
3.3 建议
调试器查询 的轮询间隔推荐
250毫秒DAP查询 的轮询间隔推荐
2毫秒,仅在 DAP请求 之后进行