ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

WCH DAP-LINK调试实战:驱动安装、Keil配置与故障排查

WCH DAP-LINK调试实战:驱动安装、Keil配置与故障排查 1. 为什么WCH DAP-LINK值得单独写一篇调试实战市面上做ARM Cortex-M调试的探针不少J-Link、ST-Link、CMSIS-DAP各家都有各自的生态位。WCH DAP-LINK是沁恒微电子推出的一款基于CMSIS-DAP协议的开源调试器价格通常在十几到二十几块钱支持SWD和JTAG两种接口能直接对接Keil MDK、IAR、OpenOCD等主流工具链。它的核心芯片一般是CH552或CH32系列固件层面遵循ARM官方的CMSIS-DAP规范所以理论上任何支持CMSIS-DAP的IDE都能直接识别。但“理论上支持”和“实际上跑通”之间往往隔着驱动安装、固件版本、Keil配置这几道坎。我自己在多个项目里用过WCH DAP-LINK从STM32F103到GD32E230再到CH32V系列踩过的坑不算少。这篇文章不打算写成一份干巴巴的说明书而是把驱动安装、Keil环境配置、实际调试过程中遇到的典型问题拆开来讲把每个操作背后的逻辑说清楚。如果你手头正好有一块WCH DAP-LINK或者正在纠结选哪个调试器这篇内容应该能帮你省下不少折腾的时间。需要提前说明的是WCH DAP-LINK有两个常见版本一个是早期基于CH552的版本另一个是后来基于CH32V305的版本。两者在驱动层面基本一致但在固件升级和高速调试支持上有些差异。下面涉及具体操作时我会标注版本差异没有特别说明的地方默认两者通用。2. 驱动安装从设备管理器里那个黄色感叹号说起2.1 插上探针之后系统到底认出了什么把WCH DAP-LINK插到电脑USB口上第一件事是打开设备管理器看系统识别成了什么。正常情况下你会看到两种可能的结果第一种设备管理器里出现一个“USB设备”或者“CMSIS-DAP”相关的条目没有黄色感叹号说明系统已经自带了WinUSB驱动或者探针固件里自带了描述符让系统直接识别。这种情况下你不需要额外装驱动Keil里直接选CMSIS-DAP就能用。第二种设备管理器里出现一个带黄色感叹号的未知设备名字可能是“WCH DAP-LINK”或者“USB Device”这时候就需要手动安装驱动。黄色感叹号的意思是系统认出了USB设备的存在但没有找到匹配的驱动程序来跟它通信。这里有个细节值得注意WCH DAP-LINK在固件层面模拟的是一个HID设备或者WinUSB设备。如果是HID模式Windows通常能自动识别不需要额外驱动如果是WinUSB模式就需要安装一个.inf文件来告诉系统用WinUSB驱动来对接。早期版本的WCH DAP-LINK固件默认走HID后来为了支持更高的调试速率部分固件版本改成了WinUSB模式。2.2 驱动安装的两种路径与选择逻辑WCH官方提供了两种驱动安装方式我分别说一下适用场景和操作步骤。路径一使用WCH官方提供的驱动安装工具沁恒官网的WCH DAP-LINK产品页面下会提供一个驱动安装包通常叫“WCH DAP-LINK Driver”或者类似的名字。下载之后解压里面会有一个.exe安装程序或者一个.inf文件加安装脚本。直接运行安装程序按照提示下一步下一步就行。安装完成后重新插拔探针设备管理器里应该能看到一个正常的“CMSIS-DAP”设备。这种方式的优点是省事适合不想折腾的开发者。缺点是官方安装包有时候更新不及时如果你用的是新版本固件的探针可能会遇到驱动版本不匹配的问题。路径二手动指定WinUSB驱动如果官方安装包不管用或者你用的是第三方固件的WCH DAP-LINK可以手动指定驱动。操作步骤是在设备管理器里右键那个带感叹号的设备选择“更新驱动程序”然后选择“浏览我的电脑以查找驱动程序”再选择“让我从计算机上的可用驱动程序列表中选取”。在列表里找到“WinUSB设备”或者“USB输入设备”选中之后下一步完成安装。这里有个关键点手动指定驱动的时候不要选“USB复合设备”或者“HID-compliant device”除非你确认探针固件走的是HID模式。选错了驱动类型设备管理器里可能看起来正常了但Keil里死活连不上。提示如果你不确定探针固件走的是HID还是WinUSB模式可以先用Zadig这个工具看一下。Zadig能列出当前USB设备的接口描述符如果看到的是HID接口就选HID驱动如果是Vendor Specific或者WinUSB就选WinUSB。2.3 驱动装好了但Keil认不到一个容易被忽略的排查点驱动装完设备管理器里也显示正常了但Keil的Debug选项里就是找不到CMSIS-DAP设备。这种情况我遇到过好几次原因通常出在以下几个方面第一Keil版本太老。CMSIS-DAP协议本身有几个版本早期Keil MDK 4.x对CMSIS-DAP的支持不完整建议至少用Keil MDK 5.20以上版本。如果你还在用MDK 4.74建议升级到5.x不然很多新探针都用不了。第二探针固件版本和Keil的CMSIS-DAP DLL版本不匹配。Keil安装目录下有一个CMSIS-DAP.dll文件这个文件负责跟探针通信。如果探针固件用的是较新的CMSIS-DAP v2协议而Keil自带的DLL还是v1版本就会出现认不到设备的情况。解决办法是从ARM官网下载最新的CMSIS-DAP DLL替换掉Keil安装目录下的同名文件。第三USB线或者USB口的问题。有些便宜的USB线只有充电功能没有数据线芯插上去设备管理器里能看到设备但通信不稳定。换一根确认能传数据的USB线试试。另外USB 3.0口有时候对CMSIS-DAP的兼容性不如USB 2.0口如果遇到奇怪的问题换到USB 2.0口上试试。3. Keil MDK里的调试配置从新建工程到第一次单步3.1 工程选项里那几个必须改的配置项假设你已经有一个能编译通过的Keil工程现在要把调试器从J-Link或者ST-Link切换到WCH DAP-LINK。打开Options for Target切到Debug标签页在右上角的下拉框里选择“CMSIS-DAP Debugger”然后点旁边的Settings按钮。在弹出的设置窗口里有几个地方需要确认Port模式WCH DAP-LINK支持SWD和JTAG两种模式。对于绝大多数Cortex-M芯片SWD就够了占用的引脚少速度也够快。在Port下拉框里选SWD。Max Clock这是调试时钟频率。WCH DAP-LINK在SWD模式下最高能跑到10MHz左右但实际能跑多快取决于你的目标芯片和PCB布线。建议先设成1MHz或者2MHz等确认能正常连接之后再往上调。如果设太高会出现连接不稳定或者直接连不上的情况。Reset方式这个选项决定了Keil在开始调试时如何复位目标芯片。常见的有“SYSRESETREQ”、“VECTRESET”和“Autodetect”。对于STM32和GD32系列通常选“SYSRESETREQ”就行。如果遇到复位后连不上的情况可以试试“Autodetect”或者手动指定“VECTRESET”。设置完这些之后点“OK”保存然后点Debug标签页旁边的“Utilities”标签页确认“Use Debug Driver”被勾选并且下拉框里也是“CMSIS-DAP Debugger”。这一步很多人会忽略结果烧录的时候用的还是旧的烧录器配置。3.2 第一次连接怎么判断是真的连上了配置改完之后点Keil工具栏上的“Download”按钮或者按F8如果一切正常底部的Build Output窗口会显示烧录成功的提示。但烧录成功不代表调试连接没问题真正验证连接是否正常的方法是进入调试模式。按CtrlF5或者点“Start/Stop Debug Session”按钮Keil会尝试连接目标芯片并进入调试界面。如果连接成功你会看到代码窗口左边出现一个黄色的箭头指向main函数的第一行同时底部的寄存器窗口、内存窗口都会显示出目标芯片的实时数据。如果连接失败Keil会弹出一个错误对话框常见的错误信息有“No Cortex-M Device found in JTAG chain”意思是SWD链路上没有找到目标芯片。排查方向是检查SWDIO和SWCLK两根线有没有接反目标芯片有没有供电复位引脚有没有被拉低。“Cannot access target”能识别到芯片但无法访问。通常是复位方式配置不对或者目标芯片处于低功耗模式导致调试接口被关闭。“RDDI-DAP Error”CMSIS-DAP通信错误。可能是USB连接不稳定或者探针固件有问题。3.3 调试过程中查看结构体变量的正确姿势这是很多从J-Link转到CMSIS-DAP的开发者经常问的一个问题为什么在Watch窗口里看不到结构体变量的成员在J-Link下明明可以展开的。这个问题的根源在于Keil的调试信息解析方式。Keil在调试时依赖编译生成的DWARF调试信息来解析变量类型。如果你在Watch窗口里只输入结构体变量名Keil默认只显示结构体的首地址不会自动展开成员。要看到成员需要在变量名后面加上成员访问符比如myStruct.member1或者用myStruct-member1如果是指针。但更常见的情况是你输入了myStruct.member1Watch窗口却显示“cannot evaluate”。这通常是因为编译器优化等级太高结构体成员被优化掉了或者调试信息不完整。解决办法是把优化等级降到-O0或者-O1重新编译之后再调试。另外Keil MDK 5.x版本里有一个“Periodic Window Update”选项在Debug菜单下。勾选之后Watch窗口里的变量值会在程序运行过程中自动刷新。但要注意这个功能会占用一定的调试带宽如果调试时钟设得比较低可能会导致程序运行变慢。4. 那些让人抓狂的典型故障与排查链路4.1 探针能识别但烧录失败从电源到复位的完整排查故障现象设备管理器里WCH DAP-LINK显示正常Keil的Debug设置里也能看到CMSIS-DAP设备但一点Download就报错提示“Flash Download failed”或者“Cannot Load Flash Programming Algorithm”。这个问题的排查链路我一般是这样走的第一步确认目标芯片的供电。WCH DAP-LINK的SWD接口只提供信号线不提供电源。目标板必须自己供电而且供电电压要在芯片允许的范围内。用万用表量一下目标板的VCC和GND之间的电压确认在3.3V左右。如果电压偏低可能是目标板上的LDO有问题或者USB供电不足。第二步检查SWDIO和SWCLK的接线。这两根线不能接反也不能接错到其他引脚上。STM32系列的SWDIO通常是PA13SWCLK是PA14但不同型号可能不一样查一下数据手册确认。另外有些芯片的SWD引脚在复位后会被复用为GPIO如果目标程序里把这两个引脚配置成了普通IO调试器就连不上了。解决办法是在Keil的Debug设置里把Reset方式改成“Connect under Reset”这样调试器会在芯片复位后立即接管SWD引脚。第三步检查Flash算法。Keil在烧录时需要加载对应芯片的Flash编程算法。如果算法选错了比如给STM32F103选了STM32F4的算法就会烧录失败。在Options for Target的Utilities标签页里点“Settings”按钮确认Flash Download列表里的算法跟目标芯片匹配。第四步检查复位电路。有些目标板的复位引脚上接了一个电容导致复位信号上升沿太慢调试器无法正常复位芯片。可以在复位引脚和VCC之间并一个10kΩ的上拉电阻加快复位信号的上升速度。4.2 调试过程中程序跑飞SWD时钟与看门狗的影响故障现象烧录成功也能进入调试模式但程序运行一段时间后突然跑飞或者调试器失去连接。这种情况通常有两个原因。第一个原因是SWD时钟设得太高。WCH DAP-LINK在SWD模式下虽然标称能跑10MHz但实际能跑多快取决于目标芯片的SWD接口时序和PCB走线质量。如果走线比较长或者没有做阻抗匹配高速时钟下容易出现通信错误。解决办法是把Max Clock降到1MHz或者500kHz牺牲一点调试速度换取稳定性。第二个原因是目标程序里开了看门狗但没有在调试时喂狗。看门狗溢出后会复位芯片调试器自然就失去连接了。解决办法是在调试时暂时关闭看门狗或者在调试器初始化脚本里加上喂狗的操作。Keil的Debug设置里有一个“Initialization File”选项可以指定一个.ini文件在调试开始时执行一些初始化操作。在这个文件里可以写一段代码来关闭看门狗。4.3 固件升级失败导致探针变砖的恢复方法WCH DAP-LINK支持固件升级官方会不定期发布新固件来修复bug或者增加功能。但升级过程中如果断电或者USB断开探针可能会变砖插上去设备管理器里完全认不到。遇到这种情况不用慌WCH DAP-LINK的主控芯片通常有内置的Bootloader可以通过特定的引脚组合进入DFU模式来重新烧录固件。具体操作是按住探针上的某个按键不同版本按键位置不同然后插USB设备管理器里会出现一个DFU设备。然后用WCH提供的固件烧录工具把固件重新写进去就行。如果探针上没有按键可以尝试短接主控芯片的某个引脚到GND来进入Bootloader模式。具体是哪个引脚需要查一下主控芯片的数据手册。CH552的Bootloader进入方式是上电时把P3.6引脚拉低CH32V305的方式类似但引脚不同。注意固件升级有风险如果当前固件用着没问题不建议频繁升级。升级前一定要确认USB连接稳定最好用台式机后面的USB口避免用前面板或者USB Hub。5. 从能用到好用几个提升调试效率的配置技巧5.1 用调试脚本自动初始化目标芯片Keil支持在调试开始时执行一个初始化脚本这个脚本可以用来配置目标芯片的时钟、关闭看门狗、初始化外设等。对于WCH DAP-LINK来说这个功能特别有用因为CMSIS-DAP本身不像J-Link那样有丰富的脚本支持很多初始化操作需要在Keil层面完成。在Options for Target的Debug标签页里Initialization File那一栏可以指定一个.ini文件。这个文件里可以写类似这样的内容// 关闭看门狗 _WDWORD(0x40003000, 0x0000CCCC); // 以STM32F1为例 // 配置时钟 _WDWORD(0x40021000, 0x00010001);这段代码的意思是往看门狗的控制寄存器里写入解锁序列然后往时钟配置寄存器里写入分频值。具体地址和值需要根据目标芯片的参考手册来填。5.2 在Watch窗口里高效查看外设寄存器调试嵌入式程序时经常需要查看外设寄存器的值。Keil提供了一个“System Viewer”菜单里面列出了目标芯片的所有外设寄存器可以直接查看和修改。但这个菜单只对Keil官方支持的芯片型号有效如果你用的是国产芯片或者比较冷门的型号System Viewer里可能没有对应的选项。这时候可以用Watch窗口手动添加寄存器地址。比如要看GPIOA的ODR寄存器可以在Watch窗口里输入*(unsigned int*)0x4001080CKeil会显示这个地址上的值。如果嫌每次都要输地址太麻烦可以在代码里定义一个宏或者常量指针然后在Watch窗口里引用这个变量。5.3 调试时钟与程序运行速度的平衡前面提到过SWD时钟设得太高会导致连接不稳定设得太低又会影响调试效率。我的经验是对于大多数STM32F1和F4系列2MHz是一个比较稳妥的选择。对于GD32和CH32系列1MHz更保险一些。如果PCB走线质量好目标芯片支持高速SWD可以尝试4MHz或者8MHz。另外Keil的Debug设置里有一个“Cache Options”选项可以缓存调试信息来加快Watch窗口的刷新速度。如果调试大型工程时Watch窗口刷新很慢可以把这个选项打开。但要注意缓存可能会导致变量值显示不及时调试时序敏感的代码时建议关掉。6. 关于WCH DAP-LINK的一些个人使用体会我从几年前开始用WCH DAP-LINK最初是因为项目预算有限J-Link太贵ST-Link又只支持STM32。WCH DAP-LINK的性价比确实高十几块钱的东西能支持这么多芯片而且CMSIS-DAP协议是开放的不用担心被某一家工具链绑定。但它也不是没有缺点。首先是速度跟J-Link比起来WCH DAP-LINK的烧录和调试速度确实慢一些尤其是烧录大容量Flash的时候差距比较明显。其次是稳定性在一些电磁环境比较差或者PCB走线不规范的板子上WCH DAP-LINK容易出现连接不稳定的情况需要降低SWD时钟来换取稳定性。不过对于日常开发和小批量生产来说这些问题都在可接受范围内。我的建议是如果你主要做STM32或者国产Cortex-M芯片的开发预算有限WCH DAP-LINK完全够用。如果你需要调试多核芯片或者对调试速度有极高要求那还是得上J-Link。工具这东西没有最好的只有最合适的。最后分享一个我踩过的坑有一次用WCH DAP-LINK调试一块GD32E230的板子怎么都连不上换了三根USB线、两个USB口都不行。后来发现是目标板上的SWD接口旁边有一颗LEDLED的限流电阻跟SWCLK引脚复用了导致SWCLK信号被拉低。把LED拆掉之后一切正常。所以遇到连不上的情况除了查软件配置也要仔细看看硬件原理图有时候问题就出在一个不起眼的小元件上。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进