USB DFU特定類請求簡介


下面的Table 1和Table 2簡單列舉了DFU特定類請求和他們的參數

Table 1. DFU類請求

Request Request code Request description
DFU_DETACH 0X00 請求設備離開DFU模式,進入應用程序
DFU_DNLOAD 0x01 請求Host主機端數據發送到設備端,將數據加載到設備內部Flash.這個過程包含擦除Flash命令的過程
DFU_UPLOAD 0x02 請求設備端的數據傳輸到主機端,將設備內部Flash相應的數據加載到Host主機端的文件中
DFU_GETSTATUS 0x03 請求設備發送狀態報告到主機端(包括上一個請求執行的狀態和這個狀態之后設備即將進入的狀態)
DFU_CLRSTATUS 0x04 請求設備清除錯誤狀態並移動到下一步
DFU_GETSTATE 0x05 在這個請求之后,請求設備僅僅發送當前即將進入的狀態
DFU_ABORT 0x06 請求設備離開當前狀態/操作,並立即進入空閑狀態

:Detach請求在bootloader啟動時是無意義的,bootloader從系統復位開始,依賴啟動模式的配置,即其他應用程序不能在此期間運行

Table 2. DFU特定類請求的參數總結

bmRequest bRequest wValue wIndex wLength Data
00100001b DFU_DETACH wTimeout Interface Zero None
00100001b DFU_DNLOAD wBloackNum Interface Length Firmware
10100001b DFU_UPLOAD Zero Interface Length Firmware
00100001b DFU_GETSTATUS Zero Interface 6 Status
00100001b DFU_CLRSTATUS Zero Interface Zero None
00100001b DFU_GETSTATE Zero Interface 1 State
00100001b DFU_ABORT Zero Interface Zero None

:State和Status在程序代碼中的區別

State 表達的是形態,而 Status 表達的是從一種形態轉換成另一種形態的過程中,那些有顯著特征的離散中間值。
舉一個旅館房間的例子,一個房間可以是婚房、普通房、豪華總統房,這些都是用 State 來表達。把一個普通房改造成豪華總統房,這個過程就有設計、材料准備、工人就位、施工、驗收等步驟,這個時候就用 Status 來表達。那么,區分點在哪?區分點就在於一個房間當用 State 描述時,它是個彼此獨立的枚舉值,可以沒有前后順序的在婚房、普通房、豪華總統房之間來回轉換。而當使用 Status 時,是存在前后狀態依賴關系的一個變化量,不能沒有做設計就施工,也不能沒施工就驗收。
所以,State 和 Status 的核心區別,就是它們的枚舉值之間是否有依賴關系,沒有依賴關系的用 State,有依賴關系的用 Status

  1. DFU_DNLOAD請求命令簡介:

下載請求通常會執行不同的命令,所執行的命令是通過USB請求結構體中的wValue參數來選擇具體命令去執行的,其中支持下面的操作:

  • 寫內存 (wValue > 1)
  • 設置地址指針(wValue = 0, 第一個字節 = 0x21)
  • 擦除(wValue = 0, 第一個字節 = 0x41)
  • 讀(wValue = 0, 第一個字節 = 0x92)
  • 離開DFU(離開DFU模式並跳轉執行相應應用程序)
  1. 離開DFU狀態簡介

通過DFU download請求之后,應用程序會被加載到內部Flash或直接加載到RAM中,最后就會離開DFU模式跳轉到相應的加載地址(bootloader決定,即運行地址可以在用戶的image中,download第一步先下載IVT頭解析出將來要加載運行的地址)。
當Host發送最后一個0字節(無數據階段)的DFU_DNLOAD請求后,意味着通知device即將要離開DFU模式,當前設備處於DFU DNLOAD IDLE/DFU IDLE空閑狀態時,設備即確認這個請求。

:在完成所有的下載操作后,device會進入manifestation狀態,告訴host已經完成了一個完整的傳輸.
1)在完全能跳入應用程序后並執行,首先要確保在加載地址處正確設置中斷向量表的位置。
2)通過USB IP將應用程序加載到相應地方后,在從bootloader跳轉時,必須要禁掉相應的USB中斷,否則會干擾到用戶代碼。

下圖時完整的DFU運行過程的流程圖:

以下是定義的DFU結構體參數和DFU狀態函數表:

// H → D send request to device
/* Define DFU event struct */
typedef struct _usb_device_dfu_event_struct
{
    usb_device_dfu_state_event_t name;
    uint16_t wValue;
    uint16_t wLength;
} usb_device_dfu_event_struct_t;

// D → H return status to host
/*! @brief DFU status definition. */
typedef struct _usb_dfu_status_struct
{
    uint8_t bStatus;           /* status result */
    uint8_t bwPollTimeout[3U]; /* The minimum time host should wait before sending
                                  a subsequent DFU GETSTATUS request */
    uint8_t bState;            /* dfu state */
    uint8_t iString;           /* Index of status description in string table */
    uint8_t reserved[2];
} usb_dfu_status_struct_t;

/* DFU state function table. */
const static dfu_state_func s_dfuStateFunc[11] = {
    USB_DeviceStateAppIdle,         USB_DeviceStateAppDetach,   USB_DeviceStateDfuIdle,
    USB_DeviceStateDfuDnLoadSync,   USB_DeviceStateDfuDnBusy,   USB_DeviceStateDfuDnLoadIdle,
    USB_DeviceStateDfuManifestSync, USB_DeviceStateDfuManifest, USB_DeviceStateDfuManifestWaitReset,
    USB_DeviceStateDfuUpLoadIdle,   USB_DeviceStateDfuError
};



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM