背景
ARM-USB-TINY-HというOlimex社のArm用JTAGデバッガとOpenOCDを使ってJTAGのお勉強を始めたところ一番最初にはまった問題
ここでは問題解決ではなく回避策としてその内容を記載
解決方法
以下のいずれかで解消
- USBケーブルを抜き差しする
- コマンドによるunbind,bindによりUSB再接続する
- usb_modeswitch によりUSBリセット
エラー内容
Warn : Haven't made progress in mpsse_flush() for 2145ms.
Warn : Haven't made progress in mpsse_flush() for 4185ms.
Warn : Haven't made progress in mpsse_flush() for 8010ms.
Warn : Haven't made progress in mpsse_flush() for 16169ms.
Warn : Haven't made progress in mpsse_flush() for 32233ms.
Warn : Haven't made progress in mpsse_flush() for 64106ms.
Warn : Haven't made progress in mpsse_flush() for 128106ms.
Warn : Haven't made progress in mpsse_flush() for 256107ms.
こんな感じ。
JTAG(自分の場合, ARM-USB-TINY-H)に接続したUSBを抜き差しすることで解決したことがあった。
USBのなんらかの接触なのだろうと思い、深追いせず。
しかし、また再現。
どうやら同じ様な問題に遭遇した人もいた。ただこの人はversion 0.10の時に発生していたが、根本には解決しなかった模様。(v0.11では発生したとは書かれていない)
https://qiita.com/hro/items/dc0f8b806e2f4137772f#openocd-010
だが、自分の場合、どちらのバージョンでも再現してしまう。
さて。
mpsse_flush() のエラーログに関するcommitログはこちら。
Add wall clock timeout warning to mpsse_flush()
I think that libusb_handle_events_timeout_completed is supposed to make progress or time out, but sometimes we hit a case where it makes no progress, and mpsse_flush() loops forever. This wall clock timeout notifies the user that this is going on.
When I wrote this code, this bug would reproduce every hour or two, but right now it's not happening for me.
(推測だが)USBからのイベントが返ってこずループに陥ってしまった際に適切に警告メッセージを出すようにしたとのこと(と解釈。)
発生原因は不明だが、USBケーブルの抜き差しにより解決した理屈も納得(?)
ということで、本現象が起きてしまったらUSBを一度抜き、再接続することで回避できそう。
解決1: USBの抜き差しを行う
でも毎回抜き差しするのは面倒。
そもそもなぜこの問題が発生するのか、その理由は不明。気が付いたら再発という始末。
最近はリモート環境が当たり前になり手元に機材が置いてないことも標準なので簡単に抜き差しできるとは限らない。
それだけでなくUSB抜き差しを繰り返すことによる劣化も避けたいところ。
コマンドでUSBの抜き差しする方法があればと思って探したところ、linuxであればbind/unbindにより可能とわかった。
コマンドで USB をリセットしてみる
これでも十分なんだが接続しているusbポート番号を確認して正しく指定しなければならず、誤って異なる番号を使ってしまうリスクを考えるとあまり好きではない。(絶対ミスする気がしてならない)
usb_modeswitchというコマンドがあった!!
/sys/bus/usb/drivers/usb/bind (or unbind)によるUSBのリセットも可能だけど他の方法はないかと探してたところ、同じページにおまけとして「コマンドで USB をリセットしてみる(usb_modeswitch編)」というのがあった。
前置き長くなったけどこれが一番簡単でミスも少なく安全なのでオススメ
USBのベンダー番号、プロダクト番号を確認
おなじみlsusbを使って、ベンダー番号/プロダクト番号を確認。
$ lsusb | grep ARM-USB
Bus 003 Device 089: ID 15ba:002a Olimex Ltd. ARM-USB-TINY-H JTAG interface
今回の場合、ベンダーIDは0x15ba, プロダクト番号は0x002aとなる。16進数なのでご注意。
$ usb_modeswitch -v 0x15ba -p 0x002a --reset-usb
Look for default devices ...
Found devices in default mode (1)
Access device 089 on bus 003
Get the current device configuration ...
Current configuration number is 1
Use interface number 0
with class 255
Warning: no switching method given. See documentation
Reset USB device .
Device was reset
-> Run lsusb to note any changes. Bye!
解決2: usb_modeswitch実行によりUSB接続のリセットを行う