Edit online

Gadget 实现

USB 升级过程中,平台端是一个 USB 设备,因此在 U-Boot 中需要实现对应的 Gadget, 在 Gadget 中实现对相应的 USB 命令进行处理。

Gadget 实现框架图如下所示:

U-Boot 的 USB 驱动框架支持实现自定义的 Gadget 设备,只需按照框架定义的方式实现相应函数, 并且提供相应的描述符信息即可。Gadget 实现的源码在 drivers/usb/gadget/f_aicupgusb.c

Gadget 设备通过下面的宏进行 Declare:
DECLARE_GADGET_BIND_CALLBACK(usb_dnl_aicupg, aicupg_add);

Gadget 描述符中相关的 Vendor ID 和 Product Number 则由 Kconfig 配置:

  • CONFIG_USB_GADGET_VENDOR_NUM

    0x33C3 ArtInChip 的专有 Vendor ID

  • CONFIG_USB_GADGET_PRODUCT_NUM

    0x6677 字符串 “fw” 的 ASCII 码值,表示专门用于镜像升级的 ID

Gadget 实现的接口函数有:
f_upg->usb_function.name = "f_aicupg";
f_upg->usb_function.bind = aicupg_bind;
f_upg->usb_function.unbind = aicupg_unbind;
f_upg->usb_function.set_alt = aicupg_set_alt;
f_upg->usb_function.disable = aicupg_disable;
f_upg->usb_function.strings = aicupg_strings;
Gadget 层 USB 数据输入输出函数为:
void aicupg_trans_layer_read_pkt(struct usb_ep *in_ep,
                                 struct usb_request *in_req);
void aicupg_trans_layer_write_pkt(struct usb_ep *out_ep,
                                  struct usb_request *out_req);

具体命令的处理代码实现在arch/arm/mach-artinchip/aicupg

Gadget 层通过下面的接口与 aicupg 库进行交互:
s32 aicupg_data_packet_read(u8 *data, s32 len);
s32 aicupg_data_packet_write(u8 *data, s32 len);