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
};
相关文章
相关标签/搜索
每日一句
    每一个你不满意的现在,都有一个你没有努力的曾经。
公众号推荐
   一个历史类的公众号,欢迎关注
一两拨千金