综述

通用串行总线即插即用(USB OTG)最初由 Linux USB 子系统支持,结合 Realtek 专门设计的 USB PHY 驱动程序以及对 DWC2 USB 控制器驱动程序的一些修改。

架构

USB 软件架构如下图所示。

../_images/usb_software_architecture.svg

实现

原始 USB 由 Linux USB 子系统支持。

文件

描述

<linux>/drivers/usb/dwc2/

由Realtek修改的DWC2主机和设备控制器驱动程序

<linux>/drivers/usb/core/

HCD 核心

<linux>/drivers/usb/gadget/

Gadget 核心

<linux>/drivers/usb/gadget/function/

设备类,例如ADB、CDC ACM、HID、MSC等。

<linux>/drivers/usb/class/cdc-acm.*

CDC ACM 主机类

<linux>/drivers/usb/storage/*

MSC 主机类

参考 usb system v5.4 或者 usb system v6.6 获取 USB 子系统的更多细节。

Realtek USB PHY 驱动程序实现为以下文件:

文件

描述

<linux>/drivers/rtkdrivers/usb_phy/Kconfig

USB PHY 驱动器 Kconfig

<linux>/drivers/rtkdrivers/usb_phy/Makefile

USB PHY 驱动器 Makefile

<linux>/drivers/rtkdrivers/usb_phy/phy-rtk-usb.c

USB PHY 函数

<linux>/drivers/rtkdrivers/usb_phy/phy-rtk-usb.h

USB PHY 接口声明

配置

设备树配置

USB PHY 设备树配置

USB PHY 的设备树节点在 <dts>/rtl8730e-ocp.dtsi 中定义:

usb_phy: usb-phy@41000000 {
   compatible = "realtek,otg-phy";
   reg = <0x400B0000 0x20>,
   <0x41000060 4>,
   <0x42000100 0x10>,
   <0x4200825C 4>;
   #phy-cells = <0>;
   clocks = <&rcc RTK_CKE_USB>;
   rtk,cal-data = <0x00 0xE0 0x9D>,
      <0x00 0xE1 0x19>,
      <0x00 0xE2 0xDB>,
      <0x00 0xE4 0x68>,
      <0x01 0xE5 0x0A>,
      <0x01 0xE6 0xD8>,
      <0x02 0xE7 0x52>,
      <0x01 0xE0 0x04>,
      <0x01 0xE0 0x00>,
      <0x01 0xE0 0x04>;
   rtk,usb-phandle = <&usb>;
   rtk,usb-force-role-en = <1>;
   status = "okay";
};

USB PHY 的设备树配置如下所列:

属性

描述

可配置?

compatible

用于将 Realtek USB PHY 驱动程序与 USB PHY 设备匹配的 ID。

reg

USB PHY 寄存器资源

#phy-cells

指示需要多少个单元来专门描述一个 USB PHY,仅一个 USB PHY 时固定为 0。

clocks

USB PHY 的时钟源

rtk,cal-data

USB PHY 的校准数据

rtk,usb-phandle

USB PHY 的 USB 指针句柄

rtk,usb-force-role-en

启用在 USB 主机模式和设备模式之间强制切换。

1/0

status

USB PHY 状态

disabled/okay

默认情况下,USB PHY 节点是启用的。要禁用它,可以在更高级别的设备树文件中通过节点引用将节点状态覆盖为 disabled,例如芯片特定的设备树文件或电路板特定的设备树文件:

&usb_phy{
   status = "disabled";
};

USB 设备树配置

USB 的设备树节点在 <dts>/rtl8730e-ocp.dtsi 中定义:

usb: usb@40080000 {
   compatible = "realtek,dwc-otg";
   reg = <0x40080000 0x20000>;
   interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
   g-rx-fifo-size = <512>;
   g-np-tx-fifo-size = <256>;
   g-tx-fifo-size = <128 120>;
   status = "okay";
   endpoints {
      ep1in {
         ep_name = "ep1in";
         ep_type = <0x0E>; // USB_EP_CAPS_TYPE_ALL
      };
      ep2out {
         ep_name = "ep2out";
         ep_type = <0x0E>; // USB_EP_CAPS_TYPE_ALL
      };
      ep3in {
         ep_name = "ep3in";
         ep_type = <0x0E>; // USB_EP_CAPS_TYPE_ALL
      };
      ep4out {
         ep_name = "ep4out";
         ep_type = <0x0E>; // USB_EP_CAPS_TYPE_ALL
      };
      ep5in {
         ep_name = "ep5in";
         ep_type = <0x0E>; // USB_EP_CAPS_TYPE_ALL
      };
      ep5out {
         ep_name = "ep5out";
         ep_type = <0x0E>; // USB_EP_CAPS_TYPE_ALL
      };
   };
};

USB 的设备树配置如下所示:

属性

描述

可配置?

compatible

用于将 DWC2 控制器驱动与 USB OTG 设备匹配的 ID。

reg

USB 寄存器资源

interrupts

USB 的 GIC 中断

g-rx-fifo-size

USB 设备的周期性接收 FIFO 大小(单位:DWORDS)。

16~512

g-np-tx-fifo-size

USB 设备的非周期性传输 FIFO 大小(单位:DWORDS)。

16~256

g-tx-fifo-size

在专用 FIFO 模式下的 TX FIFO 大小数组。每个值对应一个起始端点(单位:DWORDS)。Realtek USB 在共享 FIFO 模式下工作,因此此配置将被忽略。

16~256

status

USB 设备状态

disabled/okay

endpoints

允许 USB 端点地址配置以满足特定客户需求。

备注

  • 总数据 FIFO 深度为 1016,这意味着 \(g-rx-fifo-size + g-np-tx-fifo-size + g-tx-fifo-size\) 的结果不应大于 1016。

  • 除非确有必要,否则不要更改默认配置。

USB 节点默认是启用的。要禁用它,可以在更高级别的设备树文件中,通过节点引用将节点状态覆盖为 disabled,例如芯片特定的设备树文件或板子特定的设备树文件:

&usb{
   status = "disabled";
};

编译配置

USB 功能可以配置为内核固件中的内置功能或独立的内核模块。

内置编译配置

将 USB 功能编译到内核固件中:

  1. Device Drivers > Drivers for Realtek > USB PHY driver 选择 Y

    ../_images/select_y_for_usb_phy_driver.png
  2. Device Drivers > USB support 选择 Y

    ../_images/select_y_for_usb_support.png
  3. 选择所需的 USB 模式。

    1. 对于 USB 主机模式,在 Device Drivers > USB support > Support for Host-side USB 选择 Y

    2. 对于 USB 设备模式,在 Device Drivers > USB support > USB Gadget Support 选择 Y

    3. 对于 USB 即插即用模式,在 Device Drivers > USB support > Support for Host-side USBDevice Drivers > USB support > USB Gadget Support 中都选择 Y

    ../_images/select_required_usb_mode.png
  4. Device Drivers > USB support > DesignWare USB2 DRD Core Support 选择 Y

    ../_images/select_y_for_designware_usb2_drd_core_support.png
  5. 检查 DWC2 模式选择。

    1. 对 USB 主机模式,在 Host only mode 选择 Y

    2. 对 USB 设备模式,在 Gadget only mode 选择 Y

    3. 对 USB 即插即用模式,在 Dual Role mode 选择 Y

    ../_images/check_dwc2_mode_selection.png
  6. 选择所需类别的配置,详情请参阅以下部分。

模块配置

要将 USB 功能编译为内核模块:

  1. Device Drivers > Drivers for Realtek > USB PHY driver 选择 M

    ../_images/select_m_for_usb_phy_driver_module.png
  2. Device Drivers > USB support 选择 Y

    ../_images/select_y_for_usb_support.png
  3. 选择所需的 USB 模式。

    1. 对于主机模式,在 Device Drivers > USB support > Support for Host-side USB 选择 M

    2. 对于设备模式,在 Device Drivers > USB support > USB Gadget Support 选择 M

    3. 对于即插即用模式,在 Device Drivers > USB support > Support for Host-side USBDevice Drivers > USB support > USB Gadget Support 全都选择 M

    ../_images/select_required_usb_mode.png
  4. Device Drivers > USB support > DesignWare USB2 DRD Core Support 选择 M

    ../_images/select_m_for_designWare_usb2_drd_core_support.png
  5. 检查 DWC2 模式选择。

    1. 对 USB 主机模式,在 Host only mode 选择 Y

    2. 对 USB 设备模式,在 Gadget only mode 选择 Y

    3. 对 USB 即插即用模式,在 Dual Role mode 选择 Y

    ../_images/check_dwc2_mode_selection.png
  6. 选择所需类别的配置,详情请参阅以下部分。

  7. 在运行时载入内核模块。

    这里的 <kernel_ver> 取决于内核版本,例如 5.4.63。

    1. 对于主机模式,输入以下命令序列以在加载任何 USB 类特定模块之前加载 USB 通用主机驱动程序:

      insmod /lib/modules/<kernel_ver>/kernel/drivers/rtkdrivers/usb_phy/phy-rtk-usb.ko
      insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/common/usb-common.ko
      insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/core/usbcore.ko
      insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/dwc2/dwc2.ko
      
    2. 对于设备模式,输入以下命令序列以在加载任何 USB 类特定模块之前加载 USB 通用设备驱动程序:

      insmod /lib/modules/<kernel_ver>/kernel/drivers/rtkdrivers/usb_phy/phy-rtk-usb.ko
      insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/common/usb-common.ko
      insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/gadget/udc/udc-core.ko
      insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/gadget/libcomposite.ko
      insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/dwc2/dwc2.ko
      

主机解决方案

在 USB 主机模式下,USB OTG 可以枚举已连接的 USB 设备并启动 USB 传输。

本节仅描述了几个主机类的使用,更多信息请参阅 usb v5.4 或者 usb v6.6.

透传主机方案

配置

除了通用的 USB 主机配置之外,还需要额外的配置来支持 USB CDC ACM 类驱动程序,用户可以选择将其配置为内置功能或独立的内核模块。

以下配置提供了支持典型 CDC ACM 设备(如 USB 串口)的示例。

根据需要调整配置。

内置编译配置

进入 USB support 菜单,输入 Y 选择 USB Modem (CDC ACM) supportUSB Serial Converter support 选项:

../_images/type_y_usb_modem_support.png

模块配置

  1. 进入 USB support 菜单,输入 M 选择 USB Modem (CDC ACM) supportUSB Serial Converter support 选项:

    ../_images/type_m_usb_modem_support.png
  2. 在加载常用 USB 主机模块后,加载 CDC ACM 类的内核模块。

    insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/class/cdc-acm.ko
    insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/serial/usbserial.ko
    

应用的 APIs

请参考 usb guide x332

使用示例

一旦配置为 CDC ACM 主机,SoC 将识别连接的 CDC ACM 设备为 TTY 设备,并能够通过 TTY 接口与 CDC ACM 设备进行通信。

  1. 将 CDC ACM 设备通过 USB 电缆连接到 SoC,控制台上将打印以下日志:

    dwc2 40080000.usb: Set speed to high-speed
    usb 1-1: new high-speed USB device number 2 using dwc2
    dwc2 40080000.usb: Set speed to high-speed
    cdc_acm 1-1:1.0: ttyACM0: USB ACM device
    
  2. 通过设备节点 /dev/ttyACM0 与 CDC ACM 设备通信,例如:

    1. 向 CDC ACM 设备发送数据:

      echo helloworld > /dev/ttyACM0
      
    2. 从 CDC ACM 设备接收数据:

      cat /dev/ttyACM0
      

请参考 <sdk>/tests/usbh_cdc_acm 以获取 CDC ACM 主机演示。

存储主机方案

配置

除了常见的 USB 主机配置外,还需要额外的配置来支持 USB MSC 类驱动程序,用户可以选择将其配置为内置功能或独立的内核模块。

以下配置提供了一个示例来支持典型的 MSC 设备:使用瑞昱读卡器解决方案的 UDISK,并格式化为 FAT32 文件系统。

USB MSC 类驱动程序所需的常见配置:

  1. Device Drivers > SCSI device support > SCSI device supportDevice Drivers > SCSI device support > SCSI disk support

    ../_images/scsi_device_disk_support.png
  2. File systems > DOS/FAT/NT Filesystems > VFAT (Windows-95) fs support

    ../_images/vfat_windows_95_fs_support.png
  3. File systems > Native language support > Codepage 437(United States, Canada)File systems > Native language support > NLS ISO 8859-1 (Latin 1; Western European Languages)`

    ../_images/codepage_437.png
    ../_images/nls_ios_8859_1.png

根据需要调整配置。

内置编译配置

进入 USB support 菜单,输入 Y 选择 USB Mass Storage supportRealtek Card Reader support 选项:

../_images/type_y_usb_mass_storage_support.png

模块配置

  1. 进入 USB support 菜单,输入 M 选择 USB Mass Storage support 然后是 Realtek Card Reader support 选项:

    ../_images/type_m_usb_mass_storage_support.png
  2. 在加载通用 USB 主机模块后,加载 MSC 类的内核模块。

    insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/storage/usb-storage.ko
    insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/storage/ums-realtek.ko
    

应用 APIs

请参考 usb guide x498

使用示例

以下是使用支持的 UDISK 测试 USB 主机 MSC 驱动程序的示例。

  1. 将 UDISK 连接到 SoC,控制台将输出以下日志。

    usb 1-1: USB disconnect, device number 2
    dwc2 40080000.usb: Set speed to high-speed
    usb 1-1: new high-speed USB device number 3 using dwc2
    dwc2 40080000.usb: Set speed to high-speed
    usb-storage 1-1:1.0: USB Mass Storage device detected
    scsi host0: usb-storage 1-1:1.0
    scsi 0:0:0:0: Direct-Access TOSHIBA USB FLASH DRIVE PMAP PQ: 0 ANSI: 6
    sd 0:0:0:0: [sda] 30253056 512-byte logical blocks: (15.5 GB/14.4 GiB)
    sd 0:0:0:0: [sda] Write Protect is off
    sd 0:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
    sda: sda1
    sd 0:0:0:0: [sda] Attached SCSI removable disk
    
  2. 挂载 UDISK 设备。

    mkdir /mnt/udisk
    mount -t vfat /dev/sda1 /mnt/udisk
    
  3. 访问 UDISK 设备。创建一个文件并进行读写操作。

    cd /mnt/udisk
    echo hello >> test.txt
    cat test.txt
    hello
    
  4. 卸载 UDISK 设备。

    umount /mnt/udisk
    
  5. 断开 UDISK 设备连接。

    usb 1-1: USB disconnect, device number 2
    

视频主机方案

配置

除了常见的 USB 主机配置,支持 USB UVC 类驱动程序需要额外的配置,并且用户可以选择将其配置为内置功能或独立的内核模块。

以下配置提供了一个支持典型 UVC 设备(如 UVC 摄像头)的示例。

UVC 摄像头所需的常见配置,在 SDK 中默认选中:

  1. Device Drivers > Multimedia support

    ../_images/multimedia_support.png
  2. Device Drivers > Multimedia support > Cameras/video grabbers support, Media Controller API, V4L2 sub-device userspace API, Media USB Adapters

    ../_images/options_in_multimedia_support.png

内置编译配置

进入 Media USB Adapters 输入 Y 选择 USB Video Class (UVC)

../_images/y_for_usb_video_class.png

模块配置

  1. 进入 Media USB Adapters 输入 M 选择 USB Video Class (UVC)

    ../_images/m_for_usb_video_class.png
  2. 在加载常见的 USB 主机模块后,加载有关 UVC 类的内核模块。

    insmod /lib/modules/<kernel_ver>/kernel/drivers/media/usb/uvc/uvcvideo.ko
    

应用 APIs

它将 UVC 设备视为 V4L2 设备。请参阅 linux video 以获取有关 V4L2 API 的更多信息。

使用示例

以下是典型 UVC 设备(如 USB 摄像头)的简单用法示例:

一旦 USB 摄像头插入 USB 电缆,控制台上将打印以下日志。

dwc2 40080000.usb: Set speed to high-speed
usb 1-1: new high-speed USB device number 2 using dwc2
dwc2 40080000.usb: Set speed to high-speed
uvcvideo: Found UVC 1.00 device USB Camera (0bda:5842)
input: USB Camera: USB Camera as /devices/platform/ocp/40080000.usb/usb1/1-1/1-1:1.0/input/input1

用户可以使用带有 V4L2 库 API 的 IOCTL 访问 USB 摄像头。

<sdk>/tests/usbh_uvc 目录下找到 UVC 演示,这是一个从 UVC 摄像头捕获图像并将其保存到 SD 卡的示例。

备注

在运行 UVC 演示之前,应先挂载 SD 卡。

自定义主机方案

Vendor 类是为用户设计的,用于开发自定义的 USB 主机类。

配置

除了常见的 USB 主机配置外,还需要额外的配置来支持 USB Vendor 类驱动程序,用户可以选择将其配置为内置功能或独立的内核模块。

内置编译配置

输入 Y 选择 USB 测试驱动:

../_images/y_for_usb_testing_driver.png

模块配置

  1. 输入 M 选择 USB 测试驱动:

    ../_images/m_for_usb_testing_driver.png
  2. 在加载常见的 USB 主机模块后,加载有关 Vendor 类的内核模块。

    insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/misc/usbtest.ko
    

应用 APIs

无。

使用示例

<sdk>/tests/usbh_vendor 目录下找到用于用户空间的 USB 主机 Vendor 示例。

设备解决方案

Linux 协议栈中,USB 设备称为 Gadget 。

在 Gadget 模式下,USB OTG 控制器可被 USB 主机枚举,并响应传输请求。

Gadget 驱动支持两种配置方式:

  • Configfs 模式:通过用户空间的文件系统接口动态配置 Gadget 功能。

  • 传统模式:通过加载特定内核模块使用预设配置。

本节主要介绍 Configfs 模式下的使用。

有关设备类的更多详细信息,请参考内核文档 usb support v5.4usb support v6.6

透传设备方案

配置

启用 CDC ACM 类需在基础 USB 配置之上进行额外设置。用户可将其配置为内核内建功能或独立模块。

内置编译配置

在 Gadget 支持中输入 Y 以选择以下选项:

  • 通过 configfs 可配置的 Gadget 功能

  • Gadget 串口控制台支持

  • 抽象控制模型 (CDC ACM)

模块配置

  1. 在 Gadget 支持中选择以下选项:

    • 输入 M 选择 USB Gadget functions configurable through configfs

    • 输入 Y 选择 Serial gadget console support

    • 输入 Y 选择 Abstract Control Model (CDC ACM)

    ../_images/cdc_acm_module_configuration_options_usb_gadget_support.png
  2. 在加载通用 USB 设备模块后,加载有关 CDC ACM 类的内核模块。

    insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/gadget/function/u_serial.ko
    insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/gadget/function/usb_f_acm.ko
    

应用 APIs

请参考 usb guide

使用示例

本示例展示如何将开发板配置为 CDC ACM 设备。

  1. 使用 USB 线缆连接开发板与 PC。

  2. 在开发板终端执行以下命令进行 Configfs 配置:

    mkdir /mnt/config
    mount none /mnt/config -t configfs
    cd /mnt/config/usb_gadget
    mkdir cdc && cd cdc
    echo 0x0200 > bcdUSB
    echo 0x02 > bDeviceClass
    echo 0x02 > bDeviceSubClass
    echo 64 > bMaxPacketSize0
    echo 0x8730 > idProduct
    echo 0x0BDA > idVendor
    mkdir strings/0x409
    echo "Realtek" > strings/0x409/manufacturer
    echo "VCOM" > strings/0x409/product
    echo "123456789AB" > strings/0x409/serialnumber
    mkdir configs/c.1
    echo 120 > configs/c.1/MaxPower
    mkdir configs/c.1/strings/0x409
    echo "acm" > configs/c.1/strings/0x409/configuration
    mkdir functions/acm.ttyS1
    ln -s functions/acm.ttyS1 configs/c.1/
    echo 40080000.usb > UDC
    
  3. 数据发送测试

    在 PC 端打开对应的 COM 端口。在开发板终端输入:

    echo 12345 > /dev/ttyGS0
    

    PC 端串口工具将接收到字符串 12345

  4. 数据接收测试

    在开发板终端监听端口:

    cat /dev/ttyGS0
    

    从 PC 端发送字符串 12345,开发板终端将显示接收到的内容。

备注

Win7 不能直接驱动 CDC ACM 设备。需要安装特定驱动程序: <sdk>/tools/image_tool/RtkUsbCdcAcmSetup.INF 。并且此驱动程序中的 PID / VID 应该与 CDC ACM 设备描述符一致。

备注

如果 PC COM 无法打开,请在 <linux>/drivers/usb/gadget/function/f_acm.c 中注释以下代码以临时解决问题:

static int acm_cdc_notify(struct f_acm *acm, u8 type, u16 value,
void *data, unsigned length)
{
   /* ep_queue() can complete immediately if it fills the fifo... */
   spin_unlock(&acm->lock);
   //status = usb_ep_queue(ep, req, GFP_ATOMIC);
   spin_lock(&acm->lock);
}

HID 设备方案

配置

除了常见的 USB 设备配置外,启用 HID 类需确保内核已选中 HID bus supportGeneric HID driver

../_images/hid_bus_support_generic_hid_driver.png

实际上,上述配置在 SDK 中默认启用以支持 ADB。

内置编译配置

  1. 在 Gadget 支持中输入 Y 以选择以下选项:

    • 可通过 configfs 配置的 USB Gadget 功能

    • 串行设备控制台支持

    • HID 功能

    ../_images/hid_built_in_configuration_options_usb_gadget_support.png

模块配置

  1. 在 Gadget 支持中选择下列项目:

    • 输入 M 选择 USB Gadget functions configurable through configfs

    • 输入 Y 选择 HID function

    ../_images/hid_module_configuration_options_usb_gadget_support.png
  2. 在加载通用 USB 设备模块后加载有关 HID 类的内核模块:

    insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/gadget/function/udc-core.ko
    insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/gadget/function/usb_f_hid.ko
    

应用 APIs

请参考 usb guide x498

使用示例

本示例展示如何将开发板配置为 HID 鼠标设备。

  1. 配置 USB 设备:

    mkdir /mnt/config
    mount none /mnt/config -t configfs
    cd /mnt/config/usb_gadget
    mkdir hid
    cd hid
    echo 0x0200 > bcdUSB
    echo 0x03 > bDeviceClass
    echo 0x00 > bDeviceSubClass
    echo 64 > bMaxPacketSize0
    echo 0x8730 > idProduct
    echo 0x0BDA > idVendor
    mkdir strings/0x409
    echo "Realtek" > strings/0x409/manufacturer
    echo "HID" > strings/0x409/product
    echo "123456789AB" > strings/0x409/serialnumber
    mkdir configs/c.1
    echo 120 > configs/c.1/MaxPower
    mkdir configs/c.1/strings/0x409
    echo "Primary configuration" > configs/c.1/strings/0x409/configuration
    
  2. 配置 HID 报告描述符:

    mkdir functions/hid.usb0
    echo 1 > functions/hid.usb0/subclass
    echo 2 > functions/hid.usb0/protocol
    echo 4 > functions/hid.usb0/report_length
    echo -ne\\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x05\\x09\\x19\\x01\\x29\\x03\\x15\\x00\\x25\\x01\\x95\\x03\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x05\\x81\\x03\\x05\\x01\\x09\\x30\\x09\\x31\\x09\\x38\\x15\\x81\\x25\\x7f\\x75\\x08\\x95\\x03\\x81\\x06\\xc0\\xc0> functions/hid.usb0/report_desc
    ln -s functions/hid.usb0 configs/c.1/
    echo 40080000.usb > UDC
    
  3. 连接主机后,通过设备节点 /dev/hidg0 与主机通信。以下命令将控制鼠标向右下方移动 0x40 像素:

    echo -ne "\0\x40\x40\0" > /dev/hidg0
    

备注

鼠标数据包协议格式:

BYTE0
|-- bit7~bit3: RSVD
|-- bit2: middle button press
|-- bit1: right button press
|-- bit0: left button press
BYTE1: x-axis value, -128~127
BYTE2: y-axis value, -128~127
BYTE3: wheel value, -128~127

存储设备方案

配置

除了常见的 USB 设备配置外,还需要额外的配置来支持 USB MSC 类,用户可以选择将其配置为内置功能或独立的内核模块。

内置编译配置

  1. 在 Gadget 支持中启用以下选项(标记为 Y):

    • 通过 configfs 可配置的 USB Gadget 功能

    • MSC

    ../_images/mass_storage_built_in_configuration_options_usb_gadget_support.png

模块配置

  1. 在 USB Gadget 支持中配置以下选项:

    • 输入 M 选择 USB Gadget functions configurable through configfs

    • 输入 Y 选择 Mass storage

    ../_images/mass_storage_module_configuration_options_usb_gadget_support.png
  2. 在加载通用 USB 设备模块后,加载关于 MSC 类的内核模块。

insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/gadget/function/udc-core.ko
insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/gadget/function/usb_f_mass_storage.ko
insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/gadget/function/libcomposite.ko

应用 APIs

请参考 usb guide x498

使用示例

本示例展示如何将开发板配置为 USB MSC 设备,并使用 SD 卡作为存储介质。

  1. 初始化 SD 卡,详情请参考 SDIO 主机章节。

  2. 连接开发板至 PC。

  3. 在开发板终端执行配置命令:

    mkdir /mnt/config
    mount none /mnt/config -t configfs
    cd /mnt/config/usb_gadget
    mkdir msc && cd msc
    echo 0x0200 > bcdUSB
    echo 0x8730 > idProduct
    echo 0x0BDA > idVendor
    mkdir strings/0x409
    echo "Realtek" > strings/0x409/manufacturer
    echo "MSC" > strings/0x409/product
    echo "123456789AB" > strings/0x409/serialnumber
    mkdir configs/c.1
    echo 120 > configs/c.1/MaxPower
    mkdir configs/c.1/strings/0x409
    echo "mass_storage" > configs/c.1/strings/0x409/configuration
    mkdir functions/mass_storage.0
    echo /dev/mmcblk0 >functions/mass_storage.0/lun.0/file
    echo 1 > functions/mass_storage.0/lun.0/removable
    echo 0 > functions/mass_storage.0/lun.0/nofua
    ln -s functions/mass_storage.0 configs/c.1/
    echo 40080000.usb > UDC
    

成功配置后,PC 将识别到一个新的可移动磁盘(UDISK)。

自定义设备方案

Vendor 类旨在供用户开发自定义的 USB 设备类。

配置

除了常见的 USB 设备配置外,还需要额外的配置来支持 USB Vendor 类驱动程序。用户可以选择将其配置为内建功能或独立的内核模块。

内置编译配置

  1. 在 Gadget 支持中启用以下选项(标记为 Y):

    • 通过 configfs 可配置的 USB Gadget 功能

    • 回环和源接收功能(用于测试)

    ../_images/vendor_built_in_configuration_options_usb_gadget_support.png

模块配置

  1. 在 Gadget 支持中配置以下选项:

    • 输入 M 选择 USB Gadget functions configurable through configfs

    • 输入 Y 选择 Loopback and sourcesink function (for testing)

    ../_images/vendor_module_configuration_options_usb_gadget_support.png
  2. 在加载通用 USB 设备模块之后,加载有关 Vendor 类的内核模块。

    insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/gadget/function/udc-core.ko
    insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/gadget/function/usb_f_ss_lb.ko
    insmod /lib/modules/<kernel_ver>/kernel/drivers/usb/gadget/function/libcomposite.ko
    

应用 APIs

无。

使用示例

以下步骤演示如何测试 Gadget Vendor 类功能:

  1. 在开发板终端执行配置命令:

    mkdir /mnt/config
    mount none /mnt/config -t configfs
    cd /mnt/config/usb_gadget
    mkdir vendor && cd vendor
    echo 0x0200 > bcdUSB
    echo 0xa4a0 > idProduct
    echo 0x0525 > idVendor
    mkdir strings/0x409
    echo "Realtek" > strings/0x409/manufacturer
    echo "Vendor" > strings/0x409/product
    echo "123456789AB" > strings/0x409/serialnumber
    mkdir configs/c.1
    mkdir configs/c.2
    echo 120 > configs/c.1/MaxPower
    echo 120 > configs/c.2/MaxPower
    mkdir configs/c.1/strings/0x409
    mkdir configs/c.2/strings/0x409
    echo "vendor1" > configs/c.1/strings/0x409/configuration
    echo "vendor2" > configs/c.2/strings/0x409/configuration
    mkdir functions/SourceSink.0
    mkdir functions/Loopback.0
    ln -s functions/SourceSink.0 configs/c.1/
    ln -s functions/Loopback.0 configs/c.2/
    echo 40080000.usb > UDC
    

备注

本示例配置为复合设备:

  • ln -s functions/SourceSink.0 configs/c.1/ 表示默认功能是 sourcesink。

  • ln -s functions/Loopback.0 configs/c.1/ 表示默认功能是 loopback。

  1. 将开发板连接至 USB 主机。

  2. 执行主机 Vendor 和设备 Vendor 的交互测试(使用 testusb 工具):

    功能

    loopback

    sourcesink

    配置设定

    ln -s functions/Loopback.0 configs/c.1/

    ln -s functions/SourceSink.0 configs/c.1/

    主机控制台命令

    testusb -a -c1 -t30 -s256 -g32 -v1

    testusb -a -c1 -tx -s256 -g32 -v1

    设备控制台命令

    无需命令

    无需命令

备注

在主机测试命令中:

  • Case 30 (-t30) 专用于 Loopback 功能测试。

  • Case 0~29 (-tx, x=0..29) 用于 SourceSink 功能测试,参数可根据需求调整。