InquirerRomualdez suspended for 90 daysPunchLagos market leaders pledge bloc votes for APC candidatesThe Jerusalem PostIDF dismantles four illegal West Bank outposts, arrests three Israelis after riotsDaily MaverickCongo’s Ebola cases surpass 11,000, government data show한겨레ESG기준원 “온실가스배출량 ‘스코프3’, 총배출량의 70% 차지”Bollywood HungamaRohit Shetty clarifies his social media presence after fake post about Gaurav Gupta’s Bigg Boss 20 roast goes viral: “My only official social media presence is on Instagram”CNN TürkHava Durumu (11-11-2026)ESPN CricinfoIPL 2027: MI and PBKS complete Hardik Pandya-Arshdeep Singh swapZDF heuteAktuelle Pressemitteilungen des ZDFLenta.ruМинобороны рассказало о срыве атаки ВСУNew Straits TimesHigh Court allows Azeez to challenge IRB's revocation of RM4.8mil tax dealColliderRocky’s Best Line Is Still the Greatest Quote in Franchise History
The Daily Newsstand · Free, Always
Wednesday, November 11, 2026

[Перевод] Почему клоны USB Blaster под Linux зависают на 30 секунд: две находки в jtagd из Quartus

Translate

Пару лет назад я слишком увлёкся разбором проблем с клонами Altera USB Blaster. Пока писал тот пост, я наткнулся на несколько очень раздражающих плавающих проблем с jtagd под Linux, и разобраться в них так и не смог. Вот что я тогда писал:

Ещё на одном из компьютеров я столкнулся с очень странной проблемой в Quartus Programmer 18.1 под Linux, никак не связанной с остальными. В захвате Wireshark было видно, что исходящий USB-трафик приходит уже испорченным, ещё до того, как в дело вступают FT245 или CPLD. Это касалось всех моих программаторов, а не только тех, что собраны на CPLD и FT245.

Иногда я всё ещё вижу долгую задержку (около 30 секунд) при первой JTAG-операции под Linux после подключения любого из моих USB Blaster на CPLD. Случается это не каждый раз, но когда случается, похоже, что jtagd зависает в ожидании байта, который так и не приходит. Он отваливается по таймауту и пробует снова, после чего всё работает нормально.

Я тогда и так вымотался со всеми остальными бедами USB Blaster, так что копать дальше эти мелкие, но назойливые проблемы мне совсем расхотелось, и я их бросил. До сих пор. С ИИ такие маленькие загадки можно закрывать, не тратя на расследование кучу времени. Поверьте, отладка бывает захватывающей задачей, но диагностировать плавающие проблемы совсем не весело.

Я скормил обе проблемы Claude Opus 5.5. Он охотно взялся за реверс-инжиниринг jtagd и без особого труда нашёл обе причины. В какой-то момент, пока он исследовал и проверял первый баг, он начал упираться в защитные ограничения по кибербезопасности. Но я заметил, что Opus 5.5 чуть лучше прежних версий справляется с такими ситуациями: пробует слегка другой подход, когда срабатывает ограничение, и даже даёт мне шанс переформулировать запрос. Раньше меня в таких случаях сразу понижало до Opus 4.8, а тот потом мог и вовсе завершить сессию, наткнувшись на похожее ограничение. Это очень приятное улучшение.

В общем, я решил коротко поделиться тем, что в итоге нашлось, и заодно дать ссылку на инструмент, которым можно пропатчить свой jtagd, если эти баги вас тоже сводили с ума. Сначала ссылка на патчер: https://github.com/dougg3/altera-jtagd-linux-fixes

Баг первый: забытая переменная в конструкторе

Первый баг, который портит USB-трафик, оказался неинициализированной переменной в конструкторе JTAG_SERVER_USB_BLASTER. Конструктор обнуляет целую пачку соседних переменных, а эту, видимо, случайно забыли. Если в ней случайно оказывается значение больше 0, в исходящие USB-данные вставляются дополнительные данные, предназначенные только для более нового USB-Blaster II от Altera, и это сбивает с толку старые USB Blaster. Это прекрасно объясняет порчу данных, о которой я писал в прошлом посте. В отличие от языковой модели, у меня в голове не было достаточно контекста, чтобы связать «испорченные данные» с протоколом нового USB Blaster. Все клоны, которые я видел, говорят на протоколе оригинального USB Blaster, так что затронуты они все. В итоге они зависают на 30 секунд, после чего выдают ошибку Unable to read device chain - JTAG chain broken.

Похоже, это происходит, только если отключить и снова подключить программатор, не останавливая jtagd: первая выделенная область памяти, как правило, оказывается обнулённой. При каждом горячем подключении создаётся новый объект JTAG_SERVER_USB_BLASTER, а куски кучи используются повторно. В 2024 году я много работал через виртуальную машину с Windows, так что, скорее всего, действительно часто переподключал устройство. Может, мало кто с этим сталкивается, но меня это бесило страшно.

Баг второй: порядок команд для FT245

Второй баг, с задержкой в 30 секунд, хитрее. Похоже, он зависит от того, какой чип серии FTDI FT245 стоит в вашем программаторе, а может, даже от того, как он подключён к компьютеру. Суть в том, что при первом открытии чипа jtagd отправляет FT245 такие команды, именно в этом порядке:

  • Reset

  • Purge TX

  • Purge RX

  • Set Latency Timer

Похоже, эта последовательность заставляет некоторые клоны примерно на 250 мс перестать принимать входящие данные. Обычно в этом не было бы большой беды, но jtagd сразу же начинает опрашивать устройство, чтобы выяснить, что подключено к JTAG-цепочке, и застревает на 30 секунд в ожидании ответа. Разные мои клоны реагируют на эту последовательность каждый по-своему (одних она задевает, других нет), хотя это всего лишь команды FT245. Может, у разных клонов разные ревизии чипа? Знаю одно: если переставить команды так, чтобы Set Latency Timer шла первой, проблема полностью исчезает.

Что в итоге

Обе проблемы живут в jtagd как минимум с Quartus 18.1 и никуда не делись в Quartus 25.1. Altera, если вы читаете этот пост, пожалуйста, подумайте о том, чтобы исправить хотя бы первый баг! Насчёт второго я, честно говоря, не уверен, баг ли это вообще или просто в некоторых клонах стоят чипы, которые ведут себя не совсем так, как в официальном устройстве. Но задержка в 300 мс после Set Latency Timer, вероятно, тоже решила бы проблему.

С исправлениями обеих проблем все клоны USB Blaster, до которых я могу дотянуться, теперь работают отлично (конечно, после моих прежних исправлений прошивки и CPLD). Я даже взял USB-хаб, совместимый с uhubctl, чтобы автоматически передёргивать питание всех моих клонов. Так у меня получился цикл обратной связи для серии стресс-тестов, которыми я как следует проверил, что исправление действительно работает.

Оглядываясь назад, первый баг я вполне мог (и должен был) найти сам. Похоже, valgrind просто преподнёс бы мне его на блюдечке. Немного досадно, что я не догадался его попробовать. Тогда я по уши ушёл в расследование с rr, пытаясь воспроизвести баг, но rr не работал на моей основной машине для разработки. А когда я поставил Quartus на старый компьютер, с которым rr был совместим, воспроизвести проблему уже не получалось. К тому моменту мне всё это осточертело, и я сдался. В своё оправдание скажу: этот баг сидит в jtagd как минимум 8 лет и почти никем не был замечен, если не считать одного короткого сообщения на форуме Altera, где человек понял, что происходит что-то странное, и его в общем-то проигнорировали.

Мой блог не превращается целиком в витрину «смотрите, что ИИ для меня сделал». Я хочу поделиться с сообществом полезным обходным решением и, надеюсь, привлечь внимание Altera, чтобы она наконец исправила давний баг. А ещё, может, я просто чокнутый, но чинить надоедливые баги в закрытом софте с помощью ИИ довольно весело. Особенно когда это старый хвост из прошлого, который я считал непрактичным закрывать. Кстати, у этого поста будет продолжение: в нём я отвечу на последний оставшийся без ответа вопрос из моих прошлых раскопок с USB Blaster.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.