Repository navigation
USB_DFU
- AVR DU 系列の USB 周辺機能実装
- USB 2.0 制御エニュメレーション
- USB 記述子
- USBクラス別詳細
- DFU は、USB協会で規約書が公開されている公式規格。規約書には Intel/Microsoft/Atmel/STM らが名を連ねている。(が、Microchip は含まれていない)
- 読んで字のごとく、装置の起動プログラムを書き換えるための、ネイティブUSB実装型組込機器用ブートストラップローダー実装規約。
- DFU 1.0 は、1999年以前に規定されたが、その複雑さに反して色々機能不足があったため、各社はベンダー固有実装で拡張している。
- 基本的には Flash 領域を先頭から書き換えるか、全部を読み出す機能しか既定されていない。(その割には細部が偏執的に煩い)
- 対象装置固有情報を応用記述から読み出す仕組みがない。このため VID:PID ペアと製品型番を 1対1で対応する必要が生じた。
- ST Microsystems の実装は "DfuSe" DFU with ST Microsystems extensions として知られている。"STM32CubeProgrammer" や "dfu-util" が対応している。
- STM32 や ESP32 等は ブートローダーを ROMとして持ち、通常プロセッサとは別のコプロセッサで走行する構造が多い。自ずと一般メモリ単位部も 最大2種類かつ全面書換なので、DFU規約をほとんどそのまま踏襲できる。
- Atmelは(DFU File Suffix を含む)DFU規約準拠の仕様も公開しつつ、別種の DFU仕様として "FLIP" という実装を開発した。EP0だけを使うという実現概念は似ているが USBクラス宣言段階からして互換性はない。
- DFU 1.1 は、2004年8月5日に公開、同31日に多少修正された。"DFU File Suffix" 拡張が "付録B" に記載されているが、付録なのでオプションに過ぎない。
- "DFU Mode" での装置記述子の内容や、インターフェース番号等は、規約書で固定的に決め打ちされている。
- ここでは、一般応用記述が走行する動作は "Run-Time" 動作という。この状態から "DFU Mode" 動作へ遷移する方法も、規約で決められている。(オプション対応)
以下に DFU規約のあらましを長々と記載するが、AVR からの視点では、これでも抜本的なところで 適切な(望みうる)機能が足りていなかったり、不明瞭だったりする。
DFU装置は、4種類の実行段階(Phase)を持つ。
- Enumeration Phase(列挙段階)
- USB規約準拠装置として ホストOSドライバに適切な記述子セットを通知する。
- 列挙段階を終えると、装置の Firmware(応用記述)は "Run-Time"通常動作か、"DFU Mode"対応動作のいずれかで走行開始する。
- Reconfiguration Phase(再構成段階)
- "Run-Time"通常動作から "DFU Mode"対応動作へ、あるいはその逆に 装置を再構成し、実行状態を切り替える。
- Transfer Phase(転送段階)
- Firmware イメージを 装置から "Upload"、 あるいは装置に "Download" する動作を実行する。
- Manifestation Phase(具現化段階)
- 装置の Firmware イメージ全体が、健全に構成されているかを検証し、"Run-Time"動作に遷移可能か否かを報告する動作。
DFU装置は、2種類の 記述子構成セットを持つことができる。
- Run-Time Descriptor Set
- 本来の "HID" や "Mass-Storage" 装置を構成する記述子に対し、"DFU Mode" へソフトウェア制御で遷移可能とするための、"Run-Time" 用の記述子を 任意で 追加することができる。
- DFU Mode Descriptor Set
- "DFU Mode" 動作時の記述子構成セット。装置記述子段階から完全に切り替わる。
文中の "ダウンロード" は ホストから装置へ、”アップロード" は 装置からホストへの Firmware イメージ転送方向を表す。
Translation of terms
- Command - 命令
- Configuration - 構成
- Descriptor - 記述子
- Device - 装置
- Enumeration - 列挙
- Functional - 機能
- General - 全般(一般)
- Host - ホスト
- Interface - 界面
- Manifest(ation) - 具現化
- Phase - 段階
- Request - 要求
- Request (order) - 指令(注文)
- State - 状態
- Status - 状況
USB 標準動作の 記述子列挙段階。
ホスト側から "Run-Time" 動作へ遷移可能にする記述子セット。ジャンパーピンや DIPスイッチ等の ハードウェア指定でのみ動作を切り替える設計であるなら、存在しなくても良い。
DFU を支援する各 標準構成記述子の bNumInterfaces項は、"Run-Time DFU Interface" の追加に対応するため、本来より 1つ増加するだろう。
この記述子は、"Runtime protocol" を処理するインターフェースを宣言する。"全般構成記述子" 要求応答の「最後」に含める。
- 実際には使われる可能性がないにも関わらず、この記述は ホストOSに、DFUドライバーの読み込みを強制するかもしれない。
| Ofs | Size | Field | Value | Description |
|---|---|---|---|---|
| 0 | 1 | bLength | 0x09 | 記述子全体長 |
| 1 | 1 | bDescriptorType | 0x04 | INTERFACE descriptor type. |
| 2 | 1 | bInterfaceNumber | 数値 | このIFを特定する指標番号(任意) |
| 3 | 1 | bAlternateSetting | 0x00 | 代替IF番号 |
| 4 | 1 | bNumEndpoints | 0x00 | このIFで使用されるエンドポイント数(なし) |
| 5 | 1 | bInterfaceClass | 0xFE | Application Specific Class Code. |
| 6 | 1 | bInterfaceSubClass | 0x01 | Device Firmware Upgrade Code. |
| 7 | 1 | bInterfaceProtocol | 0x01 | Runtime protocol. |
| 8 | 1 | iInterface | Index | String Descriptor Index. |
この機能記述子は、前述の "Run-Time DFU Interface Descriptor" に続けて記述する。自ずから "全般構成記述子" 要求応答に含まれる。
| Ofs | Size | Field | Value | Description |
|---|---|---|---|---|
| 0 | 1 | bLength | 0x09 | 記述子全体長 |
| 1 | 1 | bDescriptorType | 0x21 | DFU FUNCTIONAL descriptor type. |
| 2 | 1 | bmAttributes | Bitmap | DFU Attributes. |
| 3 | 2 | wDetachTimeOut | Number | DFU_DETACH 要求後の最大待機時間(ms) |
| 5 | 2 | wTransferSize | Number | 1回の制御転送で受容できる最大イメージバイト数 |
| 7 | 2 | bcdDFUVersion | BCD | DFU版番号(0x0100 あるいは 0x0101) |
| Bit | bmAttributes Field | Description |
|---|---|---|
| 7-4 | (予約) | |
| 3 | bitWillDetach | (DFU_DETACH) |
| 2 | bitManifestationTolerant | (DFU_GETSTATUS) |
| 1 | bitCanUpload | (DFU_UPLOAD) |
| 0 | bitCanDnload | (DFU_DNLOAD) |
装置の動作が "DFU Mode" に切り替わったことを示す記述子セット。
標準装置記述子 要求
| Device Request | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
|---|---|---|---|---|---|---|
| GET_DESCRIPTOR | 1 00 00000 | 0x06 | 0x0100 | 0 | * | 応答内容 |
DFU動作 装置記述子 応答内容
三つ組のクラス記述子は全てゼロ、構成定義数 は必ず 1とする。
| Ofs | Size | Field | Value | Description |
|---|---|---|---|---|
| 0 | 1 | bLength | 0x12 | 記述子全体長 |
| 1 | 1 | bDescriptorType | 0x01 | DEVICE descriptor type. |
| 2 | 2 | bcdUSB | 0x0100 | USB版番号(BCD) |
| 4 | 1 | bDeviceClass | 0x00 | See interface Descriptor. |
| 5 | 1 | bDeviceSubClass | 0x00 | See interface Descriptor. |
| 6 | 1 | bDeviceProtocol | 0x00 | See interface Descriptor. |
| 7 | 1 | bMaxPacketSize0 | 8,16,32,64 | エンドポイント0 のパケット最大長 |
| 8 | 2 | idVendor | ID | Vendor ID |
| 10 | 2 | idProduct | ID | Product ID |
| 12 | 2 | bcdDevice | BCD | 装置版番号 |
| 14 | 1 | iManufacturer | Index | String Descriptor Index. |
| 15 | 1 | iProduct | Index | String Descriptor Index. |
| 16 | 1 | iSerialNumber | Index | String Descriptor Index. |
| 17 | 1 | bNumConfigurations | 0x01 | 構成定義数(必ず 1) |
標準構成記述子 要求
| Device Request | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
|---|---|---|---|---|---|---|
| GET_DESCRIPTOR | 1 00 00000 | 0x06 | 0x0200 | 0 | * | 応答内容 |
DFU動作 構成記述子 応答内容
インターフェース数 は必ず 1とする。
| Ofs | Size | Field | Value | Description |
|---|---|---|---|---|
| 0 | 1 | bLength | 0x09 | 記述子全体長 |
| 1 | 1 | bDescriptorType | 0x02 | CONFIGURATION descriptor type. |
| 2 | 2 | wTotalLength | 数値 | この構成に含まれる "全般構成記述子" の総バイト数 |
| 4 | 1 | bNumInterfaces | 0x01 | この構成に含まれるインターフェース数(必ず 1) |
| 5 | 1 | bConfigurationValue | 数値 | この構成を特定する指標番号 |
| 6 | 1 | iConfiguration | Index | String Descriptor Index. |
| 7 | 1 | bmAttributes | Bitmap | この装置の電力管理構成 |
| 8 | 1 | bMaxPower | 数値 | 2mA単位の最大要求電流 |
標準 インターフェース記述子 要求
| Device Request | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
|---|---|---|---|---|---|---|
| GET_DESCRIPTOR | 1 00 00000 | 0x06 | 0x0400 | 0 | wTotalLength | 応答内容 |
DFU動作 インターフェース記述子 応答
"DFU protocol" を処理するインターフェースを定義する記述子。"全般構成記述子" 要求で読み出される。
| Ofs | Size | Field | Value | Description |
|---|---|---|---|---|
| 0 | 1 | bLength | 0x09 | 記述子全体長 |
| 1 | 1 | bDescriptorType | 0x04 | INTERFACE descriptor type. |
| 2 | 1 | bInterfaceNumber | 0x00 | このIFを特定する指標番号(必ず 0x00) |
| 3 | 1 | bAlternateSetting | Number | 代替IF番号 |
| 4 | 1 | bNumEndpoints | 0x00 | このIFで使用されるエンドポイント数(なし) |
| 5 | 1 | bInterfaceClass | 0xFE | Application Specific Class Code. |
| 6 | 1 | bInterfaceSubClass | 0x01 | Device Firmware Upgrade Code. |
| 7 | 1 | bInterfaceProtocol | 0x02 | DFU mode protocol. |
| 8 | 1 | iInterface | Index | String Descriptor Index. |
- 代替設定は、EEPROM等の追加のメモリセグメントに対応するために使用できる。この時の各代替設定の
iInterfaceは、EEPROMといった固有の文字列を返答することが推奨される。 - 代替設定の具体的な動作は DFU 規約の範囲外で、完全に実装者(ベンダー)の裁量に任されている。
この機能記述子は、前述の "DFU Mode Interface Descriptor" に続けて配置する。"全般構成記述子" 要求で読み出される。
- 記述詳細は "Run-Time DFU Functional Descriptor" と同一。
ホストは、制御エンドポイントEP0 を通して、以下の 固有要求/指令を装置に発行する。
DFUクラス(インターフェース)要求 一覧
| Class-Specific Request | Protocol | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
|---|---|---|---|---|---|---|---|
| DFU_DETACH | 1 | 0 01 00001 | 0x00 | wTimeout | IF番号 | 0 | - |
| DFU_DNLOAD | 2 | 0 01 00001 | 0x01 | wBlockNum | IF番号 | * | Firmware |
| DFU_UPLOAD | 2 | 1 01 00001 | 0x02 | wBlockNum | IF番号 | * | Firmware |
| DFU_GETSTATUS | 1* , 2 | 1 01 00001 | 0x03 | 0 | IF番号 | 6 | Status |
| DFU_CLRSTATUS | 2 | 0 01 00001 | 0x04 | 0 | IF番号 | 0 | - |
| DFU_GETSTATE | 1* , 2 | 1 01 00001 | 0x05 | 0 | IF番号 | 1 | State |
| DFU_ABORT | 2 | 0 01 00001 | 0x06 | 0 | IF番号 | 0 | - |
- Run-Time Protocol
- DFU Mode Protocol
-
*の対応は実装により自由
"Run-Time" 動作中の、再設定段階。
| Class-Specific Request | Protocol | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
|---|---|---|---|---|---|---|---|
| DFU_DETACH | Run-Time | 0 01 00001 | 0x00 | wTimeout | IF番号 | 0 | - |
この DFU_DETACH 要求は "Run-Time" 動作 にて有効。
- 機能記述子の
bmAttributesのbitWillDetachがセットされている場合、装置は USBバスの Detach-Atach 動作を実行する。この間ホストは USB Reset を実行してはならず、装置は "Run-Time" 動作は継続する。 - それ以外の場合は
wDetachTimeOutで指定されたミリ秒時間、USBバスを監視して;- USB Reset信号を検出したら "DFU Mode" 動作に遷移する。つまり次の標準装置要求に "DFU Mode Descriptor Set" で応答する。
- USBバス監視が タイムアウトに達したら、"Run-Time" 動作を継続する。
-
wTimeoutがwDetachTimeOutより小さい場合、それを USBバス監視時間(ミリ秒)とする。
"DFU Mode" 動作中の、Firmware イメージ転送段階。
Firmware イメージは、DFU_DNLOAD 指令によって 装置に "ダウンロード" できる。
| Class-Specific Request | Protocol | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
|---|---|---|---|---|---|---|---|
| DFU_DNLOAD | DFU Mode | 0 01 00001 | 0x01 | wBlockNum | IF番号 | * | Firmware |
- 装置は、機能記述子の
wTransferSize項で、1転送毎のペイロード最大バイト数を指定できる。ホストはこれを見て転送作業バッファをmallocするだろう。装置が受容できるメモリ単位部ページ量目以上を許されるのが普通。 - ホストは制御転送を用いて
bMaxPacketSize0からwLengthバイトの範囲のデータを装置に送る。 - ダウンロードされた各ブロックの送信後、ホストは DFU_GETSTATUS要求で装置の状態(メモリ書込結果)を確認する。
- 重要:Firmware イメージの内容には一切言及していない。故にベンダー実装依存でローカルな実装プロトコルをこの中に構築しうる。(Atmel はそうした)
最後の Firmware 転送ブロックが装置に送信され、状態が要求された後、ホストは wLength項を 0にクリアした DFU_DNLOAD指令を送信し、ふたたび DFU_GETSTATUS を要求する。装置が準備完了でエラーがないのであれば、転送段階は完了し、具現化段階が開始される。
ただし一部の装置は、Firmware イメージ全体を 揮発性メモリにバッファリングし、dfuMANIFEST 状態中に 不揮発性メモリへ書き込む動作をする場合がありうる。よって具現化段階において、一部の装置は再プログラミング処理中に USB経由での通信ができなくなる可能性がある。
-
bmAttributes項のbitManifestationTolerantビットをクリアすることで、ホストにこの状態を通知し、具現化段階中に ホストが 装置にパケットを送信しないように設定できる。
-
wLength項は、USB版番号1.0規約に基づいて、この 1ブロック転送における合計バイト数を示す。この値はwTransferSize項で指定された値を超えてはならない。 -
wLength項が 0であるなら、それは Firmware イメージ転送が終了したことを示す、最後のブロックである。 -
wBlockNum項はブロック指定番号である。1ブロックが転送されるたびに増分され、65535から 0にラップアラウンドする。これは装置内の DFUローダーに 有用なコンテキストを提供するために使用される。
この要求を、ホストは装置との状態同期を取るために使用する。"Run-Time"動作での支援は実装により自由。
| Class-Specific Request | Protocol | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
|---|---|---|---|---|---|---|---|
| DFU_GETSTATUS | * | 1 01 00001 | 0x03 | 0 | IF番号 | 6 | Status |
Status で応答すべき 6バイトの内容
| Ofs | Size | Status Field | Value | Description |
|---|---|---|---|---|
| 0 | 1 | bStatus | 数値 | 最新の要求/指令結果を示す状況値 |
| 1 | 3 | bwPollTimeout | 数値 | ホストが次回の DFU_GETSTATUS を送信するまでの禁止時間 |
| 4 | 1 | bState | 数値 | この応答送信後に装置が移行する状態値(または現在値) |
| 5 | 1 | iString | Index | String Descriptor Index. |
-
bwPollTimeoutを用いることで、ホストの USBパケット送信を抑制できる。この値は メモリ消去や、書き込みに要する時間によって異なるだろう。 -
iStringは、状態を表記するために装置側の持つ STRING 標準要求文字列テーブル の指標番号を意図しているが、ホスト側の独自の文字列テーブルを参照しても構わない。(0とすれば装置側は常に参照されない)
DFUローダーが独自のエラー表示文字列を自己定義するのは、相当贅沢な実装である。
bStatus 状況値と意図
| bStatus | Value | Suggested String |
|---|---|---|
| OK | 0x00 | エラーなし |
| errTARGET | 0x01 | このファイルは、この装置での使用対象ではない |
| errFILE | 0x02 | このファイルは、この装置用だが、ベンダー固有検証試験に失敗した |
| errWRITE | 0x03 | 装置がメモリに書き込むことができない |
| errERASE | 0x04 | メモリ消去機能が失敗した |
| errCHECK_ERASED | 0x05 | メモリ消去確認が失敗した |
| errPROG | 0x06 | メモリプログラム機能が失敗した |
| errVERIFY | 0x07 | プログラムされたメモリの検証に失敗した |
| errADDRESS | 0x08 | 受信したアドレスが範囲外のため、メモリをプログラムできない |
| errNOTDONE | 0x09 |
wLength = 0 の DFU_DNLOAD を受信したが、装置はまだ全データを取得していない |
| errFIRMWARE | 0x0A | 装置の Firmwareが破損している。実行時("DFU Mode"以外)の動作に戻ることができない |
| errVENDOR | 0x0B |
iStringはベンダー固有エラー説明を示している |
| errUSBR | 0x0C | 装置が予期しない USB Reset信号を検出した |
| errPOR | 0x0D | 装置が予期しない 電源投入Resetを検出した |
| errUNKNOWN | 0x0E | 何らかの問題が発生したが、装置はその原因を特定でない |
| errSTALLEDPKT | 0x0F | 装置が予期しない要求で停止した |
- 装置によっては返しようのない状況報告もある。例えば(DFU処理部と NVM書込器が物理的に別モジュールになっている)SoC構成のようなものではない、単一の USB周辺機能内蔵 MCU装置の場合、
0x0C以降を実装するには不揮発性ではないメモリ領域に、検査状況等を保持していないと困難だろう。 - 装置は、OK 状況を報告したら dfuIDLE 状態になり、次の要求/指令を待機する。そうでない非自明の状況では dfuERROR 状態になり、DFU_CLRSTATUS 指令を受領するまで、状況も状態も変化しなくなる。
- 例えば "Blank Check" 要求での "errCHECK_ERASED" 状況は十分自明なので、次の状態は dfuIDLE である。
- メモリ読み出し不可を示す状況は定義されていない。これは装置がセキュリティ強化中の場合一般に起こりうる。そのような未定義エラーは多くの場合、"errADDRESS" か "errVENDOR" 状況で代替されるだろう。(状態遷移崎は "dfuIDLE" か "dfuERROR" のいずれか)
bState 状態値と意図
| bState | Value | Meaning |
|---|---|---|
| appIDLE | 0 | 装置は通常のアプリケーションを実行中。("Run-Time") |
| appDETACH | 1 | 装置は通常のアプリケーションを実行中("Run-Time")で、DFU_DETACH 要求を受信し、USB リセットを待機中。 |
| dfuIDLE | 2 | 装置は "DFU Mode"で動作しており、任意の要求/指令を待機中。 |
| dfuDNLOAD-SYNC | 3 | 装置は Firmware ブロックを受信し、ホストが DFU_GETSTATUS を介して状況報告を要求するのを待機中。 |
| dfuDNBUSY | 4 | 装置は、Firmware ブロックを不揮発性メモリに書き込み中 |
| dfuDNLOAD-IDLE | 5 | 装置はダウンロード操作を処理している。さらなる DFU_DNLOAD 指令を待機中。 |
| dfuMANIFEST-SYNC | 6 | 装置はホストから Firmware の最終ブロックを受信し、具現化段階を開始するために DFU_GETSTATUS の受信を待機中。 または装置は具現化段階を完了し、DFU_GETSTATUS の受信を待機中。 (具現化段階後にこの状態に移行できる装置は、 bmAttributes と bitManifestationTolerant を 共に 1に設定) |
| dfuMANIFEST | 7 | 装置は具現化段階中。(この状態にあるすべての装置が DFU_GETSTATUS に応答できるとは限らない) |
| dfuMANIFEST-WAIT-RESET | 8 | 装置はメモリをプログラムし、USBリセットまたは電源投入リセットを待っている。 (この状態に移行する必要がある装置は、 bitManifestationTolerant を 0に設定) |
| dfuUPLOAD-IDLE | 9 | 装置は アップロード操作を処理中。DFU_UPLOAD 要求を待っている。 |
| dfuERROR | 10 | エラーが発生中。DFU_CLRSTATUS 指令の受信を待機中。 |
可能な状況/状態遷移
| Before bState | Requests | After bState | Comment |
|---|---|---|---|
| 0:appIDLE | DFU_DETACH | 1:appDETACH | |
| 1:appDETACH | (Detach Timeout) | 0:appIDLE | (wDetachTimeOut) |
| (USB Reset) | 2:dfuIDLE | ||
| 2:dfuIDLE | DFU_DNLOAD | 3:dfuDNLOAD-SYNC | wLength>0,bitCanDnload=1 |
| DFU_UPLOAD | 9:dfuUPLOAD-IDLE | bitCanUpload=1 | |
| 3:dfuDNLOAD-SYNC | DFU_GETSTATUS | 4:dfuDNBUSY | block in progress |
| DFU_GETSTATUS | 5:dfuDNLOAD-IDLE | block complete | |
| 4:dfuDNBUSY | (Status Poll Timeout) | 3:dfuDNLOAD-SYNC | |
| 5:dfuDNLOAD-IDLE | DFU_DNLOAD | 3:dfuDNLOAD-SYNC | wLength>0 |
| DFU_DNLOAD | 6:dfuMANIFEST-SYNC | wLength=0 | |
| 6:dfuMANIFEST-SYNC | DFU_GETSTATUS | 2:dfuIDLE | manifestation complete, and bitManifestationTolerant=1 |
| DFU_GETSTATUS | 7:dfuMANIFEST | manifestation in progress | |
| 7:dfuMANIFEST | (Status Poll Timeout) | 6:dfuMANIFEST-SYNC | bitManifestationTolerant=1 |
| (Status Poll Timeout) | 8:dfuMANIFEST-WAIT-RESET | bitManifestationTolerant=0 | |
| 9:dfuUPLOAD-IDLE | DFU_UPLOAD | No transition | Progress |
| DFU_UPLOAD | 2:dfuIDLE | Short Frame | |
| 10:dfuERROR | DFU_CLRSTATUS | 2:dfuIDLE | |
| State 2,3,5,6,9 | DFU_ABORT | 2:dfuIDLE | |
| State 0,1,2,3,5,6,9,10 | DFU_GETSTATE | No transition | |
| State 0,1,2,5,9,10 | DFU_GETSTATUS | No transition |
- dfuERROR 状態は、DFU_CLRSTATUS 指令を受けるまで、dfuERROR 状態を維持しつづける。
この指令は、装置の "dfuERROR" 状態を解消して "dfuIDLE" 状態に遷移する。装置は "OK" 状況を設定する。
| Class-Specific Request | Protocol | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
|---|---|---|---|---|---|---|---|
| DFU_CLRSTATUS | DFU Mode | 0 01 00001 | 0x04 | 0 | IF番号 | 0 | - |
この指令は、装置の("dfuERROR"を除く)任意の bStatus状態を中断し、"dfuIDLE" 状態に遷移する。装置は "OK" 状況を設定する。
| Class-Specific Request | Protocol | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
|---|---|---|---|---|---|---|---|
| DFU_ABORT | DFU Mode | 0 01 00001 | 0x06 | 0 | IF番号 | 0 | - |
| Class-Specific Request | Protocol | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
|---|---|---|---|---|---|---|---|
| DFU_GETSTATE | * | 1 01 00001 | 0x05 | 0 | IF番号 | 1 | bState |
この要求は、ホストから装置の現在の bState状態値を求める。"Run-Time"動作での支援は実装により自由。
State で応答すべき 1バイトの内容
| Ofs | Size | State Field | Value | Description |
|---|---|---|---|---|
| 0 | 1 | bState | 数値 | 現在の状態値 |
Firmware イメージは、DFU_UPLOAD 要求によって 装置から "アップロード" できる。装置の状態は "dfuIDLE" から "dfuUPLOAD" に遷移する。
| Class-Specific Request | Protocol | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
|---|---|---|---|---|---|---|---|
| DFU_UPLOAD | DFU Mode | 1 01 00001 | 0x02 | wBlockNum | IF番号 | * | Firmware |
- 重要:Firmware イメージの内容には一切言及していない。故にベンダー実装依存でローカルな実装プロトコルをこの中に構築しうる。
-
wBlockNum項はペイロードブロック指定番号である。0 から始まり、1個のペイロードが転送されるたびに増分され、65535から 0にラップアラウンドする。これはホストに 有用なコンテキストを提供するために使用される。新たな命令群を始めるたびに、0 から再カウントされる。 -
wLength項は、転送するペイロードのバイト数を示す。この値はwTransferSize項で指定された値を超えてはならない。
長さゼロの DFU_DNLOAD 要求によって転送段階が終了すると、装置は新しい Firmware を具現化する準備が整う。(前述のとおり)一部の装置は Firmware イメージを蓄積し、再プログラミング操作全体を一度に実行するかもしれない。再プログラミングが必要なデータが少量しか残っていない装置もあれば、再プログラミングが全く必要ない装置もありうるだろう。いずれの場合も装置は dfuMANIFEST-SYNC 状態に遷移し、ホストからの状況報告の要求を待つ。期待された DFU_GETSTATUS を獲得すると、装置は dfuMANIFEST 状態に遷移し、再プログラミング操作を完了する。
再プログラミングが正常に完了すると、装置は USB経由で通信可能か否かに応じて、dfuMANIFEST-SYNC または dfuMANIFEST-WAIT-RESET のいずれかの状態に遷移する。ホストは bmAttributesビットの bitManifestationTolerantによって、装置がどの状態に遷移するかを認識できなければならない。
- 装置が dfuMANIFEST-SYNC (
bitMainfestationTolerant=1) 状態になると、ホストは DFU_GETSTATUS 要求を発行し、装置は dfuIDLE 状態に遷移する。この時点でホストは別のダウンロードを実行したり、アップロードを要求したり、USB Reset を発行して装置を "Run-Time" 段階に戻ることができる。
一方で装置が dfuMANIFEST-WAIT-RESET (bitManifestationTolerant=0) 状態に遷移した場合;
-
bitWillDetach=1であれば、装置はバス上で USB Detach-Atach シーケンスを生成する。 -
bitWillDetach=0であれば、ホストは装置に USB Reset を発行しなければならない。装置はその後、Firmware の健全性を評価し、適切な段階・状態に遷移する。
ホスト側 DFUローダーが Write-Before-Read 検証方式の場合、具現化段階での具体的な処理内容は、ない。規約でも具体的に何を検証すべきはは定められていない。 Firmware イメージ以外の バイナリーデータを装置に送信する手段は DFU規約にはないため、装置側がスタンドアロンで行える Firmware 検証手段は、限定される。(DFU 規約が機能不足と言われる所以)
この項は DFU規約書の 付録B で説明されている要件で、DFUローダーが必ず実装すべきことを強制してはいない。
ホストの DFUローダーは、Firmwareイメージファイル(ファイル拡張子は ".dfu" である)を読むときに、ファイル末尾に追加された 16バイトの "DFU Suffix" を確認しなければならない。その目的は、OS全般、特に DFUローダーが、Firmware のダウンロードが正しく完了できるかどうかを事前に把握できるようにすることである。換言すれば、これらのバイト列によって DFUローダーはは互換性のない Firmware のダウンロード試行を検出し、防止することが可能になる。
"DFU Suffix" 自体は、装置に送信(ダウンロード)してはならない。(DFU規約1.1において)
以下に "DFU Suffix" の構造を示すが、バイトオフセットは ファイル末尾の最終バイトを 0とする、負の整数で示されている。よってサイズが 2以上の項は バイト並び(エンディアン)も逆転することに注意が必要。
| Ofs | Field | Size | Value | Description |
|---|---|---|---|---|
| -0 | dwCRC | 4 | 数値 | ファイル全体のCRC(dwCRC自体を除く) |
| -4 | bLength | 1 | 0x10 | この "DFU Suffix" の長さ(dwCRCを含む) |
| -5 | ucDfuSignature[-0] | 1 | 0x44 | 一意の DFU署名[-0] |
| -6 | ucDfuSignature[-1] | 1 | 0x46 | 一意の DFU署名[-1] |
| -7 | ucDfuSignature[-2] | 1 | 0x55 | 一意の DFU署名[-2] |
| -8 | bcdDFU | 2 | BCD | DFU仕様番号 |
| -10 | idVendor | 2 | ID | このファイルに関連付けられた ベンダーID FFFFh または装置の ベンダーIDと一致しなければならない |
| -12 | idProduct | 2 | ID | このファイルに関連付けられた 製品ID FFFFh または装置の 製品IDと一致しなければならない |
| -14 | bcdDevice | 2 | BCD | このファイルに関連付けられた 装置のリリース番号 FFFFh または BCDリリースまたはバージョン番号 |
-
dwCRC、bLength、ucDfuSignature、bcdDFU項は、この仕様の以降の改訂版でも決して変更されない。(と規定されている) -
ucDfuSignature項は定数であり、dwCRC項の計算方法は、この仕様の版番号 1.0 で定義されているとおりであって将来にわたり変更されない。 - 将来この "DFU Suffix" に 項が追加される場合は、それらは
bcdDevice項で指定されているよりも大きな負のオフセットで追加されうる。 -
dwCRC項は "DFU Suffix" の最初の4バイトとして定義され、常に "DFU Suffix" が追加されたファイルの最後(EOFの前)の 4バイトに存在する。 -
bLength項は "DFU Suffix" の長さを示す 1バイト値である。この DFU仕様の改訂版での長さは 16バイトで、dwCRC項が占める 4バイトも含める。 -
ucDfuSignature項は、将来にわたり固定されたマジックナンバーである。ファイルイメージとしては、ASCII文字列表現では "DFU" と読めるだろう。 -
bcdDFU項は、BCD表現で 2バイトの仕様改訂番号である。この DFU仕様の改訂版における値は0x0100で、Revision 1.0 を表す。 -
idVendor項は、有効な ベンダーID、または0xFFFFのいずれかである。これが0xFFFFであるなら、このファイルの持つ Firmware イメージは如何なる装置へも送信(ダウンロード)してよい。かつこの場合はidProduct項の値は無視しなければならない。そうでなければ、装置の持つ ベンダーID と一致しない限り、装置に Firmware イメージを送信(ダウンロード)してはならない。 -
idProduct項は、有効な 製品ID、または0xFFFFのいずれかである。これが0xFFFFであるなら、このファイルの持つ Firmware イメージは如何なる装置に送信(ダウンロード)してもよい。そうでなければ、装置の持つ(列挙段階で読める)装置ID と一致しない限り、装置に Firmware イメージを送信(ダウンロード)してはならない。 -
bcdDevice項には0xFFFFである場合と、BCD番号が含まれる場合とがある。この項は情報提供のみを目的としており、Firmware イメージが装置にデバイスに送信されるかどうかを制限するものではない。ベンダーはこの項を任意に解釈でき、その大小比較で ダウンロードを実行するか、禁止するかを判断するといったことができる。
自ずから "DFU Suffix" を含むイメージファイル(".dfu")は、本体部分に単一のイメージしか記述できない。AVRのように複数のメモリセグメント集合となりえるアーキテクチャでは、本体部分がマルチパート構成を成す場合も考えられる。それらは全くのベンダー依存実装になるだろう。
取り扱うイメージファイルが ".dfu" でないなら(例えば ".elf" 形式であったりするなら)この規約が強制される必然性はない。
- Standard CRC-32 (IEEE 802.3 / ZIP / PNG)
- 多項式
0x04C11DB7
この形式は一般的に、32bit 計算テーブルの先頭が
0x00000000, 0x77073096, ...で始まるだろう。 この形式は CRC-32/JAMCRC 形式(多項式0xEDB88320)の最後の計算結果を 全ビット反転(Xor)したものと一致する。
- dfu-util / SourceForge
- Qiita - 任意の CRC値を導出する
Twitter(X): @askn37
BlueSky Social: @multix.jp
GitHub: https://github.com/askn37/
Product: https://askn37.github.io/
Copyright (c) 2026 askn (K.Sato) multix.jp
Released under the MIT license
https://opensource.org/licenses/mit-license.php
https://www.oshwa.org/
multix.jp/てくにかるむ(休眠中)
Multix Zinnia Product SDK [*AVR]
AVR.JP(日本語訳)
AVR-LIBC(日本語訳)