新版本JLINK 手动添加自定义芯片支持国产32 单片机

适用版本:J-Link v7.80+ · 参考:SEGGER J-Link Device Support Kit

J-Link 内置了对 STM32、NXP 等主流厂商的支持,但对于国产 Cortex-M 芯片(如 Puya PY32、GigaDevice GD32 等),你需要手动告诉 J-Link 三件事:

  1. 这个芯片是谁(名字、内核、RAM 在哪)
  2. Flash 怎么烧(起始地址、大小)
  3. 烧录用哪个算法(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

五、常见问题

  1. 确认 XML 放在 %APPDATA%\SEGGER\JLinkDevices\<厂商>\ 下(不是 Local 而是 Roaming
  2. 确认 Loader 路径相对于 XML 文件所在目录是正确的
  3. 确认 FLM 文件确实在那个路径下
  4. 重启 J-Link 软件

Q: 多个器件共享同一个 FLM 怎么办?

做法不变------每个器件一个 XML,也可以多个器件放一个XML 里,各自的 Loader 指向同一个 FLM 文件即可。J-Link 不会重复加载。

Q: 可以用 .elf 格式的 Flash 算法吗?

可以。LoaderType 保持 FLASH_ALGO_TYPE_OPENLoader 指向 .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 文件到正确位置。