---
title: "jtagd 两项问题的成因与 USB Blaster 克隆设备修复"
canonical: "https://siyuanailab.com/curation/translations/884e08f4c9b87194a003c06529c68943-3131a8f2e635bb1de5d9a5826b61cdbd347a1b09992d2e53f54dfc414c27d031/"
dateModified: "2026-10-04"
datePublished: "2026-10-04"
---

[返回日报条目](https://siyuanailab.com/curation/#entry/884e08f4c9b87194a003c06529c68943)

 

资料节译

 

# jtagd 两项问题的成因与 USB Blaster 克隆设备修复

 

[阅读原文](https://www.downtowndougbrown.com/2026/10/altera-quartus-linux-jtagd-bug-fixes/)

 

现有资料无法确认原文完整，本页只翻译已取得的材料。

 

现有原件无法确认图片是否齐全。

 

几年前，我研究 Altera USB Blaster 仿制品的问题时有点过头了[](https://www.downtowndougbrown.com/2024/07/fixing-more-cheap-altera-usb-blaster-clones-cpld-adventures/)。写那篇文章时，我在 Linux 上遇到了一些令人非常沮丧、时有时无的 jtagd 问题，一直没能弄清楚原因：

 

我还在一台电脑上测试时，遇到了一个与此无关、非常奇怪的问题：Linux 上的 Quartus Programmer 18.1 出现了异常。我在 Wireshark 抓包中看到了损坏的 USB 发出流量——甚至还没涉及 FT245 或 CPLD。这个问题影响了我所有的 blaster，而不仅仅是 CPLD+FT245 型号。

 

我有时仍会注意到，在 Linux 上插入任何一款基于 CPLD 的 USB Blaster 后，第一次尝试执行 JTAG 操作会延迟很久（约 30 秒）。这并非每次都会发生，但发生时，jtagd 似乎会卡在等待接收一个永远不会到来的字节，于是超时后再试一次。之后就能正常工作了。

 

当时，我已经被其他 USB Blaster 问题折腾得筋疲力尽，完全失去了继续深挖这些恼人问题的兴趣，于是就把它们搁置了。直到现在。AI 让人们有机会解决其中一些小谜团，而不必花大量时间调查。相信我，调试可以是一项令人兴奋的挑战，但诊断时有时无的问题实在一点也不好玩。

 

我把这两个问题都交给了 Claude Opus 5.5。它很乐意着手逆向分析 jtagd，并轻松找出了这两个问题。在调查和测试第一个错误时，它一度碰到了网络安全护栏，但我注意到，与过去的版本相比，Opus 5.5 更擅长在触发护栏时尝试稍有不同的方法，也会给我机会改写提示，而不是立刻把我降级到 Opus 4.8（然后 Opus 4.8 可能又会触发类似的保护措施，导致会话结束）。这是一个非常受欢迎的改进。

 

总之，我想简单分享一下最终发现，并附上一个工具链接；如果这些错误一直让你烦不胜烦，可以用它来修补 jtagd。首先，这是修补工具的链接：[https://github.com/dougg3/altera-jtagd-linux-fixes](https://github.com/dougg3/altera-jtagd-linux-fixes)

 

导致 USB 流量损坏的第一个错误，最终被证实是`JTAG_SERVER_USB_BLASTER`构造函数中的一个变量未初始化。构造函数把附近的许多变量都设为了零，但这个变量显然被不小心漏掉了。如果它的值恰好大于 0，就会把一些仅供较新的 Altera USB-Blaster II 使用的数据额外插入发出的 USB 数据中，从而让旧款 USB Blaster 感到困惑。这完全解释了我在之前文章中提到的数据损坏。和 LLM 不同，我脑子里没有足够的背景信息，没能把“损坏的数据”与较新的 USB Blaster 协议联系起来。我见过的所有仿制设备都使用原版 USB Blaster 协议，因此无一幸免。它们最终会卡住 30 秒，随后出现`Unable to read device chain - JTAG chain broken`错误。

 

这似乎只会在 jtagd 仍在运行时拔下再重新插入 blaster 的情况下发生，因为第一次分配的内存往往总是被清零的。每次热插拔都会创建一个新的`JTAG_SERVER_USB_BLASTER`对象，并导致堆中的部分内存被重新使用。我 2024 年做的许多早期工作都涉及 Windows 虚拟机，因此我当时很可能频繁热插拔设备。这可能不是很多人都会遇到的问题，但它确实烦人得要命。

 

第二个导致 30 秒延迟的错误要隐蔽一些。它似乎取决于 blaster 使用哪种 FTDI FT245 系列芯片，甚至可能还与它连接到电脑的方式有关。问题的关键在于，jtagd 首次打开芯片时，会按以下顺序向 FT245 发送这些命令：

 

- - Reset
 
- - Purge TX
 
- - Purge RX
 
- - Set Latency Timer

 

这组特定的命令似乎会导致某些仿制设备在约 250 毫秒内忽略收到的数据。这通常不是什么大问题，但 jtagd 会立刻与它通信，以确认连接的 JTAG 链，随后便卡住并等待响应，最长达 30 秒。我有几款不同的 blaster 仿制品，它们对这组命令的反应各不相同（有些会受影响，有些不会），但这些都只是 FT245 命令。也许不同仿制品使用了不同修订版本的芯片？我只知道，把这组命令的顺序改成先执行 Set Latency Timer，就能彻底消除这个问题。

 

这两个问题在 jtagd 中至少从 Quartus 18.1 起就存在了，到 Quartus 25.1 仍然没有修复。Altera，如果你们看到了这篇文章，请考虑至少修复第一个错误！老实说，我不确定第二个问题到底算不算“错误”，也可能只是某些仿制设备的芯片行为与官方设备不完全一致，但在 Set Latency Timer 之后延迟 300 毫秒，或许就能解决问题。

 

修复这两个问题后，我能接触到的所有 USB Blaster 仿制品现在都运行良好（当然，也要先应用我之前对固件/CPLD 所做的修复）。我甚至使用了一个兼容[uhubctl](https://github.com/mvp/uhubctl)的 USB 集线器，来自动切换所有仿制设备的电源。这样我就能建立一个反馈循环，进行大量压力测试，认真验证修复确实有效。

 

回想起来，第一个错误我完全可以（也应该）自己找出来。valgrind 似乎会直接把问题摆在我面前。我有点失望，自己当时竟没想到试试它。当时我正用[rr](https://github.com/rr-debugger/rr)深入调查并尝试复现这个错误，但它与我的主力开发机不兼容。后来我在一台确实兼容 rr 的旧电脑上安装了 Quartus，却再也无法复现这个问题。那时我已经厌烦了所有这些折腾，于是放弃了。话说回来，这个错误在 jtagd 中至少存在了 8 年，而且基本上一直没人注意到，除了[Altera 论坛上的这篇小帖子，有人意识到情况有些古怪](https://community.altera.com/discussions/quartus-prime/quartus-jtagd-fails-and-unable-to-program-max10-under-linux-18-1-0-625/320842/replies/320850)，但基本上没人理会。

 

我的博客不会彻底变成一个“嘿，看看 AI 帮我做了什么”的展示。我想做的是与社区分享一个有用的变通方法，并希望引起 Altera 对这个长期存在的错误的关注，让他们修复它。另外，也许只是我比较奇怪，但用 AI 修复闭源软件里恼人的错误还挺有趣的，尤其是解决过去留下的、我原以为根本不可能收尾的问题。有鉴于此，这篇文章之后确实还会有一篇后续文章，我会在那里解决 USB Blaster 调查中遗留的最后一个未解问题。

 

AI 翻译；具体表述请与原文对照。
