使用JLink初步判定STM32芯片方法
对于嵌入式编程而言,当遇到STM32芯片无法正常下载程序时,本文提供了一套使用J-Link命令行工具的快速鉴别方法。通过读取芯片的设备ID、Flash容量、唯一序列号(UID)等关键信息,并与正品设计进行对比,可以有效甄别出可能混入的仿冒或Remark(重新打标)芯片,从而避免在硬件选型或调试中浪费大量时间。该方法简单易行,是进行芯片真伪初步筛查的实用技能。
前言
在STM32开发中,你可能会遇到一种情况:同一批采购的芯片,型号和电路完全相同,但有的能顺利下载程序,有的却始终失败。这很可能是因为其中混入了仿冒或Remark(重新打标)的芯片。这些芯片在关键细节上与正品存在差异,导致下载失败。本文将介绍一种使用J-Link命令行工具进行快速初步判别的方法,虽然不能保证100%准确,但能有效筛查绝大多数异常芯片,为你的项目质量把关。
使用JLink命令行
首先我们需要打开JLink的命令行,这里推荐几种方法:
- 如果安装了JLink驱动,可以在桌面上直接找到JLink.exe程序,双击打开
- 如果安装了Keil5:
- 打开Keil5安装目录,按照这个目录寻找:Keil\ARM\Segger\JLink.exe,双击打开
- 打开Keil5软件,点击魔法棒(Options for Target),点击右上角Debug,右上角选择J-LINK,点击Settings,点击右下角JLink Cmd
初步判定STM32芯片
大致流程
读 DBGMCU_IDCODE(设备 ID / 修订版)
读地址:0xE0042000(F1/F4 都是这个调试寄存器地址)
作用:拿到 DEV_ID(芯片型号族) + REV_ID(修订版)
命令:mem32 0xE0042000 1
解释:这个寄存器在 ST 的参考手册里定义(F1 在 RM0008 里就能查到)。
注意:很多兼容/仿品会刻意做成相同 DEV_ID,所以它是“入门筛查”,不是铁证。
读 电子签名区(Electronic signature)
这是最常用、最好用的一组“像不像 ST”的证据:
Flash 容量寄存器(Flash size register)
F1:0x1FFFF7E0(16-bit)
F4:0x1FFF7A22(16-bit)
唯一 ID(Unique device ID / UID)
F1:0x1FFFF7E8 起(96-bit = 3 个 32-bit)
F4:0x1FFF7A10 起(96-bit = 3 个 32-bit)
如果读出来全是 0xFFFFFFFF 或者读不到,往往说明:
选错了系列地址(比如把 F4 当 F1 去读),或目标被读保护/映射限制(少见),或芯片实现不兼容(可疑点)。
读 System Memory(Bootloader ROM)向量表看“有没有 ST 的系统 Bootloader”
F1 System memory:0x1FFFF000 起
F4 System memory:0x1FFF0000 起(很多 F4 都是这个区间,RM0401 给出 system memory 映射范围)
读前 64 字节通常能看到一张“像样的向量表”(首字是栈顶指针,第二个字是 Reset_Handler 地址,且地址落在 system memory 范围内)。这对“像 ST”很有帮助。
读 Option Bytes 看布局/典型值是否像 ST
F1 Option bytes:0x1FFFF800 起
F4 Option bytes(在 system memory 空间的 option bytes 区):0x1FFFC000 起(见 ST 编程手册 PM0081)
JLink命令行基本知识
连接与基础设置命令
J-Link>device STM32F407VG ; 或 STM32F103C8 等
J-Link>si SWD ; 选择 SWD 接口
J-Link>speed 4000 ; SWD 时钟 4MHz(不稳定就降到 1000/400)
J-Link>connect ; 连接目标
J-Link>r ; reset
J-Link>h ; halt(停核,读内存更稳)
device:告诉 J-Link 用哪个芯片的 flash 算法/内存布局(不影响 mem32 读寄存器,但影响擦写/下载)。
si / speed / connect:连接步骤。
r / h:复位并停住内核,避免程序跑飞导致调试口不稳定。
注意:使用时将J-Link>这部分去除
读内存命令(mem8 / mem16 / mem32)的SEGGER 语法是:
Mem8 [<Zone>:]<Addr> <NumItems>
Mem16 [<Zone>:]<Addr> <NumItems>
Mem32 [<Zone>:]<Addr> <NumItems>
判断F4的完整命令
说明:Flash/UID 地址来自 ST 参考手册的 Electronic signature 章节:UID=0x1FFF7A10,FlashSize=0x1FFF7A22
device STM32F407VG
si SWD
speed 4000
connect
r
h
; 1) 设备ID/修订版(通用)
mem32 0xE0042000 1
; 2) Flash容量(F4:0x1FFF7A22,16-bit)
mem16 0x1FFF7A22 1
; 3) UID(F4:0x1FFF7A10 起,3个32-bit)
mem32 0x1FFF7A10 3
; 4) System memory 向量表(F4 system memory 0x1FFF0000)
mem8 0x1FFF0000 64
; 5) Option bytes(常见在 0x1FFFC000)
mem32 0x1FFFC000 4
这些地址怎么来的?
0x1FFF7A10 / 0x1FFF7A22:ST 参考手册 Electronic signature / Flash size register 定义给出的。
0x1FFF0000 system memory 区间:RM0401 的 memory mapping / flash organization 表里给出 system memory 映射范围。
0x1FFFC000 option bytes:ST 编程手册 PM0081 明确写了 Option bytes 地址范围。
判断F1的完整命令
说明:F1 的电子签名/系统区地址来自 RM0008:
Flash size register:0x1FFFF7E0
UID:0x1FFFF7E8
System memory:0x1FFFF000
Option bytes:0x1FFFF800
device STM32F103C8
si SWD
speed 4000
connect
r
h
; 1) 设备ID/修订版(通用)
mem32 0xE0042000 1
; 2) Flash容量(F1:0x1FFFF7E0,16-bit)
mem16 0x1FFFF7E0 1
; 3) UID(F1:0x1FFFF7E8 起,3个32-bit)
mem32 0x1FFFF7E8 3
; 4) System memory 向量表(F1:0x1FFFF000)
mem8 0x1FFFF000 64
; 5) Option bytes(F1:0x1FFFF800)
mem8 0x1FFFF800 64
如何判断
先读 Flash size + UID(用正确系列地址)
能读到合理值(不是全 FF/全 00),且 Flash size 符合买的型号标称 → 很像 ST/兼容实现正常
读 system memory 向量表
前两个 word 像样(SP 在 0x2000xxxx,Reset_Handler 在 system memory 范围内)→ 极像 ST 带 ROM bootloader
读 option bytes
看到 AA/55 互补、写保护/读保护字段像 ST → 再加分
DBGMCU_IDCODE
DEV_ID 若完全不对 → 基本就不是选的那颗系列(或强不兼容实现)
DEV_ID 对也不代表一定原厂(高仿能伪造)
当然还有更简单的方法,就是将之前的命令得到的值全部扔给AI,让他帮你判断(非常推荐)
解析
用 J-Link 判断的通用思路
用 SWD 连上以后,要读三类“很难伪装”的信息:
DBGMCU_IDCODE(设备ID + 修订版)
- 地址固定:0xE0042000
- 读出来的 DEV_ID(低 12bit)能判断“属于哪个系列/哪类芯片”,REV_ID(高 16bit)能看硅版本。
- 这是调试模块寄存器,很多“贴标/移植内核”的芯片这里会暴露差异。
来源:F1 参考手册 RM0008 明确给出 DBGMCU_IDCODE Address: 0xE0042000,并定义 REV_ID/DEV_ID 位域。
Device electronic signature(电子签名区):Flash 容量寄存器 + UID
- Flash size register:读出工厂烧录的“官方声明容量(KB)”
- Unique ID (96-bit UID):读出 96bit 唯一ID
这些地址随系列不同(F1 和 F4 不一样),都在各自参考手册的 Device electronic signature 章节里给出: - F1:RM0008:Flash size 基址 0x1FFF F7E0,UID 基址 0x1FFF F7E8
- F4:常用基址:UID 0x1FFF7A10、Flash size 0x1FFF7A22(很多资料/代码也按这个)
System memory(系统存储器/Bootloader 区)+ Option bytes(选项字节)
- system memory 用来放 ST 出厂 Bootloader,读它的“向量表开头”通常不会全是 FF。
- option bytes 能看 RDP 读保护 等状态(如果开了读保护,读某些区域可能全 FF/报错)。
来源(F1):RM0008 内存映射表给出System memory 0x1FFF F000 - 0x1FFF F7FF、Option Bytes 0x1FFF F800 - 0x1FFF F80F
来源(F4):PM0081 明确给出 F4 选项字节在 0x1FFF C000
每条 J-Link 命令:是在干什么?
J-Link>device STM32F407VG
- 告诉 J-Link 目标芯片型号。
- 作用:让 J-Link 选择正确的 Flash 编程算法、内存布局、复位方式 等。
- 如果这里选错型号:loadfile/erase 之类可能失败,或者写到不对的地方。
J-Link>si SWD
- 选择调试接口:SWD(两线)而不是 JTAG(四/五线)。
J-Link>speed 4000
- 设置 SWD 时钟(kHz)。4000 = 4MHz。
- 线长/板子差时可降到 1000/500 提升稳定性。
J-Link>connect
- 连接目标并做一次目标探测:读取 DPIDR、扫描 AP、读 CPUID、识别内核等。
J-Link>r
J-Link>h
- reset(复位)。通常等价于让 MCU 复位一次(具体方式看 J-Link 实现/芯片支持)。
- halt(停核)。让 CPU 停在当前状态,避免读写内存时程序在跑导致数据变化。
mem8 / mem16 / mem32:为什么要分 8/16/32?
J-Link>mem32 <addr> <count>
J-Link>mem16 <addr> <count>
J-Link>mem8 <addr> <count>
- 这是 按 32位/16位/8位宽度 读内存/寄存器。
- 之所以要区分,是因为很多寄存器在手册里写了“只支持 32bit 访问”或“该字段是 16bit”。
- 例如 F1 的 DBGMCU_IDCODE 明确写 Only 32-bits access supported,所以用 mem32 0xE0042000 1 最标准。
- F1 的 Flash size register 位域是 15:0,用 mem16 读更直观
这些地址的由来
通用:0xE0042000 为什么是设备ID?
- 这是 DBGMCU(调试支持模块)里的 IDCODE 寄存器,用来给调试器识别芯片型号/修订版。
- F1 的 RM0008 直接写了:
- DBGMCU_IDCODE Address: 0xE0042000
- 高 16 位 REV_ID,低 12 位 DEV_ID(其余保留)
怎么用它判断? - 读出一个 32 位值,比如读到的 0x101F6413:
- DEV_ID = value & 0xFFF = 0x413(这类值经常对应 F4 系列的某些器件ID;如果选的是 F407,但 DEV_ID 明显不对,就高度可疑)
- REV_ID = value >> 16 = 0x101F(硅版本)
注意:DEV_ID 只能说明“芯片属于哪一类 die/系列”,不能 100% 证明“原厂/国产”。但它是第一道门槛:贴标很容易在这里露馅。
STM32F1(以 STM32F103C8 为例):这些地址在 RM0008 哪里?
Flash 容量寄存器:0x1FFF F7E0
- RM0008 “Device electronic signature” → “Flash size register” 写明:
- Base address: 0x1FFF F7E0
- F_SIZE 表示 Flash 容量(单位 KB)
J-Link>mem16 0x1FFFF7E0 1
读出来若是 0x0040 就是 64KB(典型 F103C8 标称)。
如果读出 0x0080 就是 128KB(常见“C8 实际是 CB/128KB”的情况)。
UID:0x1FFF F7E8
- 同一章节写明:UID 基址 0x1FFF F7E8,96bit 读三次 32bit 即可。
J-Link>mem32 0x1FFFF7E8
System memory:0x1FFF F000(Bootloader 所在)
- RM0008 内存映射表写了 System memory 0x1FFF F000 - 0x1FFF F7FF
J-Link>mem8 0x1FFFF000 64
看向量表开头是否“像样”(一般不是全 FF)。
Option bytes:0x1FFF F800
- 同一张表给了 Option Bytes 0x1FFF F800 - 0x1FFF F80F。
J-Link>mem8 0x1FFFF800 64
这里能间接判断是否开了读保护、写保护等(但具体位意义要看 Flash programming manual/该系列说明)。
STM32F4(以 STM32F407 为例):这些地址怎么来的?
Flash 容量寄存器:0x1FFF7A22(16-bit)
UID:0x1FFF7A10 起,读 3 个 32-bit
这两组地址属于 F4 系列“电子签名区”的常用固定映射(很多库/资料/例程都会按这个读),例如这里给出了读取方式:
- flash_read(0x1FFF7A10 + 0x00/+0x04/+0x08) 读 UID 三个 word
- 读取 Flash size 的地址是 0x1FFF7A22
J-Link>mem16 0x1FFF7A22 1
J-Link>mem32 0x1FFF7A10 3
Option bytes:0x1FFF C000(F4 常见)
- F4 的 Flash programming manual PM0081 的表格直接写:option bytes word 地址 0x1FFF C000
J-Link>mem32 0x1FFFC000 4
System memory:用的 0x1FFF0000
- 这是 F4 系列常用的 system memory(bootloader)映射起点之一(不同系列/子系列会略有差异),做法上就是:
- 去该系列 Reference Manual 的 memory map 找 “System memory” 的起始地址
- 然后 mem8 读前 64 字节看向量表
完整命令
F4(以 F407 为例)
J-Link>device STM32F407VG ; 选芯片型号(影响 flash 算法/内存布局)
J-Link>si SWD ; 选 SWD
J-Link>speed 4000 ; SWD 时钟 4MHz
J-Link>connect ; 连接并探测
J-Link>r ; 复位
J-Link>h ; 停核
J-Link>mem32 0xE0042000 1 ; DBGMCU_IDCODE:设备ID/修订版(通用,强识别点)
J-Link>mem16 0x1FFF7A22 1 ; F4 Flash size(KB)
J-Link>mem32 0x1FFF7A10 3 ; F4 UID(96-bit)
J-Link>mem8 0x1FFF0000 64 ; F4 System memory 向量表(bootloader 区开头)
J-Link>mem32 0x1FFFC000 4 ; F4 Option bytes(读保护/写保护等)
注意:J-Link命令行中输入时,需要去掉每行开头的 J-Link> 提示符
F1(以 F103C8 为例)
J-Link>device STM32F103C8
J-Link>si SWD
J-Link>speed 4000
J-Link>connect
J-Link>r
J-Link>h
J-Link>mem32 0xE0042000 1 ; DBGMCU_IDCODE(通用):contentReference[oaicite:14]{index=14}
J-Link>mem16 0x1FFFF7E0 1 ; F1 Flash size(基址 0x1FFF F7E0):contentReference[oaicite:15]{index=15}
J-Link>mem32 0x1FFFF7E8 3 ; F1 UID(基址 0x1FFF F7E8):contentReference[oaicite:16]{index=16}
J-Link>mem8 0x1FFFF000 64 ; F1 System memory(0x1FFF F000 起):contentReference[oaicite:17]{index=17}
J-Link>mem8 0x1FFFF800 64 ; F1 Option bytes(0x1FFF F800 起):contentReference[oaicite:18]{index=18}
注意:J-Link命令行中输入时,需要去掉每行开头的 J-Link> 提示符
判定真伪/贴标操作
先看 DBGMCU_IDCODE 的 DEV_ID 是否合理
- F1(中密度常见)DEV_ID=0x410 在 RM0008 就明确列出来了。
- 如果选的是 F103C8,但读出来 DEV_ID 完全不是 0x410/0x412/0x414 这类范围,基本就不是对应 die。
再看 Flash size register 是否和丝印/选择的型号一致 - F4 读到 0x0200=512KB,如果丝印是 1MB 档,就很可疑(贴标/选型错误/翻新混料)。
- F1 很多“C8 实际是 128KB”会表现为 0x0080,这更像“同系列不同容量”而不一定是国产仿品。
如果读出来一片 FFFFFFFF - 优先怀疑:地址用错系列
- 其次才怀疑:RDP/安全保护、连线不稳、掉电等。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)