Edit online

USB Device 配置

4 Dec 2024
Read time: 9 minute(s)

USB Device Controller 配置

  1. Linux Kernel Kconfig 文件中使能相应 UDC Driver:
    > Device Drivers > USB support > USB Gadget Support > USB Peripheral Controller
    
     <*> ArtInChip USB2.0 Device Controller
  2. DTS 文件中配置相应 UDC Device:
    aicudc: udc@10200000 {
        compatible = "artinchip,aic-udc-v1.0";
        reg = <0x0 0x10200000 0x0 0x1000>;
        interrupts-extended = <&plic0 34 IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&cmu CLK_USBD>, <&cmu CLK_USB_PHY0>;
        clock-names = "udc_clk";
        resets = <&rst RESET_USBD>, <&rst RESET_USBPHY0>;
        reset-names = "aicudc", "aicudc-ecc";
        status = "okay";
    };

USB Gadget 配置

为了方便 Linux 系统模拟成各种类型的 USB Device,Linux 设计了一个 Gadget Device 。为了方便用户使用 ,Linux 又将 ConfigFS 引入 USB Device 子系统,用来灵活配置 Gadget Device

所以在使用 USB Device 时,在 Linux Kernel 中把这两者都配置成使能。
  • Gadget
    > Device Drivers > USB support
    
     <*>   USB Gadget Support  --->
  • ConfigFS
    > Device Drivers > USB support > USB Gadget Support
    
     <*>   USB Gadget functions configurable through configfs

USB Interface 配置

Gadget Device 基础之上,需要配置具体的 Interface / Function 才能提供具体的 USB Device 功能。USB Gadget Device 可以模拟成各种功能的 USB 外设,例如:USB 串口、USB 网口、U 盘等
  1. ACM 串口 配置。
    1. Linux Kernel Kconfig 文件中使能 CDC ACM 类型的 Gadget functions
      > Device Drivers > USB support > USB Gadget Support
      
       <*>   USB Gadget functions configurable through configfs
       [*]     Abstract Control Model (CDC ACM)
      
      
      > Device Drivers
      
       [*] Block devices  --->
    2. 通过用户态的 configfs 文件接口创建包含 ACM 串口功能的 USB Device:
      mount -t configfs none /sys/kernel/config
      cd /sys/kernel/config/usb_gadget
      mkdir g1
      cd g1
      echo "0x1d6b" > idVendor
      echo "0x0104" > idProduct
      mkdir strings/0x409
      ls strings/0x409/
      echo "0123456789" > strings/0x409/serialnumber
      echo "AIC Inc." > strings/0x409/manufacturer
      echo "Bar Gadget" > strings/0x409/product
      mkdir functions/acm.GS0
      mkdir configs/c.1
      ls configs/c.1
      mkdir configs/c.1/strings/0x409
      ls configs/c.1/strings/0x409/
      echo "ACM" > configs/c.1/strings/0x409/configuration
      ln -s functions/acm.GS0 configs/c.1
      echo `ls /sys/class/udc` > UDC
    用户使用:
    1. 将单板的 USB Device 端口和 Windows PC 的 USB Host 端口连接,在 Windows PC 设备管理器会看到一个新的 USB 串口节点:


      image0

    2. 在 PC 端使用串口终端工具打开 COM12,波特率使用 115200。

    3. 在单板端执行: echo abd > /dev/ttyGS0 ,在 PC 端串口就会收到该字符串:


      image1

    4. 在单板端执行 cat /dev/ttyGS0 ,在 PC 端写一个字符串 “123412345” ,点回车后,在单板端也能收到该字符串。

  2. U 盘 配置
    1. Linux Kernel Kconfig 文件中,使能 Mass storage 类型的 Gadget functions
      > Device Drivers > USB support > USB Gadget Support
      
       <*>   USB Gadget functions configurable through configfs
       [*]     Mass storage
    2. Linux Kernel Kconfig 文件中,使能环回块设备:
      > Device Drivers
      
       <*>   Loopback device support
    3. Busybox 中使能 losetup 命令:
      >  Linux System Utilities
      
       [*] losetup (5.5 kb)
    4. 通过用户态的 configfs 文件接口创建包含 Mass storage 存储功能的 USB Device
      dd if=/dev/zero of=/tmp/mass.img bs=128K count=132
      losetup /dev/loop0 /tmp/mass.img
      mkdir /tmp/media
      mkfs.vfat /dev/loop0
      mount -t vfat /dev/loop0 /tmp/media/
      cp /linuxrc /tmp/media
      sync
      
      mount -t configfs none /sys/kernel/config
      cd /sys/kernel/config/usb_gadget
      mkdir g_mass
      cd g_mass
      echo "0x200" > bcdUSB
      echo "0x100" > bcdDevice
      echo "0x1234" > idVendor
      echo "0x5678" > idProduct
      mkdir configs/c1.1
      mkdir functions/mass_storage.0
      echo /dev/loop0 > functions/mass_storage.0/lun.0/file
      mkdir strings/0x409
      echo "0123456789ABCDEF" > strings/0x409/serialnumber
      echo "river" > strings/0x409/manufacturer
      echo "river_msc" > strings/0x409/product
      mkdir configs/c1.1/strings/0x409
      echo "abc" > configs/c1.1/strings/0x409/configuration
      ln -s functions/mass_storage.0 configs/c1.1
      echo `ls /sys/class/udc` > UDC
    5. 将单板的 USB Device 端口和 Windows PC 的 USB Host 端口连接,在 Windows PC 上会看到一个新增的 U 盘,可以正常读写。

  3. NCM 网口配置
    1. Linux Kernel Kconfig 文件中,使能 CDC NCM 类型的 Gadget functions
      > Device Drivers > USB support > USB Gadget Support
      
       <*>   USB Gadget functions configurable through configfs
       [*]     Network Control Model (CDC NCM)
    2. Linux Kernel Kconfig 文件中,使能 TCP/IP 支持:
      > Networking support > Networking options
      
       [*] TCP/IP networking
    3. 通过用户态的 configfs 文件接口创建包含 CDC NCM 以太网功能的 USB Device:
      mount -t configfs none /sys/kernel/config
      cd /sys/kernel/config/usb_gadget
      mkdir g_ncm
      cd g_ncm
      echo "0xA55A" > idVendor
      echo "0x0111" > idProduct
      mkdir strings/0x409
      echo "0123456789" > strings/0x409/serialnumber
      echo "Xyz Inc." > strings/0x409/manufacturer
      echo "NCM gadget" > strings/0x409/product
      mkdir functions/ncm.usb0
      mkdir configs/c.1
      mkdir configs/c.1/strings/0x409
      echo "NCM" > configs/c.1/strings/0x409/configuration
      ln -s functions/ncm.usb0 configs/c.1
      echo `ls /sys/class/udc` > UDC
      
      ifconfig usb0 up
      ifconfig usb0 173.11.1.1
    4. 用户使用:

      1. 将单板的 USB Device 端口和 Ubuntu PC 的 USB Host 端口连接,在 Ubuntu PC 会看到一个新的网络接口,名字随机,类似: enx0afcc15d3417

      2. 配置 Ubuntu PC 端的网口为同一网段地址, sudo ifconfig enx0afcc15d3417 173.11.1.2

      3. 两个网口相互可以 ping 通:
        ubuntu@ubuntu $ ping 173.11.1.1
        PING 173.11.1.1 (173.11.1.1) 56(84) bytes of data.
        64 bytes from 173.11.1.1: icmp_seq=1 ttl=64 time=10.3 ms
        64 bytes from 173.11.1.1: icmp_seq=2 ttl=64 time=5.02 ms
  4. ECM 网口 配置
    1. Linux Kernel Kconfig 文件中,使能 CDC ECM 类型的 Gadget functions
      > Device Drivers > USB support > USB Gadget Support
      
       <*>   USB Gadget functions configurable through configfs
       [*]     Ethernet Control Model (CDC ECM)
    2. Linux Kernel Kconfig 文件中,使能 TCP/IP 支持:
      > Networking support > Networking options
      
       [*] TCP/IP networking
    3. 通过用户态的 configfs 文件接口创建包含 CDC ECM 以太网功能的 USB Device:
      mount -t configfs none /sys/kernel/config
      cd /sys/kernel/config/usb_gadget
      mkdir g_ecm
      cd g_ecm
      echo "0x1d6b" > idVendor
      echo "0x0104" > idProduct
      mkdir strings/0x409
      echo "0123456789" > strings/0x409/serialnumber
      echo "AIC Inc." > strings/0x409/manufacturer
      echo "Bar Gadget" > strings/0x409/product
      mkdir functions/ecm.usb0
      mkdir configs/c.1
      mkdir configs/c.1/strings/0x409
      echo "ECM" > configs/c.1/strings/0x409/configuration
      ln -s functions/ecm.usb0 configs/c.1
      echo `ls /sys/class/udc` > UDC
      
      ifconfig usb0 up
      ifconfig usb0 173.11.1.1
    4. 用户使用:和上一节 NCM 网口 一样。
  5. ADBD 配置
    1. Linux Kernel Kconfig 文件中,使能 FunctionFS 类型的 Gadget functions
      > Device Drivers > USB support > USB Gadget Support
      
       <*>   USB Gadget functions configurable through configfs
       [*]     Function filesystem (FunctionFS)
    2. Linux Kernel Kconfig 文件中,使能 TCP/IP 支持:
      > Networking support > Networking options
      
       [*] TCP/IP networking
    3. 通过用户态的 configfs 文件接口创建 FunctionFS 中的 USB Device,挂载完 FunctionFS 文件系统以后, adbd 通过 /dev/usb-ffs/adb 中映射成文件的 endpoint 直接和 USB Host 进行通讯:
      mkdir /dev/pts
      mount -t devpts none /dev/pts
      
      mount -t configfs none /sys/kernel/config
      cd /sys/kernel/config/usb_gadget
      mkdir g_adb
      cd g_adb
      echo "0x18d1" > idVendor
      echo "0x4e26" > idProduct
      mkdir configs/c.1
      mkdir functions/ffs.adb
      mkdir strings/0x409
      mkdir configs/c.1/strings/0x409
      echo "0123456789ABCDEF" > strings/0x409/serialnumber
      echo "AIC Inc." > strings/0x409/manufacturer
      echo "FunctionFS gadget (adb)" > strings/0x409/product
      echo "Conf 1" > configs/c.1/strings/0x409/configuration
      echo 120 > configs/c.1/MaxPower
      ln -s functions/ffs.adb configs/c.1
      
      mkdir -p /dev/usb-ffs/adb
      mount -o uid=2000,gid=2000 -t functionfs adb /dev/usb-ffs/adb
      
      ifconfig lo up
      ifconfig
      
      cd /root
      adbd&
      
      sleep 1
      echo `ls /sys/class/udc/` > /sys/kernel/config/usb_gadget/g_adb/UDC
    4. 将单板的 USB Device 端口和 PC 的 USB Host 端口连接,在 PC 端运行 adb shell 命令即可进行 adb 操作。