如何手动为 J-Link 添加新器件支持
适用版本:J-Link v7.80+ · 参考:SEGGER J-Link Device Support Kit
J-Link 内置了对 STM32、NXP 等主流厂商的支持,但对于国产 Cortex-M 芯片(如 Puya PY32、GigaDevice GD32 等),你需要手动告诉 J-Link 三件事:
- 这个芯片是谁(名字、内核、RAM 在哪)
- Flash 怎么烧(起始地址、大小)
- 烧录用哪个算法(FLM 文件)
J-Link 从 v7.80 开始推荐把所有自定义文件放在 %APPDATA%\SEGGER\JLinkDevices\ 下。这样做的好处:不需要管理员权限、J-Link 升级不会覆盖、对电脑上所有 J-Link 安装同时生效。
一、你需要准备的材料
从芯片厂商提供的 CMSIS Device Family Pack (DFP) 中提取:
| 需要的文件 / 信息 | 在 DFP 中的位置 |
|---|---|
.FLM Flash 烧录算法 |
Flash/*.FLM |
| 芯片型号、内核、Flash/RAM 地址和大小 | 根目录的 .pdsc 文件(XML 格式,可用文本编辑器打开) |
如果你还没有 DFP,可以从 Keil Pack Installer 或者芯片官网下载 .pack 文件,用解压软件(如 7-Zip)解压即可得到上述文件。
二、目录结构
在 %APPDATA%\SEGGER\JLinkDevices\ 下为你的芯片厂商建一个文件夹,然后把 FLM 文件和 XML 描述文件放进去。
%APPDATA%\SEGGER\JLinkDevices\ ← 实际路径:C:\Users\<你的用户名>\AppData\Roaming\SEGGER\JLinkDevices\
├── Puya\ ← 厂商名(自定义,建议和 DFP Vendor 一致)
│ ├── PY32F003x8.xml ← 器件描述文件(一个器件一个 XML)
│ ├── PY32F002Ax5.xml
│ └── PY32F003\ ← (可选)子文件夹,方便管理 FLM
│ ├── PY32F0xx_64.FLM
│ └── PY32F0xx_32.FLM
FLM 文件放哪? 可以把 FLM 直接扔在
Puya\文件夹下(和 XML 放一起),也可以建子文件夹分类。只要 XML 里Loader路径写对就行。
三、写一个器件描述 XML
每个器件对应一个 .xml 文件。以下是一个完整的示例(Puya PY32F003x8,Cortex-M0+,64K Flash,8K RAM):
xml
<Database>
<Device>
<ChipInfo
Core="JLINK_CORE_CORTEX_M0"
Name="PY32F003x8"
Vendor="Puya"
WorkRAMAddr="0x20000000"
WorkRAMSize="0x00002000" />
<FlashBankInfo
Name="Internal Flash"
BaseAddr="0x08000000"
AlwaysPresent="1">
<LoaderInfo
Name="Default"
MaxSize="0x00010000"
Loader="PY32F003/PY32F0xx_64.FLM"
LoaderType="FLASH_ALGO_TYPE_OPEN" />
</FlashBankInfo>
</Device>
</Database>
字段说明
<ChipInfo> --- 芯片基本信息
| 属性 | 含义 | 从哪里获取 |
|---|---|---|
Name |
器件名。必须和 DFP 的 Dname 一致 (如 PY32F003x8)。J-Link 的 -device 参数就是这个值 |
DFP 的 .pdsc 文件中的 <device Dname="..."> |
Vendor |
厂商名 | .pdsc 中 <vendor> 元素的内容 |
Core |
J-Link 内核标识:M0/M0+ 用 JLINK_CORE_CORTEX_M0,M3 用 JLINK_CORE_CORTEX_M3,M4 用 JLINK_CORE_CORTEX_M4 |
.pdsc 中 <processor Dcore="Cortex-M0+"> |
WorkRAMAddr |
烧录时 J-Link 可用的 RAM 起始地址(通常是 0x20000000) |
.pdsc 中 <memory id="IRAM1" start="..."> |
WorkRAMSize |
该 RAM 的大小(字节),十六进制 | .pdsc 中 <memory id="IRAM1" size="..."> |
<FlashBankInfo> --- Flash 存储区
| 属性 | 含义 |
|---|---|
Name |
显示名。内部 Flash 通常叫 Internal Flash |
BaseAddr |
Flash 起始地址。Cortex-M 通常是 0x08000000 |
AlwaysPresent |
1 = 始终存在(内部 Flash);0 = 可能不存在(外部 SPI Flash) |
<LoaderInfo> --- 烧录算法
| 属性 | 含义 |
|---|---|
Name |
加载器名称,写 Default 即可 |
MaxSize |
Flash 大小(字节),十六进制。这个值必须和实际芯片一致,否则可能烧坏 |
Loader |
FLM 文件路径。相对于 XML 文件所在目录 |
LoaderType |
固定值 FLASH_ALGO_TYPE_OPEN(同时支持 SEGGER 和 CMSIS 算法) |
如何从 .pdsc 获取信息
用文本编辑器打开 DFP 根目录的 .pdsc 文件。找到对应器件的 <device> 元素:
xml
<device Dname="PY32F003x8">
<processor Dcore="Cortex-M0+" Dclock="48000000"/>
<memory id="IROM1" start="0x08000000" size="0x00010000" startup="1"/>
<memory id="IRAM1" start="0x20000000" size="0x00002000"/>
<algorithm name="Flash/PY32F0xx_64.FLM" start="0x08000000" size="0x00010000" default="1"/>
</device>
.pdsc 中的信息 |
填入 XML 的字段 |
|---|---|
Dname="PY32F003x8" |
ChipInfo.Name |
Dcore="Cortex-M0+" |
ChipInfo.Core="JLINK_CORE_CORTEX_M0" |
IRAM1 start="0x20000000" |
ChipInfo.WorkRAMAddr |
IRAM1 size="0x00002000" |
ChipInfo.WorkRAMSize |
IROM1 start="0x08000000" |
FlashBankInfo.BaseAddr |
IROM1 size="0x00010000" 或 algorithm size="..." |
LoaderInfo.MaxSize |
algorithm name="Flash/..." |
LoaderInfo.Loader(取文件名部分) |
四、完整操作步骤
以 Puya PY32F003x8 为例:
步骤 1:创建目录
打开文件资源管理器,在地址栏输入 %APPDATA%\SEGGER,回车。
新建文件夹 JLinkDevices(如果还没有),然后在其中新建 Puya 文件夹。
步骤 2:复制 FLM 文件
从 DFP 的 Flash\ 目录中找到对应芯片的 .FLM 文件,复制到 Puya\ 文件夹(或 Puya\PY32F003\ 子文件夹)。
对于 PY32F003x8(64K Flash),对应的 FLM 是 PY32F0xx_64.FLM。
步骤 3:创建 XML 文件
在 Puya\ 文件夹中创建 PY32F003x8.xml,粘贴本文第三节的示例 XML。
xml 文件名不重要 ------J-Link 扫描的是文件内容里的
<ChipInfo Name="...">,不是文件名。但建议文件名和Name保持一致,方便管理。
步骤 4:验证
打开JLink Commander,或运行 JLink.exe(在你安装的 J-Link 目录下,或在 PATH 中):
J-Link> ?
输入 device PY32F003x8 然后回车。如果没有报 "Device not found",就说明注册成功了。
也可以直接尝试连接:
JLink.exe -device PY32F003x8 -if SWD -speed 4000 -autoconnect 1
五、常见问题
Q: J-Link 还是找不到我的设备?
- 确认 XML 放在
%APPDATA%\SEGGER\JLinkDevices\<厂商>\下(不是Local而是Roaming) - 确认
Loader路径相对于 XML 文件所在目录是正确的 - 确认 FLM 文件确实在那个路径下
- 重启 J-Link 软件
Q: 多个器件共享同一个 FLM 怎么办?
做法不变------每个器件一个 XML,也可以多个器件放一个XML 里,各自的 Loader 指向同一个 FLM 文件即可。J-Link 不会重复加载。
Q: 可以用 .elf 格式的 Flash 算法吗?
可以。LoaderType 保持 FLASH_ALGO_TYPE_OPEN,Loader 指向 .elf 文件即可。SEGGER Open Flash Loader 同时支持 .FLM(CMSIS 格式)和 .elf(SEGGER 格式)。
Q: 我的芯片有两个 Flash Bank(如内部 Flash + 外部 QSPI Flash)怎么办?
在同一个 <Device> 里写两个 <FlashBankInfo> 即可:
xml
<Device>
<ChipInfo ... />
<FlashBankInfo Name="Internal Flash" BaseAddr="0x08000000" AlwaysPresent="1">
<LoaderInfo Loader="internal.FLM" ... />
</FlashBankInfo>
<FlashBankInfo Name="QSPI Flash" BaseAddr="0x90000000" AlwaysPresent="0">
<LoaderInfo Loader="qspi.FLM" ... />
</FlashBankInfo>
</Device>
Q: 如果我升级了 J-Link,这些文件会丢吗?
不会。%APPDATA%\SEGGER\JLinkDevices\ 是用户级目录,J-Link 安装/升级都不会动它。
六、自动化工具
手动一个一个写 XML 太累?platform-cm 提供了自动脚本:
bash
# 一条命令,自动解析 DFP 并生成所有 XML + 复制 FLM
python scripts/jlink_device.py path/to/your/dfp
# 作为 PlatformIO target
pio run -t jlink_device
脚本会自动解析 .pdsc,提取所有器件的 core、flash、ram、FLM 信息,生成符合 J-Link DSK 规范的 XML,并复制 FLM 文件到正确位置。