usb gadget configfs 验证

按照上一篇文章对gadget_configfs.txt的翻译,以imx8qxp mek的板子做为验证,配置为mass storage进行验证。


内核打开对应的宏

1、必须打开CONFIG_CONFIGFS_FSCONFIG_USB_LIBCOMPOSITE的宏,前者为用户空间提供访问配置内核驱动的configfs文件系统,后者提供usb gadget composite框架;
2、必须打开UDC(USB Device Controller)的配置,这个是配置硬件控制器。我这里使用CONFIG_USB_CHIPIDEACONFIG_USB_CHIPIDEA_UDC
3、如果使用mass storage功能,需要打开USB_CONFIGFS_MASS_STORAGEUSB_F_MASS_STORAGE,对应于usb_f_mass_storage.ko驱动。


配置步骤

  • 挂载configfs:mount -t configfs none /config/,在这之后,/configfs/目录下就会生成usb_gadget/目录;
  • 创建gadget:mkdir usb_gadget/g1,创建g1/目录之后,该目录下会生成很多配置目录,这里的g1表示gadget 1,一个UDC对应一个gadget,如果你的SOC上有多个gadget,可以创建多个gx目录。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # ll usb_gadget/g1/
    total 0
    -rw-r--r-- 1 root root 4096 1999-11-30 00:02 UDC
    -rw-r--r-- 1 root root 4096 1999-11-30 00:02 bDeviceClass
    -rw-r--r-- 1 root root 4096 1999-11-30 00:02 bDeviceProtocol
    -rw-r--r-- 1 root root 4096 1999-11-30 00:02 bDeviceSubClass
    -rw-r--r-- 1 root root 4096 1999-11-30 00:02 bMaxPacketSize0
    -rw-r--r-- 1 root root 4096 1999-11-30 00:02 bcdDevice
    -rw-r--r-- 1 root root 4096 1999-11-30 00:02 bcdUSB
    drwxr-xr-x 2 root root 0 1999-11-30 00:02 configs
    drwxr-xr-x 2 root root 0 1999-11-30 00:02 functions
    -rw-r--r-- 1 root root 4096 1999-11-30 00:02 idProduct
    -rw-r--r-- 1 root root 4096 1999-11-30 00:02 idVendor
    drwxr-xr-x 2 root root 0 1999-11-30 00:02 os_desc
    drwxr-xr-x 2 root root 0 1999-11-30 00:02 strings
  • 配置PID和VID

    1
    2
    # echo 0x18d1 > usb_gadget/g1/idVendor
    # echo 0x4ee2 > usb_gadget/g1/idProduct
  • 创建并配置string字目录

    1
    2
    3
    4
    # mkdir usb_gadget/g1/strings/0x409
    # echo "123456789" > usb_gadget/g1/strings/0x409/serialnumber
    # echo "xxx" > usb_gadget/g1/strings/0x409/manufacturer
    # echo "xxx_product" > usb_gadget/g1/strings/0x409/product
  • 创建configuration和字符串

    1
    2
    3
    # mkdir usb_gadget/g1/configs/c.1
    # mkdir usb_gadget/g1/configs/c.1/strings/0x409
    # echo "mass_storage" > usb_gadget/g1/configs/c.1/strings/0x409/configuration
  • 创建functions

    1
    2
    3
    # mkdir usb_gadget/g1/functions/mass_storage.0
    [ 108.582976] [1: mkdir: 1976] Mass Storage Function, version: 2009/09/11
    [ 108.592679] [1: mkdir: 1976] LUN: removable file: (no medium)

这里的mass_storage的名字不能随便起,需要根据insmod的function驱动usb_f_mass_storage.ko来决定。否则会出现如下错误:

1
2
1|@android:/config # mkdir usb_gadget/g1/functions/msg.0
mkdir: 'usb_gadget/g1/functions/msg.0': No such file or directory

  • 将functions和configuration关联起来
    1
    # ln -s usb_gadget/g1/functions/mass_storage.0 usb_gadget/g1/configs/c.1

上述配置之后,得到的结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
127|@android:/config # find .
.
./usb_gadget
./usb_gadget/g1
./usb_gadget/g1/os_desc
./usb_gadget/g1/os_desc/qw_sign
./usb_gadget/g1/os_desc/b_vendor_code
./usb_gadget/g1/os_desc/use
./usb_gadget/g1/strings
./usb_gadget/g1/strings/0x409
./usb_gadget/g1/strings/0x409/serialnumber
./usb_gadget/g1/strings/0x409/product
./usb_gadget/g1/strings/0x409/manufacturer
./usb_gadget/g1/configs
./usb_gadget/g1/configs/c.1
./usb_gadget/g1/configs/c.1/mass_storage.0
./usb_gadget/g1/configs/c.1/strings
./usb_gadget/g1/configs/c.1/strings/0x409
./usb_gadget/g1/configs/c.1/strings/0x409/configuration
./usb_gadget/g1/configs/c.1/bmAttributes
./usb_gadget/g1/configs/c.1/MaxPower
./usb_gadget/g1/functions
./usb_gadget/g1/functions/mass_storage.0
./usb_gadget/g1/functions/mass_storage.0/lun.0
./usb_gadget/g1/functions/mass_storage.0/lun.0/inquiry_string
./usb_gadget/g1/functions/mass_storage.0/lun.0/nofua
./usb_gadget/g1/functions/mass_storage.0/lun.0/cdrom
./usb_gadget/g1/functions/mass_storage.0/lun.0/removable
./usb_gadget/g1/functions/mass_storage.0/lun.0/ro
./usb_gadget/g1/functions/mass_storage.0/lun.0/file
./usb_gadget/g1/functions/mass_storage.0/stall
./usb_gadget/g1/UDC
./usb_gadget/g1/bcdUSB
./usb_gadget/g1/bcdDevice
./usb_gadget/g1/idProduct
./usb_gadget/g1/idVendor
./usb_gadget/g1/bMaxPacketSize0
./usb_gadget/g1/bDeviceProtocol
./usb_gadget/g1/bDeviceSubClass
./usb_gadget/g1/bDeviceClass

  • 查看当前的UDC
    可见当前的板子上有两个UDC,ci_hdrc.0gadget-cdns3

    1
    2
    3
    4
    130|@android:/config # ll /sys/class/udc/
    total 0
    lrwxrwxrwx 1 root root 0 1999-11-30 00:09 ci_hdrc.0 -> ../../devices/platform/5b0d0000.usb/ci_hdrc.0/udc/ci_hdrc.0
    lrwxrwxrwx 1 root root 0 1999-11-30 00:09 gadget-cdns3 -> ../../devices/platform/5b110000.usb3/gadget-cdns3/udc/gadget-cdns3
  • 绑定到UDC,使能gadget
    将UDC切换至device模式,这里使用OTG ID pin来实现切换。

    1
    2
    # echo ci_hdrc.0 > usb_gadget/g1/UDC
    # echo 1 > /sys/class/gpio/gpio358/value

验证结果

将配置好的开发板与ubuntu连接,从ubuntu上的串口可以看到如下信息,表示已将开发板配置成一个mass storage的设备了。

1
2
3
4
5
6
7
8
9
[95705.390004] usb 1-11: USB disconnect, device number 28
[95708.606717] usb 1-11: new high-speed USB device number 29 using xhci_hcd
[95708.756934] usb 1-11: New USB device found, idVendor=18d1, idProduct=4ee2
[95708.756941] usb 1-11: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[95708.756946] usb 1-11: Product: xxx_product
[95708.756950] usb 1-11: Manufacturer: xxx
[95708.756953] usb 1-11: SerialNumber: 123456789
[95708.766595] usb-storage 1-11:1.0: USB Mass Storage device detected
[95708.766798] scsi host6: usb-storage 1-11:1.0

当然,上述的结果是ubuntu只识别到一个mass storage的设备,但是没有识别看分区表,所以没有看到相应的磁盘信息。想要看到磁盘信息,可以更进一步的设置mass_storage的backen file属性。


定制分区

在上面创建functions步骤之后,执行以下的命令,为mass storage创建2个分区,分区的backing file是开发板上的/dev/block/mmcblk0p1/dev/block/mmcblk0p2,也就是开发板上的system分区和data分区。

1
2
3
4
mkdir usb_gadget/g1/functions/mass_storage.0/partition.2
mkdir usb_gadget/g1/functions/mass_storage.0/lun.1
echo /dev/block/mmcblk0p1 > usb_gadget/g1/functions/mass_storage.0/lun.0/file
echo /dev/block/mmcblk0p2 > usb_gadget/g1/functions/mass_storage.0/lun.1/file

所有配置完成之后,插入到ubuntu后,可以看到能识别去新的分区信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
130 victor@victor-HP:/mnt⟫ sudo dmesg -c
[40873.009026] EXT4-fs (sdc): mounted filesystem with ordered data mode. Opts: (null)
[41094.127318] usb 1-11: USB disconnect, device number 23
[41094.128072] print_req_error: I/O error, dev sdc, sector 0
[41094.131049] sd 6:0:0:0: [sdc] Synchronizing SCSI cache
[41094.131118] sd 6:0:0:0: [sdc] Synchronize Cache(10) failed: Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK
[41466.480635] usb 1-11: new high-speed USB device number 24 using xhci_hcd
[41466.630904] usb 1-11: New USB device found, idVendor=18d1, idProduct=4ee2
[41466.630911] usb 1-11: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[41466.630915] usb 1-11: Product: xxx_product
[41466.630919] usb 1-11: Manufacturer: xxx
[41466.630923] usb 1-11: SerialNumber: 123456789
[41466.640789] usb-storage 1-11:1.0: USB Mass Storage device detected
[41466.641062] scsi host7: usb-storage 1-11:1.0
[41467.645699] scsi 7:0:0:0: Direct-Access Linux File-Stor Gadget 0414 PQ: 0 ANSI: 2
[41467.646291] scsi 7:0:0:1: Direct-Access Linux File-Stor Gadget 0414 PQ: 0 ANSI: 2
[41467.646826] scsi 7:0:0:2: Direct-Access Linux File-Stor Gadget 0414 PQ: 0 ANSI: 2
[41467.647387] sd 7:0:0:0: Attached scsi generic sg2 type 0
[41467.647764] sd 7:0:0:1: Attached scsi generic sg3 type 0
[41467.648144] sd 7:0:0:0: Power-on or device reset occurred
[41467.648173] sd 7:0:0:2: Attached scsi generic sg4 type 0
[41467.649026] sd 7:0:0:1: Power-on or device reset occurred
[41467.649555] sd 7:0:0:2: Power-on or device reset occurred
[41467.650006] sd 7:0:0:0: [sdd] 1048576 512-byte logical blocks: (537 MB/512 MiB)
[41467.650766] sd 7:0:0:1: [sde] 524288 512-byte logical blocks: (268 MB/256 MiB)
[41467.651726] sd 7:0:0:0: [sdd] Write Protect is off
[41467.651731] sd 7:0:0:0: [sdd] Mode Sense: 0f 00 00 00
[41467.651929] sd 7:0:0:1: [sde] Write Protect is off
[41467.651933] sd 7:0:0:1: [sde] Mode Sense: 0f 00 00 00
[41467.652327] sd 7:0:0:2: [sdf] Attached SCSI removable disk
[41467.652581] sd 7:0:0:0: [sdd] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[41467.652837] sd 7:0:0:1: [sde] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[41467.673305] sd 7:0:0:1: [sde] Attached SCSI removable disk
[41467.674915] sd 7:0:0:0: [sdd] Attached SCSI removable disk


参考

上述的配置过程太繁琐了,在Android上,基于configfs有专门的init.rc在启动过程中去配置对应的configurationfunction,比如说init.usb.rc,里面包含了一系列gadget的配置方法。在后面的文章中,将详细讲述每条命令背后的实现原理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
on boot
write /config/usb_gadget/g1/strings/0x409/serialnumber ${ro.serialno}
write /config/usb_gadget/g1/strings/0x409/manufacturer ${ro.product.manufacturer}
write /config/usb_gadget/g1/strings/0x409/product ${ro.product.model}

setprop sys.usb.configfs 1

# OS DESCRIPTORS
#===============
# OS STRING
#----------
write /config/usb_gadget/g1/os_desc/b_vendor_code 1
write /config/usb_gadget/g1/os_desc/qw_sign "MSFT100"
# use os desc or not is up to each usb functions respectively
# write /config/usb_gadget/g1/os_desc/use 1

# MAKE b.1 THE ONE ASSOCIATED WITH OS DESCRIPTORS
#------------------------------------------------
symlink /config/usb_gadget/g1/configs/b.1 /config/usb_gadget/g1/os_desc/b1

# ci_hdrc.0 is the fixed UDC name
setprop sys.usb.controller ci_hdrc.0

on fs
mkdir /dev/usb-ffs 0770 shell shell
mkdir /dev/usb-ffs/adb 0770 shell shell
# mount the configfs on /config
mount configfs none /config mode=0755
mkdir /config/usb_gadget/g1
mkdir /config/usb_gadget/g1/configs/b.1
# mkdir for functions needed
# this will call each gadget's alloc_inst()
mkdir /config/usb_gadget/g1/functions/ffs.adb
mkdir /config/usb_gadget/g1/functions/mtp.gs0
mkdir /config/usb_gadget/g1/functions/ptp.gs1
mkdir /config/usb_gadget/g1/functions/accessory.gs2
mkdir /config/usb_gadget/g1/functions/audio_source.gs3
mkdir /config/usb_gadget/g1/functions/rndis.gs4
mkdir /config/usb_gadget/g1/functions/midi.gs5
mkdir /config/usb_gadget/g1/strings/0x409
mkdir /config/usb_gadget/g1/configs/b.1/strings/0x409
# The mount of functionfs for adb must be put AFTER the mkdir for functions in configfs

on property:sys.usb.config=none && property:sys.usb.configfs=1
write /config/usb_gadget/g1/os_desc/use 0

on property:sys.usb.ffs.ready=1 && property:sys.usb.config=adb && property:sys.usb.configfs=1
write /config/usb_gadget/g1/idProduct 0x4ee7
write /config/usb_gadget/g1/idVendor 0x18d1

on property:sys.usb.config=mtp && property:sys.usb.configfs=1
write /config/usb_gadget/g1/functions/mtp.gs0/os_desc/interface.MTP/compatible_id "MTP"
write /config/usb_gadget/g1/os_desc/use 1
write /config/usb_gadget/g1/idProduct 0x4ee1
write /config/usb_gadget/g1/idVendor 0x18d1


参考资料

Title:usb gadget configfs 验证

Author:Victor Huang

Time:2019-08-11 / 14:08

Link:http://wowothink.com/a64c6a27/

License: Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)