跳到主要内容

12_Gadget应用实例之zero

参考资料:

  • 《06_libusb的使用》

  • 《11.5_从数据传输的角度理解Gadget框架》

  • 实验代码:GIT仓库source/12_USB/05_libusb_zero

1. 编写程序

1.1 编程思路

涉及的程序如下图所示:

image-20230221090359606

基于libusb编写程序:

  • 找到设备
  • 选择配置:loopback、sourcesink
  • 得到端点:找到interface进而得到endpoint
  • 读写数据:操作endpoint

1.2 zero设备的描述符

在Ubuntu里执行如下命令:

$ lsusb -v -d 0525:a4a0

可以列出zero设备的描述符:

Bus 001 Device 002: ID 0525:a4a0 Netchip Technology, Inc. Linux-USB "Gadget Zero"
Couldn't open device, some information will be missing
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 255 Vendor Specific Class
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0525 Netchip Technology, Inc.
idProduct 0xa4a0 Linux-USB "Gadget Zero"
bcdDevice 4.09
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 2
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 69
bNumInterfaces 1
bConfigurationValue 3
iConfiguration 4
bmAttributes 0xc0
Self Powered
MaxPower 2mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 1
bNumEndpoints 4
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 4
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 4
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 32
bNumInterfaces 1
bConfigurationValue 2
iConfiguration 5
bmAttributes 0xc0
Self Powered
MaxPower 2mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 6
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0

它有2个配置:

  • 第1个配置(bConfigurationValue = 2)对应loopback功能:里面有1个接口,接口有1个setting,下面有2个endpoint
  • 第2个配置(bConfigurationValue = 3)对应SourceSink功能:里面有1个接口,接口有2个setting
    • 第1个setting下面有2个endpoint:都是bulk端点
    • 第2个setting下面有4个endpoint:2个是bulk端点,另外2个是Isochronous端点

1.3 编程

参考libusb示例:libusb/examples/xusb.c

2. 上机实验

实验步骤:

  • 先安装g_zero驱动程序:在开发板上执行modprobe g_zero

  • 然后连接OTG线到PC

  • 在Ubuntu中识别出设备

  • 执行测试程序

    • 先编译:在Ubuntu里执行如下命令

      apt-cache search libusb # 查找libusb开发包
      sudo apt install libusb-1.0-0-dev # 安装libusb开发包
      gcc -o zero_app zero_app.c -lusb-1.0 # 编译

    • 测试:在Ubuntu里执行如下命令

      $ sudo ./zero_app -l # 列出设备的配置值
      config 0: bConfigurationValue = 3
      config 1: bConfigurationValue = 2


      # 测试loopback功能
      $ sudo ./zero_app -s 2 # 选择loopback的配置
      $ sudo ./zero_app -wstr www.100ask.net # 写入字符串
      current config: 2
      in_ep = 0x81, out_ep = 0x1
      $ sudo ./zero_app -rstr # 读出字符串
      current config: 2
      in_ep = 0x81, out_ep = 0x1
      Read string: www.100ask.net

      $ sudo ./zero_app -w 1 2 3 4 5 6 7 8 # 写入8个字节
      current config: 2
      in_ep = 0x81, out_ep = 0x1
      sudo ./zero_app -r # 读到8个字节
      current config: 2
      in_ep = 0x81, out_ep = 0x1
      transferred != in_ep_maxlen
      Read datas:
      01 02 03 04 05 06 07 08


      #测试Source/Sink功能
      $ sudo ./zero_app -s 3 # 选择source/sink的配置
      book@100ask:~/nfs_rootfs/05_libusb_zero$ sudo ./zero_app -r # 读数据
      current config: 3
      in_ep = 0x81, out_ep = 0x1
      Read datas:
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

      sudo ./zero_app -w 0 0 0 # 写数据, 只能写入0,
      # 写入其他值将会导致开发板上的驱动认为是错误然后halt out端点
      # 然后只能重新执行 ”sudo ./zero_app -s 3“ 才能恢复