ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

WireShark+USBPcap:零成本搞定MCU USB协议抓包与调试

WireShark+USBPcap:零成本搞定MCU USB协议抓包与调试 1. 为什么我要折腾USB抓包这件事搞MCU开发的朋友大概率都遇到过这种场景板子插上电脑设备管理器里能看到一个USB设备但上位机软件就是收不到数据或者收到的数据全是乱码。你盯着代码看了半天枚举描述符没问题端点配置也没问题但数据就是不对。这时候如果手边没有一台USB协议分析仪基本就是盲人摸象。专业USB分析仪动辄几千上万块对于个人开发者和小团队来说成本太高。好在还有一条软件方案的路可以走用WireShark配合USBPcap在Windows主机侧把经过USB总线的数据包完整抓下来然后像分析网络包一样逐层拆解USB协议。这套方案我用了好几年从HID设备到CDC串口从自定义Bulk传输到音频流基本都能覆盖。这篇文章面向的是有MCU开发基础、但还没系统用过USB抓包工具的工程师。我会从工具选型、安装配置、抓包操作、数据解析到常见问题排查把整个流程拆开揉碎讲清楚。你不需要有USB协议栈的深厚背景只要知道端点、描述符这些基本概念跟着走一遍就能上手。中间我会穿插一些自己踩过的坑和实际调试中的经验这些内容在官方文档里通常找不到但对实际工作帮助很大。2. 工具选型与安装WireShark和USBPcap怎么配2.1 为什么是WireShark加USBPcap这个组合Windows平台上做USB抓包可选的方案其实不多。Bus Hound算一个老牌工具但它只能看到数据内容看不到完整的协议层次结构而且对新版本Windows的兼容性越来越差。USBlyzer功能比较全但收费。WireShark本身是网络协议分析工具它通过USBPcap这个捕获驱动来获取USB总线的数据然后把USB协议解析集成到自己的协议树里。这个组合的核心优势在于WireShark的显示过滤器极其强大你可以像过滤TCP端口一样过滤USB端点地址、传输类型、设备地址。而且WireShark的协议解析是逐层展开的从USB URBUSB Request Block到设备描述符、配置描述符、接口描述符、端点描述符再到具体的数据载荷每一层都能点开看原始字节。这对于调试枚举失败、端点配置错误这类问题特别有用。另一个实际考虑是成本。WireShark免费开源USBPcap也是免费的整套方案零成本。对于日常调试来说它的功能已经覆盖了百分之九十以上的需求。当然它也有局限比如抓不到USB 3.0以上的超高速信号对某些主机控制器的兼容性也有差异这些后面会详细说。2.2 安装步骤与版本选择建议安装顺序很重要先装USBPcap还是先装WireShark结果会不一样。我的建议是先装USBPcap再装WireShark。原因是WireShark安装程序会自动检测系统里是否已经安装了USBPcap如果检测到了它会在安装过程中把USBPcap的捕获接口集成进去。反过来先装WireShark的话后面再装USBPcapWireShark不一定能自动识别到新的捕获接口需要手动配置。具体步骤去USBPcap的官方发布页面下载最新稳定版安装包。截至我写这篇文章的时候1.5.x版本是比较稳定的选择。下载的时候注意选对架构现在基本都是64位系统了。运行USBPcap安装程序。安装过程中会提示你选择要捕获的USB根集线器Root Hub。这里有个关键点不要全选。全选会导致所有USB设备的数据都被捕获包括你的鼠标键盘抓出来的包会非常混乱。正确的做法是只勾选你目标设备所在的那个根集线器。怎么知道是哪个可以在设备管理器里查看目标设备的“位置”属性里面会显示它挂在哪个集线器下。安装完USBPcap后重启一次系统。这一步不能省因为USBPcap是内核态驱动需要重启才能完全加载。安装WireShark。安装过程中会提示安装Npcap这是网络抓包用的和USB抓包无关但建议一起装上以后抓网络包也用得到。安装完成后在WireShark的捕获接口列表里应该能看到“USBPcap1”、“USBPcap2”这样的接口数字对应你之前勾选的根集线器编号。注意如果你用的是Windows 11的较新版本可能会遇到USBPcap驱动签名的问题。解决办法是去USBPcap的GitHub仓库找最新的测试版或者临时禁用驱动签名强制。但后者不推荐长期使用调试完记得恢复。2.3 验证安装是否成功装完之后怎么确认能用最简单的办法打开WireShark在接口列表里找到USBPcap开头的接口双击开始捕获。然后插拔一下你的MCU设备如果能在捕获窗口里看到大量的USB URB数据包说明配置成功了。如果什么都看不到先检查USBPcap安装时勾选的根集线器是否正确再检查设备是否真的挂在那条总线上。我遇到过一种情况设备插在USB 3.0口上但USBPcap只捕获了USB 2.0的根集线器结果什么都抓不到。解决办法是把设备插到USB 2.0口上或者在USBPcap安装时勾选对应的USB 3.0根集线器。不过USBPcap对USB 3.0的支持确实有限有些主机控制器上表现不稳定这个后面会细说。3. USB协议抓包的核心原理与数据流3.1 USB数据传输的基本模型要理解抓到的包得先搞清楚USB协议的基本模型。USB是主从架构主机你的电脑是老大设备MCU板子是小弟。所有通信都由主机发起设备只能被动响应。主机每隔固定时间轮询一次设备问它有没有数据要发或者给它发数据。每次通信的基本单位叫“事务”Transaction。一个事务包含三个阶段令牌阶段Token、数据阶段Data、握手阶段Handshake。令牌阶段是主机发出的告诉设备这次要干什么——是读数据IN、写数据OUT还是设置地址SETUP。数据阶段是实际传输的数据。握手阶段是接收方发出的确认信号ACK或否定信号NAK。在WireShark里你看到的每一个USB包实际上是一个URBUSB Request Block。URB是操作系统内核里描述一次USB传输请求的数据结构。USBPcap捕获的就是这些URB然后WireShark把它们解析成人类可读的协议树。3.2 USBPcap的捕获机制USBPcap的工作方式是在Windows内核的USB驱动栈里插入一个过滤驱动。当URB在主机控制器驱动和USB功能驱动之间传递时USBPcap把它截获一份打包成pcap格式通过一个虚拟接口暴露给WireShark。这里有个关键点USBPcap捕获的是主机侧的URB不是总线上的原始电气信号。这意味着两件事。第一你看到的是主机“打算”发送或接收的数据而不是实际在D/D-线上跑的信号。如果设备因为电气问题没有正确响应USBPcap可能显示主机发了数据但设备没回ACK但具体是信号完整性问题还是设备固件问题它区分不了。第二USBPcap的捕获点决定了它能看到什么层次的信息。它能看到完整的描述符、端点配置、数据载荷但看不到底层的位填充、CRC校验这些物理层细节。这个特性决定了它的适用场景调试协议层的问题非常合适调试物理层信号问题就不行了。如果你怀疑是信号完整性问题还是得用示波器或者专业分析仪。3.3 WireShark如何解析USB数据WireShark内置了USB协议的解析器。当你打开一个USBPcap捕获的文件时WireShark会按照USB规范逐层解析每个URB。解析的层次大致是这样的最外层是USBPcap的伪包头包含设备地址、端点号、传输类型等元信息。然后是USB URB头包含URB的类型控制传输、批量传输、中断传输、等时传输、方向、数据长度等。如果是控制传输还会解析出SETUP包的内容包括bmRequestType、bRequest、wValue、wIndex、wLength这些字段。最后是数据载荷根据上下文可能是描述符、HID报告、CDC数据等。WireShark的显示过滤器可以基于这些字段做筛选。比如你想只看设备地址为5的端点1的IN传输可以用usb.device_address 5 usb.endpoint_address 0x81。这个过滤器语法和网络包的过滤器类似但字段名是USB特有的。4. 实战抓包从枚举到数据传输的完整流程4.1 抓包前的准备工作在开始抓包之前有几件事需要先做好。第一确认你的MCU设备固件已经烧录好并且设备本身能正常上电。第二把设备插到电脑上在设备管理器里确认它被识别了。如果设备管理器里显示黄色感叹号说明枚举就有问题这时候抓包正好能帮你定位问题出在哪一步。第三关闭其他无关的USB设备。特别是鼠标、键盘、U盘这些它们会产生大量中断传输的包干扰你的分析。如果条件允许用一个独立的USB扩展卡或者Hub只接你的目标设备。第四在WireShark里设置好捕获过滤器。USBPcap支持捕获过滤器可以在抓包之前就过滤掉不需要的流量。比如你只想抓设备地址为5的包可以在捕获接口的配置里设置usb.device_address 5。不过设备地址在枚举过程中会变化所以如果你要抓完整的枚举过程建议先不要设过滤器抓完再用显示过滤器筛选。4.2 捕获设备枚举过程设备枚举是USB通信中最关键也最容易出问题的环节。枚举过程大致分为这几个步骤主机检测到设备插入发送复位信号。主机用地址0向设备发送GET_DESCRIPTOR请求获取设备描述符的前8个字节。主机再次复位设备然后用地址0发送SET_ADDRESS请求给设备分配一个新地址。主机用新地址发送GET_DESCRIPTOR请求获取完整的设备描述符。主机获取配置描述符、接口描述符、端点描述符。主机发送SET_CONFIGURATION请求选择配置。如果是HID设备主机还会获取HID报告描述符。在WireShark里抓这个过程你会看到大量的控制传输包。重点看几个地方SET_ADDRESS请求是否成功设备是否回了ACKGET_DESCRIPTOR请求的wLength字段是否正确设备返回的数据长度是否匹配SET_CONFIGURATION请求的wValue字段是否和你的配置值一致。我遇到过一个典型问题设备描述符里的bMaxPacketSize0字段写的是64但实际端点0的缓冲区只有8字节导致主机在获取完整设备描述符时数据溢出枚举失败。在WireShark里看就是GET_DESCRIPTOR请求发出后设备返回的数据长度不对或者直接回了STALL。这种问题看代码很难发现但抓包一看就清楚了。4.3 捕获批量传输和中断传输枚举成功后设备进入正常工作状态。这时候的数据传输主要是批量传输Bulk和中断传输Interrupt。批量传输用于大量数据比如CDC串口的数据收发中断传输用于小量、周期性的数据比如HID报告。抓批量传输的时候重点看端点的数据长度和实际传输长度是否一致。比如你配置的端点最大包长是64字节但实际发送了100字节的数据主机会把它拆成两个包第一个64字节第二个36字节。在WireShark里能看到两个URB第二个的data_length是36。如果设备固件里没有正确处理分包就可能出现数据丢失或错位。中断传输的抓包要注意轮询间隔。主机按照端点描述符里bInterval字段指定的间隔来轮询设备。如果bInterval设得太小比如1ms而设备固件处理不过来就会频繁回NAK。在WireShark里会看到大量的NAK握手包。这时候需要调整固件的处理逻辑或者增大bInterval。4.4 用显示过滤器精准定位问题抓完包之后面对成千上万个数据包怎么快速找到有用的WireShark的显示过滤器是关键。以下是我常用的几个过滤器过滤需求过滤器表达式说明只看某个设备usb.device_address 5设备地址在枚举后分配只看某个端点usb.endpoint_address 0x810x81表示端点1的IN方向只看控制传输usb.transfer_type 0x020x02是控制传输的枚举值只看批量传输usb.transfer_type 0x030x03是批量传输只看中断传输usb.transfer_type 0x010x01是中断传输只看SETUP包usb.setup.bRequest有SETUP字段的包只看错误包usb.urb_status ! 0URB状态非0表示有错误这些过滤器可以组合使用比如usb.device_address 5 usb.transfer_type 0x03 usb.endpoint_address 0x01就能精确锁定设备5的端点1上的批量OUT传输。提示设备地址在每次枚举后可能不同所以抓包时最好先抓完整的枚举过程记下分配的设备地址然后再用这个地址做过滤。如果设备已经枚举好了可以在设备管理器里查看“位置”信息里面会显示设备地址。5. 常见问题排查与实战避坑指南5.1 抓不到任何USB数据怎么办这是最常见的问题原因通常有这几个第一USBPcap安装时没有勾选正确的根集线器。解决办法是重新运行USBPcap安装程序在组件选择界面勾选所有根集线器或者根据设备管理器里的位置信息精确勾选。我一般建议先全选抓一次确认能看到数据后再根据实际情况精简。第二设备插在USB 3.0口上但USBPcap只捕获了USB 2.0根集线器。USB 3.0的根集线器和USB 2.0是分开的在USBPcap的接口列表里会显示为不同的USBPcap编号。解决办法是把设备插到USB 2.0口或者在安装时勾选USB 3.0根集线器。不过USBPcap对USB 3.0的支持确实不如USB 2.0稳定有些主机控制器上会出现丢包。第三WireShark没有以管理员权限运行。USBPcap需要管理员权限才能访问内核驱动。解决办法是右键WireShark图标选择“以管理员身份运行”。第四杀毒软件或安全软件拦截了USBPcap驱动。有些安全软件会把内核过滤驱动当成可疑行为。解决办法是临时关闭安全软件或者把USBPcap加入白名单。5.2 抓到的数据包不完整或乱序USBPcap在高流量场景下可能会出现丢包。比如你的设备在做高速批量传输每秒几MB的数据USBPcap的缓冲区可能来不及处理。解决办法是增大USBPcap的缓冲区大小可以在WireShark的捕获选项里调整。另外关闭WireShark的实时显示更新也能减少开销抓完再分析。还有一种情况是数据包看起来乱序。USB协议本身是保证顺序的但USBPcap捕获的是URB多个URB可能并发提交在捕获文件里的顺序不一定和实际总线上的顺序完全一致。分析的时候要结合URB的ID和时间戳来判断。5.3 设备枚举失败怎么定位枚举失败在WireShark里通常表现为GET_DESCRIPTOR请求发出后设备回了STALL或者返回的数据长度不对或者干脆没有响应。如果设备回了STALL重点检查设备描述符里的bMaxPacketSize0字段。这个字段告诉主机端点0的最大包长是多少主机后续的GET_DESCRIPTOR请求会按照这个长度来读取。如果设备实际缓冲区比这个小就会STALL。如果返回的数据长度不对检查描述符的bLength字段。每个描述符的第一个字节是bLength表示这个描述符的总长度。如果bLength写错了主机解析就会出错。如果没有响应检查设备固件里是否正确处理了SETUP阶段。有些MCU的USB库要求在处理SETUP包后必须在规定时间内写入数据或STALL超时了主机就会认为设备无响应。5.4 批量传输数据丢失或错位批量传输出问题最常见的原因是端点缓冲区的处理逻辑有误。比如设备收到OUT数据后没有及时把数据从端点缓冲区读走下一个OUT包来了就会覆盖或者NAK。在WireShark里会看到NAK握手包或者数据长度不对。另一个常见原因是ZLPZero Length Packet的处理。USB协议规定如果传输的数据长度正好是端点最大包长的整数倍发送方需要额外发一个长度为0的包来表示传输结束。有些MCU的USB库会自动处理ZLP有些需要手动发送。如果没处理好接收方会一直等待后续数据导致超时。5.5 WireShark显示异常或崩溃WireShark在解析大量USB数据时可能会卡顿甚至崩溃。解决办法是分段抓包不要一次抓太长时间。另外关闭不需要的协议解析器也能提升性能。在WireShark的“分析”菜单里选择“启用的协议”把和USB无关的协议都取消勾选。如果WireShark打不开或者启动时报错可能是Npcap和USBPcap的版本冲突。解决办法是卸载所有捕获驱动重启后先装USBPcap再装WireShark让WireShark自动处理Npcap的安装。6. 进阶技巧从抓包到协议分析的效率提升6.1 保存和复用捕获过滤器WireShark允许你把常用的显示过滤器保存起来下次直接调用。在过滤器输入框旁边有个“保存”按钮点一下就能把当前过滤器命名保存。我一般会保存几个常用的枚举过程、批量IN、批量OUT、中断传输、错误包。这样切换起来很快不用每次手动输入。捕获过滤器也可以保存在捕获选项的接口配置里有个“捕获过滤器”输入框旁边的书签图标可以保存。不过捕获过滤器用的语法和显示过滤器不同捕获过滤器用的是BPF语法显示过滤器用的是WireShark自己的语法。USBPcap支持的捕获过滤器字段有限常用的就是usb.device_address和usb.endpoint_address。6.2 用时间戳分析传输时序USB协议对时序有严格要求特别是中断传输和等时传输。WireShark的包列表里有一列是时间戳默认显示的是相对时间。你可以右键点击时间戳列选择“设置时间参考”把某个关键包设为参考点后面的包都显示相对于它的时间。这对于分析设备响应延迟特别有用。比如你怀疑设备对某个控制传输的响应太慢可以把SETUP包设为时间参考然后看设备返回数据包的时间差。如果超过规范要求的时间就说明固件处理有问题。6.3 导出数据载荷做进一步分析WireShark可以把USB数据载荷导出成原始二进制文件。选中你要导出的包右键选择“导出分组字节流”保存成.bin文件。然后你可以用Python或者其他工具对这个二进制文件做进一步解析。比如你抓的是自定义协议的数据可以写个脚本按照你的协议格式解析每个字段。我经常用这个方法做自动化测试。抓一批数据导出然后用脚本检查数据是否符合预期。比人工在WireShark里一个个看效率高多了。6.4 结合设备固件日志交叉验证抓包只是看到了主机侧的数据设备侧到底发生了什么还需要结合固件的日志。我通常会在固件里加一些调试输出通过串口打印关键状态。抓包的时候同时打开串口终端这样主机发了什么、设备回了什么、固件里怎么处理的三方面信息一对照问题基本就定位了。比如抓包看到设备回了NAK串口日志显示固件正在处理上一个包还没完成那就说明是固件处理速度跟不上需要优化代码或者增大端点缓冲区。7. 一些实际项目中的经验体会我在实际使用这套方案的过程中最大的体会是抓包工具本身不难用难的是知道该看什么。刚开始的时候我抓了一大堆包但不知道从哪看起浪费了很多时间。后来慢慢总结出一个套路先看枚举是否成功再看端点配置是否正确然后看数据传输的握手是否正常最后看数据载荷是否符合协议。这个顺序基本能覆盖大部分问题。另一个体会是不要过度依赖抓包工具。有些问题比如信号完整性问题、电源噪声问题抓包是看不出来的。这时候还是得上示波器。抓包工具和示波器是互补的不是替代关系。还有一点USBPcap在Windows上的稳定性确实不如Linux上的usbmon。如果条件允许在Linux环境下用usbmon加WireShark体验会好很多。但Windows的普及率更高所以USBPcap还是值得掌握的。最后分享一个小技巧如果你经常调试同一款设备可以把常用的过滤器和捕获配置保存成一个配置文件每次直接加载。WireShark支持导入导出配置在“编辑”菜单的“配置配置文件”里可以管理。这样换电脑或者重装系统后不用重新配置一遍。
返回列表