ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Keil v5无法识别JLink?驱动替换与自定义设备添加实战指南

Keil v5无法识别JLink?驱动替换与自定义设备添加实战指南 用了一段时间Keil v5之后很多人都会遇到同一个尴尬场景手头明明有JLink目标板供电、接线也都正常但一点下载Keil要么报“No J-Link found”要么直接甩一句“The connected J-Link is defective”甚至干脆在Device列表里找不到自己那颗芯片。这个坑我在自己装的JLink和几款非主流MCU上反复踩过后来把整个链路梳理了一遍发现核心问题就两个一是Keil自带的Segger组件和自行安装的JLink驱动版本不匹配二是Keil v5的设备支持机制从“内置数据库”变成了“Pack包”管理官方没给你收录的芯片就得自己想办法加。这篇经验帖主要解决这两件事适合手里有便捷JLink、正在折腾STM32/GD32/自制Cortex-M板子、或者被Pack版本问题搞到崩溃的开发者参考。1. 项目背景与核心问题拆解1.1 Keil v5为什么不认自行安装的JLink先说结论大多数情况下不是你的JLink坏了而是Keil v5使用的JLink相关文件和你实际安装的JLink驱动不是同一个版本两边“协商”失败Keil就不认了。Keil MDK v5安装之后会在安装目录下的ARM\SEGGER文件夹里放一套精简版的Segger工具包括JLinkARM.dll、JLink.exe、JLinkGDBServer等。这套文件是Keil发布时固定携带的OEM版本版本号跟着Keil走比如有些老版Keil 5.24内置的是JLink V6.xx的DLL而你自行安装的Segger JLink驱动已经更新到V7.xx甚至V8.xx。真正连接时Keil通过内置DLL去访问JLink硬件然后JLink硬件里的固件又会和DLL做一次握手校验。只要DLL版本、固件版本、硬件版本三者之间有代差握手就会失败。表现就是Keil里能看到“J-Link”字样但一点连接就报错或者说设备损坏。这里还有个容易被忽略的点Keil是32位应用程序在64位Windows系统上跑的时候它会加载32位版本的JLink驱动。而Segger官网新驱动安装后默认路径下通常会有x86和x64两个子目录。如果你不小心把64位版本的DLL复制到哪里去了Keil根本认不出来照样报错。所以后面做DLL替换时一定要记得取x86目录下的文件。1.2 “添加自定义设备”到底在解决什么问题Keil v5和Keil v4一个很大的差别就是设备支持方式变了。Keil v4是在软件里内置一个设备数据库选中芯片之后编译和烧录参数都写死在工程里。Keil v5改成了“CMSIS-Pack”机制所有芯片的描述、启动文件、Flash算法、SVD调试描述文件都以pack的形式存在。你在Pack Installer里看到的ST、NXP、GD32等厂商支持本质上是下载了对应的.pack包。这就带来一个问题如果芯片厂商没有跟进Pack机制或者你的芯片特别小众或者干脆是你自己定制的SoC那么在Pack Installer的Device列表里永远找不到它。但单片机还是要用的程序还是要烧的。所以“添加自定义设备”本质上是在做三件事让Keil在新建工程时能选到这颗芯片编译链接参数准确。给Keil提供Flash算法文件FLM否则下载时Keil不知道怎么把程序写进Flash。提供SVD调试描述文件让调试器能解析外设寄存器。很多人以为自定义设备只是改个名字其实不改算法文件的话就算你新建工程选到了名字下载那一步照样会报“Cannot Load Flash Programming Algorithm”。这个坑我在后面专门展开讲。2. 识别与驱动准备先让自装JLink被电脑认出来2.1 驱动安装与环境确认拿到一个自装JLink第一步不是急着打开Keil而是先确认JLink本身能不能被电脑识别。把JLink插上USB口打开设备管理器看“通用串行总线控制器”或者“通用串行总线设备”下面有没有出现“J-Link”开头的设备。如果出现一个带黄色感叹号的未知设备说明驱动没装好。这时候去Segger官网下载对应版本的JLink驱动安装包装上即可。安装完之后设备管理器里应该会显示类似“J-Link”这样的条目没有感叹号。然后打开JLink Commander。它在开始菜单里的名字可能是“J-Link Commander V6.xx”或类似叫法也可以直接到Segger安装目录下找JLink.exe。打开后会提示输入目标设备型号随便填一个你手里的芯片型号如果连接成功会打印出目标板的ID、内核类型、序列号等信息。这一步如果都能顺利通过那说明你的JLink硬件、USB线、目标板接线都是好的问题才能锁定到Keil这边。这里有一个经验USB线别用那种只能充电的线。JLink对USB数据线要求不算苛刻但有些廉价线材要么接触不良要么只有电源线没有数据线插上去电脑没反应。我遇到过一次换了根粗一点的线就好折腾了半小时。2.2 驱动版本怎么选才不踩坑自行安装的JLink尤其是非官方渠道的兼容设备对驱动版本很敏感。新驱动往往对老硬件支持不友好会出现“The connected J-Link is defective”这种提示。我的经验是分类型对待老款V8/V9兼容设备尽量装6.8x到7.0x之间的驱动太新容易报设备故障。新款V10/V11设备装7.x以上新驱动比较稳妥老驱动反而可能出现无法识别固件的问题。如果你不确定自己手里的JLink硬件版本看JLink Commander启动时的版本号和固件提示它会告诉你能不能升级。这里顺便提一下Segger新驱动会提示“Update Firmware”。对于兼容设备升级固件有一定风险。不是不能升而是升级前务必确认你手里设备的固件版本和驱动版本是配套的否则升坏了反而更麻烦。所以我在后面所有操作里都建议能不升固件就不升优先用DLL替换和降级驱动来解决Keil识别问题别动固件。2.3 SWD和JTAG的接线规范JLink和目标板之间最常用的是SWD模式最少只要四根线VCC参考电压、SWDIO、SWCLK、GND。很多人图省事只接三根不接GND然后各种莫名奇怪的报错就来了。JLink的VTref就是通过VCC这根线检测目标板供电的如果没接或者电压不对Keil里会一直提示“Target power”相关问题。JLink标准20Pin接口里常用的几个引脚是这样引脚名称说明1VTref目标板参考电压接3.3V或5V用于电平匹配检测3SWDIO / TMSSWD数据线JTAG模式为TMS5SWCLK / TCKSWD时钟线JTAG模式为TCK7SWO / TDOSWO跟踪输出JTAG模式为TDO调试时可选用9GND公共地必须接13TDIJTAG模式数据输入可以不管SWD实际使用中接1、3、5、9这四根线基本就能烧录。如果目标板没有标准20Pin接口就从JLink的杜邦线单独引出来把颜色对应好。我自己调试自制板子时习惯用四根杜邦线省事、不容易接错。如果你发现能识别但下载不稳定先检查一下SWCLK频率是不是太高可以在Keil的Debug设置里把时钟降到1MHz左右试试稳定了再往上调。3. Keil v5识别自装JLinkDLL替换与版本匹配3.1 Keil v5内置的JLinkARM.dll究竟是什么Keil v5在ARM\SEGGER目录下放了一套自己的JLink动态库Keil识别JLink时调用的就是这些DLL。这套东西和Segger官网驱动是两回事官网驱动是给整个系统用的谁都能调用Keil内置DLL是Keil私有的编译时绑定在Keil目录里。也就是说你哪怕装好了官网驱动Keil还是会优先用自己目录下的那套DLL去连JLink。所以当Keil提示“No J-Link found”或者“defective”时一种非常有效的方法就是把Keil内置的DLL替换成你自己安装的JLink驱动里的DLL。具体操作分四步先记录Keil安装路径。右键Keil快捷方式打开文件所在位置通常就是C:\Keil_v5。找到C:\Keil_v5\ARM\SEGGER文件夹把里面的JLinkARM.dll和JLink.dll有的版本只有其中一个复制到桌面备份。到Segger官网驱动安装目录下找到x86子目录里的同名文件。把JLinkARM.dll复制到Keil的ARM\SEGGER目录如果驱动目录里还有JLink.dll一并复制过去。打开Keil重新进入Options for Target - Debug选择J-LINK调试器点Settings看能不能正常读取到序列号和目标板ID。这里有几个细节。第一Keil是32位程序必须用x86目录里的DLLx64目录里的文件复制过去基本无效。第二替换前一定要备份因为你不知道这次替换是否一定成功万一版本不匹配至少能退回去。第三不同Keil版本对DLL名称的要求不一样老版本主要认JLinkARM.dll新版本已经转向JLink.dll保险起见两个文件都替换掉。3.2 替换之后Keil里的配置要点替换DLL只是第一步把Keil的调试配置也理顺了才算真正能用。打开Options for Target - Debug右边选中“J-LINK / J-TRACE Cortex”点紧挨着的Settings按钮会弹出一个窗口。这里重点看两个标签页Debug标签页里如果设置正确能看到你的JLink序列号、端口模式、目标设备内核。如果这里显示“Cannot find J-Link”或固件版本提示不匹配回去检查DLL是不是放对了。在“Port”下拉框里一般选SW或者JTAG。目标板用的是SWD就选SW否则怎么都连不上。Flash Download标签页更关键这里对应烧录算法。很多人在网上找的工程模板打开之后编译没问题一烧录就报“Flash Download failed”原因多半是这个页面里没有加对Flash算法。点“Add”在弹出的列表里选中你目标芯片对应的Flash算法比如STM32F103ZE对应的是“STM32F10x High-density Flash 512K”这样的条目。加好后编程算法、起始地址、大小都会自动带出来。如果你的芯片是自定义设备这个列表里可能找不到对应项那就需要手动添加FLM文件这个放到第4章细说。还有一个很多人不注意的选项“Reset and Run”。勾选它之后烧录完成会自动复位运行程序不勾选下载完程序停留在停住状态。调试时我一般会勾上少点一次复位。有时候目标板带有外部看门狗烧录后立刻复位反而会被看门狗咬住不断重启这种场景下就不勾配合手动复位更可靠。3.3 RDDI-DAP报错的个人处理经验替换DLL解决了版本问题之后下一个高频报错是“RDDI-DAP Error”。这个报错第一次出现时我一度以为是JLink坏了后来排查下来发现它更像是目标板侧的连接问题而不是DLL问题。常见原因按概率排目标板没有供电或者供电电压不在JLink的VTref检测范围内。先量一下目标板的3.3V引脚有没有电。GND没共地。JLink和目标板必须接公共地否则电压参考点是悬空的。SWCLK频率太高。在Settings的Debug页面里把时钟降到1MHz以下连接稳定之后再提高。复位电路问题。有些板子拉了很长的复位线或者复位引脚被其他器件拉低JLink没法正确复位内核也会报RDDI-DAP。我的排查顺序是先看供电再量GND通断再降SWCLK频率最后查看复位引脚。四个步骤下来大部分RDDI-DAP都能解决。真要是还不行就把JLink拔掉重新插一次有时候只是USB识别卡住了。4. 添加自定义设备从pack到FLM完成烧录闭环4.1 用Pack Installer导入第三方芯片支持包如果你的芯片虽然非主流但厂家提供了Keil支持包那是最省事的路径。现在很多国产ARM芯片厂商官网都会放CMSIS-Pack格式的支持包下载下来是一个.pack文件比如GigaDevice.GD32F10x_DFP.2.0.0.pack这种命名。打开Keil的Pack Installer在菜单栏选File - Import找到你下载的.pack文件双击导入。等待几秒安装完成后左边Device列表里就会出现对应厂商和芯片型号。之后新建工程或者打开老工程都能直接选到这颗芯片编译、烧录参数也会自动匹配。这里有一个版本兼容性的坑Pack包的格式版本和Keil主程序版本有关。新版本的pack通常要求Keil 5.30以上老版本Keil导入新pack时可能会提示“Pack requires newer MDK version”之类的错误。解决办法要么升级Keil主程序要么去找和当前Keil版本匹配的旧版pack。Keil 5.17这种特别老的主程序能支持的pack版本就更有限了所以我个人建议还在用5.1x的同学如果经常要接第三方芯片至少升到5.27以上兼容性会好很多。4.2 完全自定义设备时PDSC文件怎么改如果芯片厂商没有提供Pack或者芯片是你自己做的那就要手工建一个设备定义。这个听起来很复杂但实际拆开来看核心就是三板斧一个PDSC描述文件、一个FLM烧录算法、一个SVD调试描述文件。最简单的方式是找一份相近设备的pack把PDSC文件解压出来后用文本编辑器打开。PDSC文件本质是一个XML结构大概长这样package schemaVersion1.4 vendorMyVendor nameMyCustom_DFP version1.0.0 devices family DfamilyMyCM0 DcoreCortex-M0 DvendorMyVendor:2 device DnameMyCM0F processor DcoreCortex-M0 PnameCM0 / memory idIROM1 start0x08000000 size0x00010000 default1 / memory idIRAM1 start0x20000000 size0x00002000 default1 / algorithm nameMyFlash32K.FLM start0x08000000 size0x00010000 / /device /family /devices /package关键信息就几个芯片内核、Flash起始地址和大小、RAM起始地址和大小、以及烧录算法文件的引用。改完之后重新打包成.pack再用Pack Installer导入设备列表里就能看到了。实际做的时候我建议先在Pack Installer里把某个相近厂商的官方包导入然后找到它的PDSC文件做参考把厂商名、设备名、Flash大小、算法文件这些字段改成你自己芯片的。第一次不追求完美只要Keil能识别、能编译、能烧录就算成功。SVD文件如果没有也不影响烧录只是调试时看不到外设寄存器的具体名字暂时可以先不折腾。如果连pack导入这条路都嫌麻烦还有一个临时的土办法新建工程时不选具体芯片选一个相近的通用设备比如“Generic Cortex-M3”然后编译后在Options for Target - Utilities里手动勾选“Use Flash Programming Algorithm”从算法列表里选一颗相近的FLM。这个方法不需要做pack但工程参数和实际设备可能不完全匹配只适合应急验证程序逻辑不建议作为正式开发流程。4.3 必须搞懂的FLM烧录算法FLM文件是Keil用来写Flash的“驱动插件”。Keil下载程序时并不是直接往内存地址写而是调用FLM里的擦除、编程、校验函数来操作Flash。所以没有对应的FLM哪怕你在Device列表里选到了芯片下载时也会报Cannot Load Flash Programming Algorithm。FLM文件放在Keil安装目录的ARM\Flash下。打开这个目录你会看到一大堆厂商前缀的.FLM文件。你的自定义设备如果没有自己的FLM可以试着从里面找一颗“内核相同、Flash规格接近”的FLM来替代。比如你的自制MCU是Cortex-M0内核、Flash 32KB那找一个同样Cortex-M0、32KB的FLM大概率能用。但注意FLM里包含的是具体Flash控制器时序不同厂商的Flash控制器差异可能很大替代失败也正常。只要下载时提示“Erase Done. Programming Done. Verify OK.”就说明算法是对的。更好的方案是让厂家提供官方FLM或者基于CMSIS-Pack的Flash算法模板自己写一个。这个工程量不大但需要目标芯片Flash控制器的寄存器手册新手可以先从替代方案入手跑通流程再考虑定制。4.4 把外部Flash算法也加进Keil很多时候内部Flash不够用需要把字库、配置文件或者部分代码放进外部Nor Flash。这种情况下只有内部Flash算法还不够得把外部Flash的算法也加进来。操作分两步。第一步找到对应Nor Flash芯片的FLM文件。很多MCU厂商在自家的Pack包里会附带外部Flash烧录算法比如STM32系列就有对应的SPI Nor Flash算法。把它复制到Keil的ARM\Flash目录。第二步在Options for Target - Debug - Settings - Flash Download页面里点Add从算法列表里选外部Flash算法并填写起始地址和大小。填写的起始地址要和你的外部Flash映射地址一致这个地址在芯片手册里查得到。如果实在找不到现成的外部Flash FLM比如Nor Flash型号太老旧那可以绕开Keil直接用JLink命令行工具来烧。在命令行里执行JLink.exe进入交互模式然后依次输入设备型号、连接方式、加载地址和文件loadbin C:\app.bin 0x90000000 savebin C:\backup.bin 0x90000000 0x10000loadbin把二进制文件加载到外部Flash地址savebin可以把Flash内容读回来做校验。这个方式虽然不在Keil的下载流程里功能却一点不少特别适合验证外部Flash映射地址是否正确。5. 常见问题与排查技巧实录5.1 常见报错排查速查表这一节把我在实际项目中遇到过的报错整理成表格方便大家对照排查报错信息可能原因解决办法No J-Link foundUSB线没接好、驱动没装、DLL替换错误检查设备管理器、换USB线、确认用的是x86目录DLLThe connected J-Link is defectiveDLL版本与固件不匹配、兼容设备固件故障替换Keil内置DLL、换老版本驱动、不要乱升固件RDDI-DAP Error目标板供电异常、GND没共地、SWCLK频率过高先量VTref再共地再降SWD频率Cannot Load Flash Programming Algorithm缺少FLM算法或算法与芯片不符加Flash算法或用同内核FLM替代Flash Download failed - Cortex-M4内核选错、Flash算法起始地址不对核对Device列表里的内核、检查Flash Download算法起始地址SWD/JTAG Communication Failure目标芯片进入了低功耗模式或SWD引脚被复用按住复位键连接或通过Boot引脚启动再擦除这些报错看起来很吓人但大多数情况下不是硬件坏了而是配置链路里某一环没对上。按表格顺序检查一遍能解决八成问题。5.2 调试中的三个细节坑第一个是看门狗没关。程序里如果开了独立看门狗IWDG进入调试后单步执行时间稍长看门狗超时就会不断复位内核体现为“总是跳到0x0000或者复位向量”。解决方式是在Debug设置里配置Initialization File也就是.ini脚本在连接后把看门狗关掉。脚本内容大致就是写寄存器键值和关看门狗寄存器具体地址要看芯片手册但思路是通用的。第二个是低功耗模式导致SWD连不上。主程序运行后芯片进入Sleep或Stop模式内核时钟停了JLink抓不到目标芯片。这时候最粗暴有效的方法是按住目标板的复位键不放点Keil的下载在下载开始瞬间松开复位键。原理是芯片上电复位阶段内核还在运行JLink抓住这个窗口建立连接。如果手法不熟练多试几次就找到感觉了。第三个是DLL替换后Keil识别正常但一更新Segger驱动又废了。我后来养成了一个习惯每次替换DLL之前把Keil的ARM\SEGGER整个目录压缩备份。因为新驱动安装时往往会重新覆盖或增加一些文件搞得我之前调好的组合又乱了。备份好之后随时能一键还原。5.3 为什么这个经验不一定通用题目里我说“经验自留不一定通用”这是真心话。因为Keil主程序版本、Segger驱动版本、JLink固件版本、目标芯片类型这四个变量排列组合起来可能性太多了。我在A环境里调好的DLL组合放到B环境里可能就不好使。所以这篇文章真正有价值的部分不是告诉你“某个版本一定行”而是给你一套排查思路先确认硬件OK再锁定DLL和固件版本最后检查Flash算法和配置项。按这个顺序走基本都能找到问题点。另外提醒一点替换任何文件前都做好备份。不要小看这个习惯我见过有人把JLinkARM.dll换成新版本后Keil连老工程都打不开了最后只能重装整个Keil。有备份的话十秒钟就能还原回来。6. 写在最后的一点个人习惯这些年在多个项目里折腾JLink和自定义设备我最大的体会是工具链没有“一劳永逸”的配置只有“当前项目可用”的配置。每次拿到一块新板子或者新芯片我都会先花五分钟把三样东西记下来Keil主程序版本、Segger驱动版本、目标芯片的Flash算法来源。有了这组记录下次再遇到报错对照起来特快。如果你现在正好被Keil的JLink识别问题卡住可以先从替换ARM\SEGGER目录下的DLL开始试再按表格排查接线和算法。要是这篇文章能帮你少走一次弯路那这趟记录就值了。
返回列表