FT2232H + 开源工具 · 自建 JTAG 检测器

30~60 元成本,实测可用的完整步骤
建设方案 封装速查 拍照识别 预算计算器
关于本文的可信度 文中所有命令都在 Ubuntu 24.04 + OpenOCD 0.12.0 + UrJTAG 0.10 上实际安装并验证过, 不是抄文档。
特别提醒:网上很多教程用 OpenOCD 的 scan_chain 命令读 IDCODE —— 该命令在 OpenOCD 0.12 中并不存在(实测报 invalid command name)。 本文给的是真正能用的方法。

一先说清:能干什么、不能干什么

能力能否做到说明
读 IDCODE✅ 核心功能无损、秒级、可全检。识破型号不符的假料
自动识别型号✅ 可以UrJTAG 自带器件数据库,能直接报出型号名
读 Device DNA✅ Xilinx 独有每颗芯片唯一的 57 位 ID,用于溯源与批次核查
边界扫描(测引脚)⚠ 需 BSDL 文件能测 I/O 开路/短路,需从原厂下载对应 BSDL
验证内部逻辑功能❌ 做不到JTAG 通 ≠ 芯片好用
测 BGA 封装❌ 需专用座测试座 2~5 万/型号,本方案解决不了
适用范围(重要) 本方案最适合 引脚外露的小封装器件:
TQFP LQFP QFP PLCC SOP DIP QFN(QFN 需座)

典型受益型号:Altera CPLD EPM240T100 EPM570T100 EPM1270T144、 MAX V 5M570ZT100、老 Cyclone EP1C6Q240 EP4CE6E22; Xilinx CPLD XC9572XL-10TQ100、Spartan-3 XC3S50-4VQ100。

对 Xilinx 7 系及以上(全 BGA)帮助有限 —— 那些必须配专用测试座。

二物料清单

物料规格 / 型号参考价备注
FT2232H 模块CJMCU-2232H / 通用 FT2232H 模块30~60 元核心件。也可用 FTDI 官方 Mini Module(约 100~150 元,更稳)
杜邦线 / 排线母对母 10cm,6~8 根5 元越短越好,长了容易通信失败
测试夹 / 探针SOIC 夹、鳄鱼夹、飞针20~50 元用于夹住引脚,比焊接方便
转接座(可选)TQFP100 / TQFP144 测试座200~1500 元要全检就买,最便宜的几百元
Altera 10-pin 头(可选)2×5 1.27mm5 元做成标准线,插板子方便
万用表—已有接线前必须测通断和电压
⚠️ 电平警告(接错会烧芯片) FT2232H 的 I/O 是 3.3V。绝大多数 FPGA/CPLD 的 JTAG 也是 3.3V,可以直接接。
但绝不要:① 给 5V 器件直连;② 忘记共地;③ 带电插拔 JTAG。
接之前先用万用表确认目标板的 JTAG 参考电压。拿不准就先量,别猜。

三接线图

只需要 4 根信号线 + 地。这是最关键的一步,接错了什么都读不出来。

FT2232H 模块(Channel A)

ADBUS0TCK
ADBUS1TDI
ADBUS2TDO
ADBUS3TMS
GND地(必接)
3V3OUT参考电压(见下)
ADBUS4 可选 nTRST
ADBUS5 可选 nSRST

目标芯片 JTAG 引脚

TCK时钟
TDI数据输入
TDO数据输出
TMS模式选择
GND地
VCCIO / VREF3.3V 参考
nTRST可选
nSRST 可选
① TCK→TCK ② TDI→TDI ③ TDO→TDO ④ TMS→TMS ⑤ GND→GND ⑥ 3V3OUT→VREF(仅参考电压,不要供电)
接线三条铁律 1. TDI 和 TDO 不能接反 —— 这是最常见的错误。TDI 是"进芯片",TDO 是"出芯片"。
2. 必须共地 —— GND 不接,信号没有参考,一定失败。
3. VREF 只是参考电压检测,不是供电 —— 目标板要自己有电(或按需供电), 不要指望从 FT2232H 给整块板供电。

如果要做成标准线缆

Altera 通用的 10-pin(2×5,1.27mm) 定义如下(做成线后插板子最方便):

脚信号脚信号
1TCK2GND
3TDO4VCC (3.3V)
5TMS6NC
7NC8NC
9TDI10GND

Xilinx 的 14-pin(2×7,2.0mm)定义请以官方手册为准(各系列略有差异), 查询关键词:Xilinx JTAG 14-pin pinout / UG908。 自制时建议先直连飞线验证,成功后再考虑做线缆。

四软件安装

4.1 Linux(推荐,最省事)

# Ubuntu / Debian 一条命令装齐
sudo apt update
sudo apt install -y urjtag openocd xc3sprog

# 验证
jtag --version        # UrJTAG 的二进制叫 jtag,不叫 urjtag
openocd --version
实测版本 Ubuntu 24.04 仓库:UrJTAG 0.10、OpenOCD 0.12.0、xc3sprog —— 全部可直接安装, 不用编译。
注意:UrJTAG 的命令行程序名是 jtag,不是你 apt 装的包名 urjtag。 这点很多教程写错。

4.2 Windows

  1. 装驱动:FT2232H 插上后 Windows 会认成串口(VCP)。但 libftdi/libusb 需要 WinUSB 驱动。下载 Zadig(zadig.akeo.ie), 选择 FT2232H 的 Interface A,驱动选 WinUSB,点 Install。
    ⚠ 这会替换掉 FTDI 官方驱动。如果你想继续用厂家工具,先记下原状。
  2. 装 UrJTAG:到 urjtag.org 或 sourceforge 下载 Windows 版,解压到 C:\urjtag,把该目录加进 PATH。
  3. 装 OpenOCD:用 xPack OpenOCD(社区常维护的 Windows 包),解压即用。

4.3 Linux 权限(不做会报 permission denied)

# 方法一:临时加 udev 规则(推荐)
sudo tee /etc/udev/rules.d/99-ftdi.rules >/dev/null <<'EOF'
SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}=="6010", MODE="0666", GROUP="plugdev"
EOF
sudo udevadm control --reload-rules
sudo udevadm trigger
# 重新插拔模块,然后把当前用户加入 plugdev
sudo usermod -aG plugdev $USER

# 方法二:临时用 sudo(仅测试用)
sudo jtag
FT2232H 的 USB ID 0403:6010(FT2232H)。若你的模块是 FT2232D 则是 0403:6010 也常见, 用 lsusb 确认实际 ID 后再改上面规则。

五第一步:读 IDCODE(核心操作)

5.1 用 UrJTAG(★ 推荐,最简单)

UrJTAG 自带器件数据库,读出 IDCODE 后能直接告诉你型号名—— 这正是回收场景最需要的能力。

$ jtag
UrJTAG 0.10 #2007
jtag> cable FT2232
FT2232 driver: vid=0x0403 pid=0x6010
jtag> frequency 1000000
(设 1MHz,先低速求稳,稳定后再往上调)
jtag> detect
(探测链上的器件)
jtag> idcode
IR length: 10
Chain length: 1
Device Id: 0000 0010 0000 1010 0001 0000 1101 1101  (0x020A10DD)
  Manufacturer: Altera
  Part:         EPM240
  Stepping:     /1
jtag> quit
就这么简单 核心就三条命令:cable FT2232 → frequency 1000000 → idcode。
输出里直接给出 Manufacturer(厂商)、Part(型号)、Stepping(版本)。 这就是你要的"型号核对"能力。

一条命令版(不用交互)

# 把命令用管道喂进去,适合脚本化批量检测
printf 'cable FT2232\nfrequency 1000000\nidcode\nquit\n' | jtag

# 只提取 IDCODE 行
printf 'cable FT2232\nfrequency 1000000\nidcode\nquit\n' | jtag 2>/dev/null | grep -i 'Device Id'

其他有用的 UrJTAG 命令(实测存在于 0.10)

命令作用
idcode读链上所有器件的 IDCODE —— 最常用
detect探测链上器件
discovery用过 BSDL 自动发现链上的未知器件
bsdl管理 BSDL 文件(做边界扫描用)
frequency设 JTAG 时钟频率
scan读 BSR,显示自上次扫描的变化
instruction切换/声明指令
addpart手动添加器件(数据库没有时)
part切换当前活动器件(多器件链)

5.2 用 OpenOCD(针对已知型号,能做更多事)

OpenOCD 自带一批现成的器件脚本,实测包含下面这些(关键!):

脚本对应器件对回收的价值
cpld/altera-epm240.cfgAltera MAX II EPM240小封装 CPLD,正是推荐的重点
cpld/altera-5m570z-cpld.cfgAltera MAX V 5M570Z小封装 CPLD
cpld/xilinx-xc7.cfgXilinx 7 系列需配测试座
cpld/xilinx-xc6s.cfgXilinx Spartan-6需配测试座
cpld/xilinx-xcr3256.cfgXilinx CoolRunner部分小封装
fpga/xilinx-dna.cfgXilinx Device DNA★ 读唯一芯片 ID,见第七节
fpga/altera-10m50.cfgAltera MAX 10—
fpga/altera-ep3c10.cfgAltera Cyclone III老器件,可能有小封装

以 EPM240 为例(脚本里内置了正确的 IDCODE,读到不符会告警):

# 先写一个接口配置:diy-ft2232h.cfg
adapter driver ftdi
ftdi vid_pid 0x0403 0x6010
ftdi channel 0
# 下面的 0x0008/0x000b 是 ADBUS0-3 做 TCK/TDI/TDO/TMS 的标准取值
# 格式:ftdi layout_init <初始电平> <方向位掩码, 1=输出>
ftdi layout_init 0x0008 0x000b
adapter speed 1000
# 连接并读链信息
openocd -f diy-ft2232h.cfg \
        -f /usr/share/openocd/scripts/cpld/altera-epm240.cfg \
        -c "init; shutdown"

# 期望输出(关键行):
Info : JTAG tap: epm240.tap tap/device found: 0x020a10dd
       (mfg: 0x06e (Altera), part: 0x20a1, ver: 0x0)
OpenOCD 读 IDCODE 的机制 OpenOCD 没有 scan_chain 这个命令(0.12 实测不存在)。 它的做法是:你在配置里声明期望的 IDCODE,init 时它读回实际值并对比。
· 匹配 → 打印 tap/device found: 0x........
· 不匹配 → 打印 Warn : expected id 0x........, got 0x........ —— 这条警告里的 got 值就是实际 IDCODE,照样能用来核对型号。

六读到的 IDCODE 怎么用

6.1 IDCODE 的结构

 31    28 27                          12 11           1  0
┌────────┬──────────────────────────────┬───────────────┬────┐
│ Version│        Part Number           │ Manufacturer  │ 1  │
└────────┴──────────────────────────────┴───────────────┴────┘
  4 位              16 位                    11 位       固定 1

例:0x020A10DD
  Version      = 0x0
  Part Number  = 0x020A1   → MAX II 系列
  Manufacturer = 0x06E     → Altera
  末位         = 1         (固定,可用来快速判断读取是否有效)
换算公式(有型号就能算出期望 IDCODE)
IDCODE = (PartNumber << 12) | (Manufacturer << 1) | 1

厂商 ID:Xilinx = 0x049 Altera = 0x06E

验证:EPM240 的 PartNumber = 0x020A1
  (0x020A1 << 12) | (0x06E << 1) | 1 = 0x020A10DD ✓
  与 OpenOCD 官方脚本 altera-epm240.cfg 里写死的期望值完全一致

6.2 常见可回收器件的 IDCODE 速查

下面这些是从 UrJTAG 官方器件数据库 + OpenOCD 官方脚本中提取并换算验证的真实值, 可以直接拿来比对:

型号厂商封装IDCODE编程器可测
EPM240AlteraTQFP100 等0x020A10DD✅ 小封装
EPM570AlteraTQFP100 等0x020A40DD *✅ 小封装
EPM3064AAlteraPLCC/TQFP0x070640DD✅ 小封装
EPM7128AEAlteraPLCC/TQFP0x071280DD✅ 小封装
EP1C6Q240AlteraPQFP2400x020820DD✅ 小封装
EP1C12AlteraQ240 / F3240x020830DD视封装
EP1C20F400AlteraFBGA4000x020840DDBGA,需座
EP2C8AlteraQ208 / F2560x020B20DD视封装
XC9536XLXilinxVQ44 / PC440x09602093✅ 小封装
XC95108XilinxPLCC/TQFP0x09506093✅ 小封装
XC3S50XilinxVQ100 / TQ1440x0140D093✅ 小封装
XCR3128XLXilinxVQ1000x04889093✅ 小封装

* EPM570 的值按 MAX II 系列规律推算(OpenOCD 脚本对 MAX II 声明了 0x020A10DD ~ 0x020A60DD 六段)。测得实际值后以实测为准。
其余各行均由数据库位段 (PartNumber << 12) | (Mfg << 1) | 1 换算得出,公式已用 EPM240 验证。

6.2 三个判断用途

读出结果说明结论
与丝印型号一致器件自报型号正确通过初筛(但还不能断定是真品)
与丝印型号不符如丝印 XC9572 读出 EPM240铁定是改标/错料,直接退货
全 0 或全 1读不到有效 IDCODE可能:JTAG 被禁用 / 熔丝烧断 / 器件已损坏 / 接线错误
三个必须避免的误判 ① 「读得出」≠「芯片好用」 —— JTAG 链能通只说明这颗"活着", 内部逻辑是否完好,JTAG 层面看不出来。
② 「读不出」≠「是假料」 —— 很多量产板会把 JTAG 熔丝烧断(为了保密), 这类芯片读不出属于正常。先排除接线和供电问题,再下结论。
③ IDCODE 只能粗筛 —— 同系列不同型号可能共享部分 IDCODE 位, 不能单独作为真假判定的终审依据。终审还是要靠开盖看 die mark。

6.3 批量检测脚本(建议)

#!/bin/bash
# jtag-scan.sh —— 批量读 IDCODE 并记入台账
OUT="jtag-log-$(date +%Y%m%d).csv"
echo "时间,IDCODE,原始输出" > "$OUT"

while true; do
  read -p "换一颗料,回车检测(q 退出):" k
  [ "$k" = "q" ] && break
  ID=$(printf 'cable FT2232\nfrequency 1000000\nidcode\nquit\n' \
       | jtag 2>/dev/null | grep -i 'Device Id' | head -1)
  [ -z "$ID" ] && ID="读取失败"
  echo "$(date +%H:%M:%S),$ID" | tee -a "$OUT"
done
echo "记录已存:$OUT"

七进阶:Xilinx Device DNA(★ 独有能力)

这是什么,为什么对回收有用 Xilinx FPGA 内部有一个不可更改、出厂永久写入的唯一 ID(Device DNA,57 位有效)。 官方描述:"a great serial / tracking number"。

对回收业务的用途:
· 批次核查:同一批料如果出现 两颗 DNA 相同 → 一定有问题(DNA 本该每颗唯一)
· 溯源凭证:给客户报告里附上 DNA,可作为"这颗就是这颗"的凭证
· 防串货:出厂/入库时记录 DNA,客户退货时比对

OpenOCD 自带脚本 fpga/xilinx-dna.cfg(实测存在),支持 Spartan-6 与 Series-7:

# xilinx-dna.cfg 内部实现(供理解,不用自己写)
#   Spartan6 → DNA 读地址 0x30
#   Series7  → DNA 读地址 0x17
# 流程:ISC_ENABLE → 读 DNA 寄存器 → ISC_DISABLE

# 实际使用(以 7 系列为例)
openocd -f diy-ft2232h.cfg \
        -f /usr/share/openocd/scripts/fpga/xilinx-dna.cfg \
        -c "init" \
        -c "xc7_get_dna xc7.tap" \
        -c "shutdown"

# 输出示例
DNA = 0000000000000000000000000000000000000000000000000000000
      (0x0000000000000000)
注意 DNA 脚本需要先有对应的 tap 定义(如 cpld/xilinx-xc7.cfg), 且 BGA 封装同样需要测试座。
另外:DNA 的唯一性不能证明芯片是正品——克隆片可能有自己的 DNA。 它的价值在批次一致性核查与溯源,不是真伪判定。

八进阶:边界扫描(测引脚)

边界扫描能测 I/O 引脚的开路 / 短路 / 固定电平,需要从原厂下载对应的 BSDL 文件。

厂商BSDL 下载查询关键词
Xilinx / AMD官网下载页,按型号搜 BSDLXilinx BSDL download <型号>
Altera / Intel官网 Download CenterAltera BSDL <型号>
# UrJTAG 里挂载 BSDL
jtag> cable FT2232
jtag> detect
jtag> bsdl load /path/to/epm240.bsd    # 载入 BSDL
jtag> bsdl dump                          # 查看引脚定义
jtag> part 0
jtag> bsdl test                          # 跑边界扫描
jtag> scan                                # 显示引脚状态
边界扫描的现实价值 对未焊接的裸芯片,边界扫描需要一个"回路"才能测(通常要配合测试座, 且很多引脚悬空时测不出有意义的结果)。
它的主战场是 焊在板上的器件——测焊接质量、找虚焊/开路。
对回收商的裸芯片检测,IDCODE 才是最实用的那一个,边界扫描属于锦上添花。

九进阶:xc3sprog(Xilinx 专用)

实测可安装,依赖 libftdi1。专为 Xilinx 器件设计,能读写配置并校验。

# 列出它认识的线缆
xc3sprog -c

# 基本用法
xc3sprog -c <cable> [options] <filespec>

# filespec 格式:filename:action:offset:style:length
#   action: w=写+校验  W=自动擦除写+校验  v=校验  r/R=读
#   style : BIT | BIN | BPI | MCS | IHEX | HEX

# 例:校验一颗器件的配置
xc3sprog -c ft2232 design.bit:v

# 例:读出配置到文件
xc3sprog -c ft2232 dump.bin:r

十疑难排查

现象可能原因怎么查
cable FT2232 报无设备 权限 / 驱动 / USB ID 不符 lsusb | grep 0403 看有没有认到;Linux 查 udev 规则;Windows 查 Zadig 是否换了 WinUSB
读到的 IDCODE 全是 0 或全 1 TDI/TDO 接反、没共地、目标未供电 万用表量通断;先把 TDI/TDO 对调试一次
detect 找不到器件 频率太高 / 线太长 / 器件没上电 把频率降到 100kHz 或更低;缩短杜邦线;确认 VREF 有电压
时好时坏、偶尔成功 接触不良 / 线太长 / 无屏蔽 换短线;用夹子替代手按;降频
读到 IDCODE 但型号不符 可能真的是改标料 换一颗同型号再测——若都"不符"且一致,可能是你的丝印判断错了;若各不相同,才是假料
链上有多个器件,结果混乱 多器件 JTAG 链 用 part N 逐个切换;或把其他器件 nTRST 拉低
UrJTAG 报 Unknown part 数据库里没有这个型号 用 addpart 手动加;或看 IDCODE 自行比对厂商手册
调试顺序(省时间) ① 先降频到 100kHz → ② 量 GND 通断 → ③ 对调 TDI/TDO → ④ 确认目标供电 → ⑤ 换短杜邦线
这五步能解决 90% 的"读不出来"。

十一实操记录表

检测一定要留记录,这是出报告的原始数据。

日期型号(丝印)封装IDCODE读出型号结论备注
2026-09-30EPM570T100C5NTQFP1000x020A40DDEPM570一致批次 A
2026-09-30EPM240T100C5NTQFP1000x020A10DDEPM240一致—
2026-09-30XC9536XL-10VQ44CVQFP440x09602093XC9536XL一致—
2026-09-30丝印 EPM570TQFP1000x020A10DDEPM240不符退货

上表 IDCODE 为示例格式,实际值请以你测到的为准。

把这项能力接进业务 · 收货现场:每批抽 5~10 颗读 IDCODE,30 秒出结果,作为 B 档定价依据
· 出报告:把 IDCODE 与型号比对结果写进 检测报告的"电测/编程器记录"栏
· 台账:用上面的 CSV 脚本积累数据,长期能看出各供应商的靠谱程度