只读分享解决方案文档调试&解决方案📅 2026-10-14🔖 Rev 1.0⏳ 还有3日到期
🔧解决方案&应用市场分析 -> 调试&解决方案 -> 存储_量产问题排查 -> SPI_NOR_烧录找不到型号_解决方案

SPI_NOR_烧录找不到型号_解决方案

同系列 · 调试&解决方案
扫码打开本页
微信扫码

SPI NOR Flash 烧录「找不到型号」解决方案

从识别机制到自建通用烧录器的六条路径 · 编制日 2026-08-29 | 编制日期 2026-10-14 | 版本号 Rev 1.0

5 分钟
最快恢复出片
路径一:参数比对后顶替型号
0x5A
SFDP 读参数命令
支持即免型号库,容量/擦除自报
8 项
判定兼容的必查参数
容量、擦除、页、地址宽度等
6 条
解决路径
从顶替型号到自建烧录器
5 V
CH341A 的电平陷阱
不改造可能打穿 3.3V 芯片
报告总结

量产或维修时,编程器软件里搜不到手上这颗 SPI NOR 的型号,出不了片、刷不了固件。文档先把「编程器认型号」这件事拆到底层机制,再给出六条按耗时从短到长排列的解决路径,每条都落到可执行的具体操作:改哪个配置文件、填哪些字段、发什么命令、怎么判断成功。

结论

型号只是参数表的别名。只要能把这颗芯片的容量、擦除粒度与命令码、页编程、地址宽度、状态寄存器与保护/Quad 使能位这五组参数搞对,用什么型号名去烧都无所谓——这就是所有替代方案的共同原理。

1. 问题本质:编程器到底在认什么

把「认型号」还原成「查参数表」,问题就从「库里没有这个名」变成了「我能不能自己给出这组参数」。这一章是后面所有路径的共同基础。

1.1 型号库只是一张 ID → 参数的映射表

编程器软件里那个几万条的器件列表,本质是一张二维表:左边是 JEDEC ID,右边挂着这颗芯片的操作参数与时序。选中型号,软件只是把右边那组参数读出来,按它去发 SPI 命令。型号字符串本身不参与通信。所以「找不到型号」的真实含义是:软件手里没有一个已知 ID 能对上这颗芯片,因此没人告诉它该发什么命令。

编程器是怎么「认出」一颗 SPI NOR 的上电 / 复位释放掉电 0xAB读 JEDEC ID命令 0x9F(RDID)查型号库ID → 参数条目命中加载内置参数厂家预置算法读 / 擦 / 写 / 校验正常烧录未命中读 SFDP命令 0x5A有表解析参数容量/擦除/页无表报错:未知器件 / Unknown chip软件里自然「找不到型号」人工介入:指定同参数型号 / 手动填参数(本方案的落点)注:型号库只是一张「ID → 参数」的映射表。型号名本身对烧录没有意义,有意义的是它背后那组参数。
图 1 · SPI NOR 编程器识别链路:从读 ID 到加载参数的三条分支

1.2 编程器真正需要的那组参数

无论哪条路径,最终都要落到下面 8 项。做兼容替换或手填参数时,就是逐项确认这 8 项。

#参数典型值 / 命令填错会怎样
1总容量512Kb – 2Gb(64KB – 256MB)读写出界;校验报地址越界或尾部数据丢失
2页大小 Page256 B(少数 512 B / AAI 字节写)跨页回绕:末尾数据覆盖本页开头而不报错
3擦除粒度与命令4KB / 0x20,32KB / 0x52,64KB / 0xD8命令不支持则擦不掉;粒度填大则误擦相邻数据
4页编程命令0x02(Dual 0xA2、Quad 0x32)写入无响应,校验全 0xFF 或全 0x00
5地址宽度≤16MB 用 3 字节;>16MB 需 4 字节高地址区读写回绕到低地址,固件跑飞
6读命令 + dummy 周期0x03 / 0x0B(8 dummy)/ 0xEB读回数据与写入不符,但芯片内容可能其实是对的
7状态寄存器与保护位SR1/SR2/SR3,BP[3:0]、CMP、TB、SEC、SRP写保护没解除 → 写入静默失败或报保护错误
8特殊解锁 / 时序WEL(0x06)、4B 模式 0xB7/0xE9、QE 位、复位 0x66/0x99卡在某一步不动;或 Quad 模式读不到数据

说明:上表为通用 NOR 的通行约定,具体以器件 datasheet 为准;命令码见附录 A。

1.3 JEDEC ID:三字节里装了什么

主机发 0x9F(RDID)后,芯片回 3 字节:厂商 ID + 存储器类型 + 容量码。这是所有编程器识别的起点,也是手工建型号时必须填准的字段。

字节含义示例(W25Q128JV)说明
第 1 字节Manufacturer ID 厂商0xEF(Winbond)由 JEDEC 分配;部分国产厂商存在复用/自定义,见附录 B
第 2 字节Memory Type 类型0x40常编码了电压/系列/代次,不同厂商定义不一
第 3 字节Capacity 容量码0x18 → 16 MB近似 2^n 关系,但不能反推,必须查表
拿到 ID 的最快办法

不用管软件认不认:把编程器切到 GENERIC / SPI 通用识别模式读一次 ID,或用逻辑分析仪抓一次 0x9F 的响应。拿到 3 字节 ID 后,再去比对手册里的 ID 表,就能从印字模糊的料片反推出真实型号。

1.4 SFDP:芯片自己带的一张参数表

JEDEC 的 JESD216 标准规定:现代 SPI NOR 内部固化了一张只读参数表,叫 SFDP(Serial Flash Discoverable Parameters),用命令 0x5A 读取(3 字节地址 + 8 个 dummy 时钟,之后连续读出)。芯片出厂时就把容量、页大小、支持哪几种擦除命令、每种擦多大写在这张表里了。

这是最理想的情况:参数由芯片自报,主机压根不需要认识这颗料。flashrom、NXP LinkServer 的通用 flash 驱动、RT-Thread 的 SFUD 走的都是这条路。

优先级建议

遇到未知型号,第一步永远是先试 SFDP:能读出来就直接用,不用找替代型号、不用改配置文件。只有 SFDP 读不出来时才往后走其他路径。

1.5 找不到型号的四种真实原因

原因典型表现对应路径
软件版本太旧同厂同系列的新料号搜不到,老料号能搜到升级软件/器件库;P1
国产或小厂新料印字是陌生品牌(XTX、PUYA、XM25、PY25、HK25Q 等)P1 / P2 / P5
印字不是型号丝印只有 logo + 两三码缩写,查不到对应 datasheet先读 ID 反查;P3
ID 冲突或厂商自定义识别出型号但容量不对、擦除报错P2 手填 ID 与参数;P5

2. 六条解决路径总览

按「多久能出片」排序。前两条通常当天就能解决,第三条是原理上最干净的,第四条绕过编程器,第五条是长期兜底,第六条是彻底但慢。

找不到型号时的路径选择编程器提示「未知器件」先判一件事:芯片支持 SFDP 吗?(发 0x5A 读 4 字节,看是不是 53 46 44 50)支持就走 P3,一切参数由芯片自报,最省事支持不支持 / 读不出P3 · SFDP 自动识别容量、擦除命令、页大小全部由芯片自报flashrom 会以 “SFDP-capable chip” 直接干活能拿到这颗芯片的 datasheet 吗?(原厂官网 / 代理商 / 立创商城资料页)没有 datasheet 就拿不准参数,只能先去要能拿到拿不到P1 · 同参数兼容型号顶替按五组参数逐项比对,选库里最接近的一颗来烧P6 · 要资料 / 请厂商加型号原厂 FAE、代理商、编程器厂商,通常 1–2 周进库以下两条为备选手段(视场景选用)P2 · 手动建型号ID 填真值,算法挂靠一颗兼容型号P4 · 绕开编程器走主控侧SoC 的 bootloader / U-Boot / 调试器P5 · 自建通用烧录器 —— 不依赖任何型号库,长期兜底
图 2 · 找不到型号时的六条路径决策树
PATH 1
同参数兼容型号顶替
在库里找一颗参数完全相同的已知型号来烧。型号名不同无所谓,参数对得上就行。 前提是能拿到未知芯片的 datasheet 做逐项比对。
耗时 5–30 分钟 · 风险低 · 需 datasheet
PATH 2
手动建型号
在编程器的用户自定义配置文件里新建一条:ID 填真值,算法挂靠一颗兼容型号。 RT809H 改 DEVICE.INI,CH341A 系改 AsProgrammer / NeoProgrammer 的芯片库。
耗时 30–60 分钟 · 风险中 · 需知道兼容基准型号
PATH 3
SFDP 自动识别
让工具直接读芯片自带的参数表。flashrom 会报 “Unknown SFDP-capable chip” 并自动解析出容量与擦除命令,读/擦/写/校验都能正常工作。
耗时 5 分钟 · 风险低 · 仅芯片支持 SFDP 时可用
PATH 4
绕开编程器,走主控侧
通过板端 SoC 的 bootloader、U-Boot sf 命令、或调试器(J-Link/OpenOCD) 把固件写进 flash。适用于芯片已焊在板上且不打算拆的场景。
耗时视环境 · 需板子能进下载模式
PATH 5
自建通用 SPI NOR 烧录器
USB-SPI 桥接器(CH347 / FT2232H / RP2040 / 树莓派)+ flashrom 或 SFUD, 完全不依赖商业型号库。既是主力工具,也是验证其他路径的手段。
耗时半天–一天 · 一次性投入,长期兜底
PATH 6
请厂商加型号
把样片与 datasheet 发给编程器厂商或芯片原厂 FAE,对方排期进库。 适合量产长期使用的料号,一次性把问题根治。
耗时 1–2 周 · 风险最低 · 适合量产
路径适用场景前置条件出片耗时长期可用性
P1 兼容顶替有 datasheet,能找到参数相同型号datasheet + 库里有相近型号★ 最快中
P2 手动建型号没有完全一致的,但算法可挂靠知道用哪颗型号的算法★★中高
P3 SFDP2015 年后的主流料,支持 JESD216工具支持 SFDP(flashrom 等)★ 最快高
P4 主控侧烧已贴片、有串口/USB/JTAG 下载口bootloader 可用★★★高
P5 自建烧录器型号杂、经常换料、需要可控会接线 + 命令行基础★★★★最高
P6 厂商加型号量产定型料号能联系到厂商/FAE★★★★★高

3. 路径一:同参数兼容型号顶替

成本最低、见效最快。核心动作是「比对」而不是「猜」——逐项核对 5 组关键参数,确认无误后用库里已有的型号名去烧。

拿库里已有的型号「顶替」未知型号:逐项比对 + 闭环验证① 定容量印字 / 0x9F 容量码 / SFDP必须完全一致② 定擦除粒度4K / 32K / 64K 命令码0x20 / 0x52 / 0xD8③ 定页与编程页 256B、命令 0x02跨页回绕行为④ 定地址宽度≤16MB 用 3 字节>16MB 需 4 字节⑤ 定保护与 QE状态寄存器、BP 位QE 位位置五项全部一致(或差异在可容忍范围内)?是否建自定义型号条目ID 填真值,算法挂兼容型号换路径P5 自建烧录器强制闭环验证(缺一不可)① 先整片读回存档 → ② 空片检查 → ③ 写入 → ④ 读回逐字节比对 → ⑤ 装机实跑
图 3 · 兼容型号替换的逐项比对与闭环验证流程

3.1 五组必查参数与容忍度

下表是判定「能不能顶替」的依据。左列任一项不满足,就不许顶替;右列不满足,必须回到 datasheet 确认或换路径。

参数组必须一致(不可容忍差异)可容忍的差异去 datasheet 哪里查
容量总容量必须相同(或选库里更大的同系列并手动限定烧录长度)无Feature / Ordering Information 的密度表
擦除粒度与命令扇区擦 0x20、块擦 0x52/0xD8 的命令码与粒度必须一致整片擦除命令 0xC7/0x60 差异无关紧要Instruction Set Table 中 Erase 组
页编程页大小必须一致(主流 256B)Dual/Quad 编程命令(0xA2/0x32)有无不影响单线烧录Page Program 时序与 AC 特性表
地址宽度≤16MB 用 3 字节;>16MB 必须支持 4 字节(0xB7 或 4B 命令)4 字节的进入/退出方式可不同(0xB7 或专用 4B 命令)Addressing / 4-Byte Address Mode 章节
状态寄存器与保护写使能 0x06、状态寄存器读 0x05 必须一致QE 位位置可以不同——离线单线烧录时不进 Quad 模式,用不到Status Register 与 Quad Enable 章节
最容易翻车的一条:QE 位

Quad Enable 位的位置各厂各代次都不一样(有的在状态寄存器 2 的 bit1,有的在状态寄存器 1 的 bit6,还有的放在易失配置寄存器里)。但离线单线烧录根本用不到 QE 位——只有在 Quad/DTR 模式下读写才需要它。所以做兼容替换时,QE 位不一致不影响烧录本身,只影响「烧进去的固件能不能在目标板上以 Quad 模式启动」。这一项要分开判断,别混为一谈。

3.2 找基准型号的实操顺序

  1. 先认厂:读 0x9F 拿厂商 ID,对照附录 B 确定原厂。同厂同系列优先,跨厂次之。
  2. 再定容量:按容量码或印字确定密度,在库里筛出同容量的一批候选。
  3. 查代次:同容量下优先选同一代工艺的型号(如 GD25QxxE 对 GD25QxxE,不要拿老 GD25Qxx 的算法去烧新 E 代)。
  4. 比对命令集:打开两份 datasheet 的 Instruction Set 表,逐行核 0x20/0x52/0xD8/0x02/0x03/0x0B/0x05/0x01/0x06。
  5. 建条目并小范围试:不要一上来就整片擦写。先读回原片存档,再只擦一个扇区、写几十字节、读回比对。
  6. 通过后放量:小范围验证 OK 后,再整片烧录并做全片校验。

3.3 闭环验证:五个动作缺一不可

步骤动作判定标准失败时说明什么
① 存档整片读回,存成 bin 并备份文件大小 == 标称容量容量填错,或接触不良
② 空检Blank Check(或读回看是否全 0xFF)空白片应全 FF前次数据没擦净,或擦除命令不生效
③ 擦除执行 Chip Erase不报错,读回全 FF写保护未解除,或擦除命令码不对
④ 写入 + 校验写固件并自动读回比对提示 VERIFIED / 校验通过页大小或编程命令错;跨页回绕
⑤ 装机实跑焊回板上通电运行系统正常启动参数对但配置位(QE/4B/保护)不对
第 ⑤ 步不能省

前面四步全过,只说明数据被正确地写进去了,不代表目标板能以 Quad 模式读到它。批产前必须装机实跑至少一片:验证 QE 位、4 字节地址模式、状态寄存器非易失位等配置是否符合主板要求。跳过这步,量产线上会成片地「烧录 100% 通过、上电全不启动」。

4. 路径二:手动建型号(主流编程器实操)

库里没有,就自己补一条。原理统一:ID 用真值(让软件认得这颗料),算法挂靠一颗参数相同的已知型号(让软件知道怎么操作)。

手动建一条型号 = 给软件补一条「ID → 借来的算法」① 真身 ID0x9F 读回的 3 字节ex. 0x0B4018② 借来的算法库里已有的兼容型号ex. W25Q128JV③ 容量与电压datasheet 查得ex. 16MB / 1.8V用户自定义器件条目(配置文件中的一条记录)ChipID = 0x0B4018 AlgoRef = W25Q128JV ChipSize = 16384 VCC = 1.8V软件重启后:列表里出现自定义型号 → 选中即可烧录
图 4 · 手动建型号:真身 ID + 借来的算法 = 一条可用记录

4.1 RT809H / RT809F:编辑 DEVICE.INI

RT809 系列一直支持用户自行扩充器件库。安装目录下找到 DEVICE.INI(默认 D:\RT809H\DEVICE.INI),按 [ChipN] 的编号逐个递增追加条目,序号不能与已有条目重复,否则无效。

字段含义怎么填
User作者/备注信息任意,可留空或写自己名字
ManuName厂商名称按印字或 ID 反查的原厂名,如 XTX、PUYA
ChipName型号/印字芯片表面实际印字,方便以后在列表里搜到
ChipSize容量按文件内注释给定的单位填写(示例文件中有说明)
ChipID核心字段以 0x 开头 + 6 位十六进制 = 0x9F 读回的 3 字节,如 0x0B4018
AlgoRef核心字段填库里已有、参数兼容的型号名,算法直接复用它的
VCC / VCCIO供电 / IO 电平1.8V 器件必须在这里写对,写 3.3V 会打穿芯片
PinVal引脚接触检测值不确定可留空;填错会导致误报接触不良
VPP / TSCE / TPROG高压 / 擦除时间 / 编程时间一般留空,让软件沿用 AlgoRef 的默认值

完整示例:给一颗 1.8V 的 16MB 国产料建条目

; —— 追加在 DEVICE.INI 末尾,序号接在最后一个 [ChipN] 之后 ——
[Chip1]
User = YourName
ManuName = XTX
ChipName = XT25F128B
ChipSize = 16384
ChipID   = 0x0B4018
AlgoRef  = W25Q128JV
PinVal   =
VCC      = 1.8
VPP      =
VCCIO    = 1.8
TSCE     =
TPROG    =
选 AlgoRef 的经验法则

官方给出的经验是:W25X 与 MX25L 系列的算法通用性最好,优先考虑;而 SST、PCT 这类指令集比较特殊的,只能用同一厂商的型号来挂,跨厂大概率失败。实操中就是先用 W25Q 系列试,不行换 MX25L,再不行回同厂同系列。

改之前先备份

DEVICE.INI 是纯文本,改错一个字符可能导致软件启动异常。动手前先复制一份原文件,改完重启软件,在器件列表里搜自己写的 ChipName 确认能出现。

4.2 XGecu(T48 / T56 / T76):用型号支持列表先确认

XGecu 各机型的器件支持列表是公开的,遇到问题先在官方列表里核对一次,确认是不是真的没有——很多时候只是丝印与列表里的正式型号写法不同导致的误判。

机型能力范围支持列表
T48I2C / SPI / LPC / FWH / 并行 / eMMCxgecu.com/MiniPro/T48_List.txt
T56同上,含 eMMCxgecu.com/MiniPro/T56_List.txt
T76更高速,面向量产见官网 MiniPro 目录
8Mb 及以上器件的注意点

社区反馈:EZP 与部分 XGecu 机型对 8Mb(1MB)及以上的 ROM 自动识别不太准,建议手动指定型号而不是依赖自动识别;若读写报错,先把速度档位调低再试。这一条同样适用于其他品牌的国产编程器。

4.3 CH341A 系(AsProgrammer / NeoProgrammer)

这两个是 CH341A 编程器最常用的上位机,都允许往芯片库里加条目。做法一致:找到安装目录下的芯片定义文件(按软件版本不同,可能是 XML 或文本格式的库文件,具体以该版本 README 为准),照着同厂同容量的一条复制,改掉这几个关键字段即可。

字段(常见命名)填什么说明
name自定义型号名建议写成「印字 + 容量」,方便以后搜索
id3 字节 JEDEC ID厂商+类型+容量,十六进制连写,如 0B4018
size总容量注意单位(KB 或字节),填错会导致读写截断
pagesize页大小主流 256
sector / block擦除粒度分别填 4096 与 65536(4K/64K)
硬件前提:先把 CH341A 的电平问题解决

给 CH341A 加型号之前,请务必先读 第 7 章。黑色版 CH341A 的 IO 电平是 5V,而它给芯片供的是 3.3V——长期超规格使用会损伤 3.3V 的 SPI NOR,1.8V 器件更是一次就可能打穿。先改造或加电平转换,再谈烧录。

4.4 flashrom:往 flashchips.c 加一条

如果走 P5 自建烧录器(用 flashrom),加型号是改源码里的 flashchips.c,在对应厂商段追加一条结构体。字段含义如下,照抄一条最接近的再改关键项即可。

{
    .vendor         = "XTX",
    .name           = "XT25F128B",
    .bustype        = BUS_SPI,
    .manufacture_id = 0x0B,          /* 厂商 ID:0x9F 第 1 字节 */
    .model_id       = 0x4018,        /* 类型+容量:第 2、3 字节 */
    .total_size     = 16384,         /* 容量,单位 kB → 16MB */
    .page_size      = 256,
    .feature_bits   = FEATURE_WRSR_WREN,
    .tested         = TEST_UNTESTED,
    .probe          = PROBE_SPI_RDID,
    .probe_timing   = TIMING_ZERO,
    .block_erasers  = {
        {
            .eraseblocks = { {4 * 1024, 4096} },          /* 4096 个 4KB 扇区 */
            .block_erase = SPI_BLOCK_ERASE_20,            /* 命令 0x20 */
        }, {
            .eraseblocks = { {64 * 1024, 256} },          /* 256 个 64KB 块   */
            .block_erase = SPI_BLOCK_ERASE_D8,            /* 命令 0xD8       */
        }, {
            .eraseblocks = { {16 * 1024 * 1024, 1} },     /* 整片             */
            .block_erase = SPI_BLOCK_ERASE_60,
        }
    },
    .printlock      = SPI_PRETTYPRINT_STATUS_REGISTER_PLAIN,
    .unlock         = SPI_DISABLE_BLOCKPROTECT,           /* 写前自动解保护 */
    .write          = SPI_CHIP_WRITE256,                  /* 256B 页编程    */
    .read           = SPI_CHIP_READ,
    .voltage        = {1650, 2000},                       /* 1.8V 器件!    */
},
其实多数时候不用改代码

flashrom 会先跑 SFDP 探测。只要芯片支持 SFDP,即使 flashchips.c 里没有它,flashrom 也会把它识别成 “Unknown SFDP-capable chip” 并自动解析出容量与擦除命令,读/擦/写/校验全部可用——直接 -c "SFDP-capable chip" 就能干活。改源码只在芯片不支持 SFDP 时才必要。

4.5 嵌入式侧:SFUD 加一条

如果目标是让设备自己的 MCU 驱动这颗 flash(而不是用编程器烧),RT-Thread 的 SFUD(Serial Flash Universal Driver)在 sfud_flash_def.h 里维护了一张静态表,不支持 SFDP 的老芯片靠它兜底。加一条的字段格式:

/* {"型号名", 厂商ID, 类型ID, 容量ID, 容量(字节), 写模式, 擦除粒度, 擦除命令} */
{"XT25F128B", 0x0B, 0x40, 0x18, 16L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20},

SFUD 的识别是三级回退:先 SFDP → 再查静态表 → 最后用手动写死的参数。三条路都失败才初始化失败。所以给 SFUD 加条目的唯一场景是「既没有 SFDP、表里又没有」的老料。

4.6 建完怎么验:先小后大

  1. 重启软件,搜索自定义型号名,确认能出现在列表里且 ID 显示为你填的值。
  2. 先只读不写:整片读回存档。读不出来说明 ID 或接触有问题,别往下走。
  3. 单扇区试擦:只擦一个 4KB 扇区,读回确认该扇区变全 FF、其余区域未受影响。
  4. 小数据试写:往刚擦的扇区写几十字节,读回比对。
  5. 全片烧录 + 校验:通过后整片写入并自动校验,确认出现 VERIFIED。
  6. 装机实跑:焊回目标板上电,确认能正常启动(验证 QE 位、4 字节地址等配置位)。

编制日 2026-08-29 · 适用于研发 / 维修 / 生产场景的 SPI NOR 烧录问题处置

相关报告 · 交叉引用 1 器件全部展开收起 ▾
点开类目即可展开:具体文档 / 章节(点章直接跳转到该章)
SPI NOR
电路设计指南
软件设计规范
Linux 驱动开发
样机问题排查
量产问题排查
系统设计指南