USB DFUファームウェア更新失敗:ブートローダーモード、コントロール転送、タイムアウト、再接続のデバッグ
USB DFUファームウェア更新の失敗、ブートローダー検出、デバイス再接続、コントロール転送STALL、タイムアウト、ドライババインド、ファームウェアダウンロード失敗のトラブルシューティング方法を解説します。
ファームウェア更新の失敗はストレスフルです。デバイスがいなくなり、ブートローダーモードに入り、別のVID/PIDで再接続し、「initializing」「erasing」「downloading」「rebooting」のどこかで止まったように見える。USBの状態遷移をアップデータが正直に表示してくれることはまずないので、USB DFU failed、firmware update stuck initializing、USB bootloader not detected、DFU device not found、firmware update timeout で検索することになります。
USB Device Firmware Upgradeのワークフローは、通常、コントロール転送とデバイス状態遷移のうえに成り立っています。アップデータは通常のアプリファームウェアと通信し、ブートローダーへの再起動を指示し、別のUSBデバイスが列挙されるのを待ち、ファームウェアブロックを送信し、状態を要求し、最後にdetachまたはresetを指示します。
Bus Scopeが効くのは、各ステージがバス上でキャプチャ可能だからです。ただし最初から取得しておく必要があります。
ファームウェア更新は「2台のデバイス」と考えたほうがいい
多くの製品では、通常動作時に1つのUSBデバイスとして列挙され、ブートローダーモード時には別のデバイスとして列挙されます。VID/PID、プロダクト文字列、インターフェース、ドライババインドが変わることもあります。
シーケンス例:
- 通常デバイスが接続されている
- アップデータが「ブートローダーに入る」コマンドを送る
- デバイスが切断する
- ブートローダーデバイスが列挙される
- アップデータがDFUのダウンロードブロックを送る
- デバイスがステータスを返す
- デバイスが通常モードにリセットされる
デバイス消滅後にキャプチャを始めると、肝心の遷移はもう残っていません。
よくある失敗ポイント
DFU更新が失敗する場面:
- ブートローダーモードに入らない
- ブートローダーは列挙するがドライバがバインドされない
- アップデータがあるVID/PIDを期待しているがデバイスは別のものを出す
- コントロール転送がストールする
- ファームウェアのブロックサイズが間違っている
- 消去中にデバイスがタイムアウト
- ステータスポーリングが攻撃的すぎる
- ダウンロード中にデバイスが切断
- ケーブル/電源の問題でリセット
- セキュリティ/バージョン検査がイメージを拒否
アップデータはこれらをすべて「firmware update failed」と表示します。
コントロール転送の証拠
DFUクラスオペレーションはコントロール転送を使います。トレースを見れば、アップデータがダウンロードデータを送ったか、状態を要求したか、状態をクリアしたか、STALLに遭遇したかが分かります。
確認するキーワード:
DFU_DNLOADDFU_UPLOADDFU_GETSTATUSDFU_CLRSTATUSDFU_ABORT- デバイスリセット/切断
- エンドポイントゼロのSTALL
毎回同じブロックでコントロール転送がストールするなら、ファームウェアイメージ正当性、ブロックサイズ、フラッシュの消去/書き込み動作、ブートローダのバグが原因の可能性が高いです。
再接続のタイミング
ブートローダーモードに入ったあと、アップデータは再列挙を待つ必要があります。検索が早すぎると、実際には1秒後にブートローダーが現れるのに「device not found」と表示してしまいます。
バストレースは次のようなタイミングを示してくれます。
- 通常デバイスのデタッチ時刻
- ブートローダーのアタッチ時刻
- ディスクリプタ読み取り
- ドライババインド
- 最初のDFUリクエスト
この証拠があれば、「アップデータのタイムアウト」と「デバイス側の失敗」を切り分けられます。
ドライババインドの問題
Windowsでは、ブートローダーが通常デバイスと異なるドライバを要する場合があります。LinuxではVID/PIDごとに権限が異なることがあります。macOSではまた挙動が変わります。
ブートローダーが正しく列挙されてもアップデータがオープンできないなら、問題は「基本USB列挙」より上にあります。ブートローダーがそもそも列挙されないなら、ファームウェア/ケーブル/リセット/電源を先に疑ってください。
デバッグチェックリスト
次の流れで作業すると、原因に早くたどり着けます。
- アップデータ起動前にキャプチャを開始する
- 通常デバイスのディスクリプタを記録する
- ブートローダー入りコマンドをキャプチャする
- 切断とブートローダーの再列挙を観察する
- ブートローダーのVID/PIDとディスクリプタを記録する
- DFUコントロール転送を確認する
- 最初のSTALL/タイムアウト/リセット/無応答を探す
- 再現性がある場合、失敗ブロック番号を比較する
- 列挙後のドライババインドと権限を確認する
- トリミング前に更新タイムライン全体を保全する
最終的な診断
USB DFUの失敗は「状態遷移の失敗」です。根本原因は、ブートローダーへの遷移/再列挙/ドライババインド/DFUコントロール転送挙動/ブロックサイズ/フラッシュタイミング/イメージ検証/リセットタイミングのいずれかになり得ます。
Bus Scopeは、ファームウェア更新を「止まったプログレスバー」ではなく、USBの証拠として扱えるようにします。