Gadget 测试

本文档总结了 Gadget 提供的 USB 功能的基本测试信息。

1. ACM 功能

此功能由 usb_f_acm.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“acm”。ACM 功能在其功能目录中只提供一个属性

port_num

此属性为只读。

系统中最多可以有 4 个 ACM/通用串行/OBEX 端口。

测试 ACM 功能

在主机上

cat > /dev/ttyACM<X>

在设备上

cat /dev/ttyGS<Y>

然后反过来

在设备上

cat > /dev/ttyGS<Y>

在主机上

cat /dev/ttyACM<X>

2. ECM 功能

此功能由 usb_f_ecm.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“ecm”。ECM 功能在其功能目录中提供以下属性

ifname

与此功能实例关联的网络设备接口名称

qmult

用于高速和超高速的队列长度乘数

host_addr

此 USB 以太网链路主机端的 MAC 地址

dev_addr

此 USB 以太网链路设备端的 MAC 地址

创建 functions/ecm.<实例名称> 后,它们包含默认值:qmult 为 5,dev_addr 和 host_addr 随机选择。如果功能未绑定,则可以写入 ifname。写入必须是接口模式,例如“usb%d”,这将导致网络核心选择下一个空闲的 usbX 接口。默认情况下,它设置为“usb%d”。

测试 ECM 功能

配置设备和主机的 IP 地址。然后

在设备上

ping <host's IP>

在主机上

ping <device's IP>

3. ECM 子集功能

此功能由 usb_f_ecm_subset.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“geth”。ECM 子集功能在其功能目录中提供以下属性

ifname

与此功能实例关联的网络设备接口名称

qmult

用于高速和超高速的队列长度乘数

host_addr

此 USB 以太网链路主机端的 MAC 地址

dev_addr

此 USB 以太网链路设备端的 MAC 地址

创建 functions/ecm.<实例名称> 后,它们包含默认值:qmult 为 5,dev_addr 和 host_addr 随机选择。如果功能未绑定,则可以写入 ifname。写入必须是接口模式,例如“usb%d”,这将导致网络核心选择下一个空闲的 usbX 接口。默认情况下,它设置为“usb%d”。

测试 ECM 子集功能

配置设备和主机的 IP 地址。然后

在设备上

ping <host's IP>

在主机上

ping <device's IP>

4. EEM 功能

此功能由 usb_f_eem.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“eem”。EEM 功能在其功能目录中提供以下属性

ifname

与此功能实例关联的网络设备接口名称

qmult

用于高速和超高速的队列长度乘数

host_addr

此 USB 以太网链路主机端的 MAC 地址

dev_addr

此 USB 以太网链路设备端的 MAC 地址

创建 functions/eem.<实例名称> 后,它们包含默认值:qmult 为 5,dev_addr 和 host_addr 随机选择。如果功能未绑定,则可以写入 ifname。写入必须是接口模式,例如“usb%d”,这将导致网络核心选择下一个空闲的 usbX 接口。默认情况下,它设置为“usb%d”。

测试 EEM 功能

配置设备和主机的 IP 地址。然后

在设备上

ping <host's IP>

在主机上

ping <device's IP>

5. FFS 功能

此功能由 usb_f_fs.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“ffs”。该功能目录有意为空且不可修改。

创建目录后,系统中将有一个新的 FunctionFS 实例(一个“设备”)可用。一旦“设备”可用,用户应遵循使用 FunctionFS 的标准程序(挂载它,运行实现该功能的完整用户空间进程)。应通过向 usb_gadget//UDC 写入合适的字符串来启用 gadget。

FFS 功能在其功能目录中只提供一个属性

ready

此属性为只读,表示功能是否准备好(1)使用,例如,如果用户空间已将描述符和字符串写入 ep0,则可以启用 gadget。

测试 FFS 功能

在设备上:启动功能的 Sigil 用户空间守护程序,启用 gadget

在主机上:使用设备提供的 USB 功能

6. HID 功能

此功能由 usb_f_hid.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“hid”。HID 功能在其功能目录中提供以下属性

protocol

要使用的 HID 协议

report_desc

HID 报告中要使用的数据,但通过 /dev/hidg 传递的数据除外

report_length

HID 报告长度

subclass

要使用的 HID 子类

对于键盘,协议和子类都是 1,report_length 是 8,而 report_desc 是

$ hd my_report_desc
00000000  05 01 09 06 a1 01 05 07  19 e0 29 e7 15 00 25 01  |..........)...%.|
00000010  75 01 95 08 81 02 95 01  75 08 81 03 95 05 75 01  |u.......u.....u.|
00000020  05 08 19 01 29 05 91 02  95 01 75 03 91 03 95 06  |....).....u.....|
00000030  75 08 15 00 25 65 05 07  19 00 29 65 81 00 c0     |u...%e....)e...|
0000003f

这样的字节序列可以使用 echo 存储到属性中

$ echo -ne \\x05\\x01\\x09\\x06\\xa1.....

测试 HID 功能

设备

  • 创建 gadget

  • 将 gadget 连接到主机,最好不是用于控制该 gadget 的主机

  • 运行一个写入 /dev/hidg 的程序,例如在Linux USB HID gadget 驱动程序中找到的用户空间程序

    $ ./hid_gadget_test /dev/hidg0 keyboard
    

主机

  • 观察来自 gadget 的按键

7. LOOPBACK 功能

此功能由 usb_f_ss_lb.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“Loopback”。LOOPBACK 功能在其功能目录中提供以下属性

qlen

回环队列深度

bulk_buflen

缓冲区长度

测试 LOOPBACK 功能

设备:运行 gadget

主机:test-usb (tools/usb/testusb.c)

8. 大容量存储功能

此功能由 usb_f_mass_storage.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“mass_storage”。大容量存储功能在其目录中提供以下属性:文件

stall

设置为允许功能停止批量端点。在一些已知无法正常工作的 USB 设备上禁用。您应该将其设置为 true。

num_buffers

管道缓冲区数量。有效数字为 2..4。仅在设置 CONFIG_USB_GADGET_DEBUG_FILES 时可用。

以及一个对应于 SCSI LUN #0 的默认 lun.0 目录。

可以使用 mkdir 添加新的 LUN

$ mkdir functions/mass_storage.0/partition.5

LUN 编号不必连续,但默认创建的 LUN #0 除外。最多可以指定 8 个 LUN,并且它们都必须遵循 <名称>.<数字> 方案命名。数字可以是 0..8。一个好的约定可能是将 LUN 命名为“lun.<数字>”,尽管这不是强制性的。

在每个 LUN 目录中都有以下属性文件

file

LUN 后备文件的路径。如果 LUN 未标记为可移动,则必需。

ro

指定 LUN 访问权限为只读的标志。如果启用了 CD-ROM 仿真以及无法以读/写模式打开“filename”时,则隐含此设置。

removable

指定 LUN 应指示为可移动的标志。

cdrom

指定 LUN 应报告为 CD-ROM 的标志。

nofua

指定 SCSI WRITE(10,12) 中的 FUA 标志的标志

forced_eject

此只写文件仅在功能激活时有用。它导致后备文件从 LUN 中强制分离,无论主机是否允许。写入任何非零字节数都将导致弹出。

测试大容量存储功能

设备:连接 gadget,启用它 主机:dmesg,查看 USB 驱动器出现(如果系统配置为自动挂载)

9. MIDI 功能

此功能由 usb_f_midi.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“midi”。MIDI 功能在其功能目录中提供以下属性

buflen

MIDI 缓冲区长度

id

USB MIDI 适配器的 ID 字符串

in_ports

MIDI 输入端口数量

index

USB MIDI 适配器的索引值

out_ports

MIDI 输出端口数量

qlen

USB 读取请求队列长度

测试 MIDI 功能

有两种情况:从 gadget 播放 MIDI 到主机,以及从主机播放 MIDI 到 gadget。

  1. 从 gadget 播放 MIDI 到主机

主机

$ arecordmidi -l
 Port    Client name                      Port name
 14:0    Midi Through                     Midi Through Port-0
 24:0    MIDI Gadget                      MIDI Gadget MIDI 1
$ arecordmidi -p 24:0 from_gadget.mid

gadget

$ aplaymidi -l
 Port    Client name                      Port name
 20:0    f_midi                           f_midi

$ aplaymidi -p 20:0 to_host.mid
  1. 从主机播放 MIDI 到 gadget

gadget

$ arecordmidi -l
 Port    Client name                      Port name
 20:0    f_midi                           f_midi

$ arecordmidi -p 20:0 from_host.mid

主机

$ aplaymidi -l
 Port    Client name                      Port name
 14:0    Midi Through                     Midi Through Port-0
 24:0    MIDI Gadget                      MIDI Gadget MIDI 1

$ aplaymidi -p24:0 to_gadget.mid

from_gadget.mid 的声音应与 to_host.mid 相同。

from_host.mid 的声音应与 to_gadget.mid 相同。

MIDI 文件可以使用例如已安装的 timidity 播放到扬声器/耳机

$ aplaymidi -l
 Port    Client name                      Port name
 14:0    Midi Through                     Midi Through Port-0
 24:0    MIDI Gadget                      MIDI Gadget MIDI 1
128:0    TiMidity                         TiMidity port 0
128:1    TiMidity                         TiMidity port 1
128:2    TiMidity                         TiMidity port 2
128:3    TiMidity                         TiMidity port 3

$ aplaymidi -p 128:0 file.mid

MIDI 端口可以使用 aconnect 工具进行逻辑连接,例如

$ aconnect 24:0 128:0 # try it on the host

将 gadget 的 MIDI 端口连接到 timidity 的 MIDI 端口后,在 gadget 侧使用 aplaymidi -l 播放的任何内容都可以在主机的扬声器/耳机中听到。

10. NCM 功能

此功能由 usb_f_ncm.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“ncm”。NCM 功能在其功能目录中提供以下属性

ifname

与此功能实例关联的网络设备接口名称

qmult

用于高速和超高速的队列长度乘数

host_addr

此 USB 以太网链路主机端的 MAC 地址

dev_addr

此 USB 以太网链路设备端的 MAC 地址

max_segment_size

P2P 连接所需的段大小。这将把 MTU 设置为 14 字节

创建 functions/ncm.<实例名称> 后,它们包含默认值:qmult 为 5,dev_addr 和 host_addr 随机选择。如果功能未绑定,则可以写入 ifname。写入必须是接口模式,例如“usb%d”,这将导致网络核心选择下一个空闲的 usbX 接口。默认情况下,它设置为“usb%d”。

测试 NCM 功能

配置设备和主机的 IP 地址。然后

在设备上

ping <host's IP>

在主机上

ping <device's IP>

11. OBEX 功能

此功能由 usb_f_obex.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“obex”。OBEX 功能在其功能目录中只提供一个属性

port_num

此属性为只读。

系统中最多可以有 4 个 ACM/通用串行/OBEX 端口。

测试 OBEX 功能

在设备上

seriald -f /dev/ttyGS<Y> -s 1024

在主机上

serialc -v <vendorID> -p <productID> -i<interface#> -a1 -s1024 \
        -t<out endpoint addr> -r<in endpoint addr>

其中 seriald 和 serialc 是 Felipe 的实用程序,可在此处找到

12. PHONET 功能

此功能由 usb_f_phonet.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“phonet”。PHONET 功能在其功能目录中只提供一个属性

ifname

与此功能实例关联的网络设备接口名称

测试 PHONET 功能

在没有特定硬件的情况下无法测试 SOCK_STREAM 协议,因此只测试了 SOCK_DGRAM。为了使后者工作,过去我必须应用此处提到的补丁

http://www.spinics.net/lists/linux-usb/msg85689.html

需要以下工具

git://git.gitorious.org/meego-cellular/phonet-utils.git

在主机上

$ ./phonet -a 0x10 -i usbpn0
$ ./pnroute add 0x6c usbpn0
$./pnroute add 0x10 usbpn0
$ ifconfig usbpn0 up

在设备上

$ ./phonet -a 0x6c -i upnlink0
$ ./pnroute add 0x10 upnlink0
$ ifconfig upnlink0 up

然后可以使用测试程序

http://www.spinics.net/lists/linux-usb/msg85690.html

在设备上

$ ./pnxmit -a 0x6c -r

在主机上

$ ./pnxmit -a 0x10 -s 0x6c

结果是应该从主机向设备发送一些数据。然后反过来

在主机上

$ ./pnxmit -a 0x10 -r

在设备上

$ ./pnxmit -a 0x6c -s 0x10

13. RNDIS 功能

此功能由 usb_f_rndis.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“rndis”。RNDIS 功能在其功能目录中提供以下属性

ifname

与此功能实例关联的网络设备接口名称

qmult

用于高速和超高速的队列长度乘数

host_addr

此 USB 以太网链路主机端的 MAC 地址

dev_addr

此 USB 以太网链路设备端的 MAC 地址

创建 functions/rndis.<实例名称> 后,它们包含默认值:qmult 为 5,dev_addr 和 host_addr 随机选择。如果功能未绑定,则可以写入 ifname。写入必须是接口模式,例如“usb%d”,这将导致网络核心选择下一个空闲的 usbX 接口。默认情况下,它设置为“usb%d”。

测试 RNDIS 功能

配置设备和主机的 IP 地址。然后

在设备上

ping <host's IP>

在主机上

ping <device's IP>

14. 串行功能

此功能由 usb_f_gser.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“gser”。串行功能在其功能目录中只提供一个属性

port_num

此属性为只读。

系统中最多可以有 4 个 ACM/通用串行/OBEX 端口。

测试串行功能

在主机上

insmod usbserial
echo VID PID >/sys/bus/usb-serial/drivers/generic/new_id

在主机上

cat > /dev/ttyUSB<X>

在目标设备上

cat /dev/ttyGS<Y>

然后反过来

在目标设备上

cat > /dev/ttyGS<Y>

在主机上

cat /dev/ttyUSB<X>

15. SOURCESINK 功能

此功能由 usb_f_ss_lb.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“SourceSink”。SOURCESINK 功能在其功能目录中提供以下属性

pattern

0(全零)、1(mod63)、2(无)

isoc_interval

1..16

isoc_maxpacket

0 - 1023 (全速), 0 - 1024 (高速/超高速)

isoc_mult

0..2 (仅限高速/超高速)

isoc_maxburst

0..15 (仅限超高速)

bulk_buflen

缓冲区长度

bulk_qlen

批量队列深度

iso_qlen

同步队列深度

测试 SOURCESINK 功能

设备:运行 gadget

主机:test-usb (tools/usb/testusb.c)

16. UAC1 功能(旧版实现)

此功能由 usb_f_uac1_legacy.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“uac1_legacy”。UAC1 功能在其功能目录中提供以下属性

audio_buf_size

音频缓冲区大小

fn_cap

捕获 PCM 设备文件名

fn_cntl

控制设备文件名

fn_play

播放 PCM 设备文件名

req_buf_size

ISO OUT 端点请求缓冲区大小

req_count

ISO OUT 端点请求计数

这些属性具有合理的默认值。

测试 UAC1 功能

设备:运行 gadget

主机

aplay -l # should list our USB Audio Gadget

17. UAC2 功能

此功能由 usb_f_uac2.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“uac2”。UAC2 功能在其功能目录中提供以下属性

c_chmask

捕获通道掩码

c_srate

捕获采样率列表(逗号分隔)

c_ssize

捕获样本大小(字节)

c_sync

捕获同步类型(异步/自适应)

c_mute_present

捕获静音控制启用

c_volume_present

捕获音量控制启用

c_volume_min

捕获音量控制最小值(1/256 dB)

c_volume_max

捕获音量控制最大值(1/256 dB)

c_volume_res

捕获音量控制分辨率(1/256 dB)

c_hs_bint

HS/SS 的捕获 bInterval(1-4:固定,0:自动)

fb_max

异步模式下的最大额外带宽

p_chmask

播放通道掩码

p_srate

播放采样率列表(逗号分隔)

p_ssize

播放样本大小(字节)

p_mute_present

播放静音控制启用

p_volume_present

播放音量控制启用

p_volume_min

播放音量控制最小值(1/256 dB)

p_volume_max

播放音量控制最大值(1/256 dB)

p_volume_res

播放音量控制分辨率(1/256 dB)

p_hs_bint

HS/SS 的播放 bInterval(1-4:固定,0:自动)

req_number

为捕获和播放预分配的请求数量

function_name

接口名称

if_ctrl_name

拓扑控制名称

clksrc_in_name

输入时钟名称

clksrc_out_name

输出时钟名称

p_it_name

播放输入终端名称

p_it_ch_name

播放输入首个通道名称

p_ot_name

播放输出终端名称

p_fu_vol_name

播放功能单元名称

c_it_name

捕获输入终端名称

c_it_ch_name

捕获输入首个通道名称

c_ot_name

捕获输出终端名称

c_fu_vol_name

捕获功能单元名称

c_terminal_type

捕获终端类型代码

p_terminal_type

播放终端类型代码

这些属性具有合理的默认值。

测试 UAC2 功能

设备:运行 gadget 主机:aplay -l # 应列出我们的 USB 音频 Gadget

此功能不需要实际硬件支持,它只是向/从主机发送音频数据流。为了在设备端实际听到声音,必须在设备端使用类似以下命令

$ arecord -f dat -t wav -D hw:2,0 | aplay -D hw:0,0 &

例如

$ arecord -f dat -t wav -D hw:CARD=UAC2Gadget,DEV=0 | \
  aplay -D default:CARD=OdroidU3

18. UVC 功能

此功能由 usb_f_uvc.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“uvc”。UVC 功能在其功能目录中提供以下属性

streaming_interval

数据传输轮询端点的时间间隔

streaming_maxburst

超高速伴随描述符的 bMaxBurst

streaming_maxpacket

选择此配置时,此端点能够发送或接收的最大包大小

function_name

接口名称

还有“control”和“streaming”子目录,每个子目录都包含许多其子目录。提供了一些合理的默认值,但用户必须提供以下内容

控制头

在 control/header 中创建,从 control/class/fs 和/或 control/class/ss 链接

流式传输头

在 streaming/header 中创建,从 streaming/class/fs 和/或 streaming/class/hs 和/或 streaming/class/ss 链接

格式描述

在 streaming/mjpeg 和/或 streaming/uncompressed 中创建

帧描述

在 streaming/mjpeg/<格式> 和/或 streaming/uncompressed/<格式> 中创建

每个帧描述都包含帧间隔规范,每个这样的规范由多行组成,每行中都有一个间隔值。上述规则最好通过示例进行说明

# mkdir functions/uvc.usb0/control/header/h
# cd functions/uvc.usb0/control/
# ln -s header/h class/fs
# ln -s header/h class/ss
# mkdir -p functions/uvc.usb0/streaming/uncompressed/u/360p
# cat <<EOF > functions/uvc.usb0/streaming/uncompressed/u/360p/dwFrameInterval
666666
1000000
5000000
EOF
# cd $GADGET_CONFIGFS_ROOT
# mkdir functions/uvc.usb0/streaming/header/h
# cd functions/uvc.usb0/streaming/header/h
# ln -s ../../uncompressed/u
# cd ../../class/fs
# ln -s ../../header/h
# cd ../../class/hs
# ln -s ../../header/h
# cd ../../class/ss
# ln -s ../../header/h

测试 UVC 功能

设备:运行 gadget,modprobe vivid

# uvc-gadget -u /dev/video<uvc video node #> -v /dev/video<vivid video node #>
其中 uvc-gadget 是此程序

http://git.ideasonboard.org/uvc-gadget.git

带有这些补丁

主机

luvcview -f yuv

19. 打印机功能

此功能由 usb_f_printer.ko 模块提供。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“printer”。打印机功能在其功能目录中提供以下属性

pnp_string

要以 pnp 字符串形式传递给主机的数据

q_len

每个端点的请求数量

测试打印机功能

最基本的测试

设备:运行 gadget

# ls -l /devices/virtual/usb_printer_gadget/

应显示 g_printer<数字>。

如果 udev 处于活动状态,则 /dev/g_printer<数字> 应自动出现。

主机

如果 udev 处于活动状态,则例如 /dev/usb/lp0 应出现。

主机->设备传输

设备

# cat /dev/g_printer<number>

主机

# cat > /dev/usb/lp0

设备->主机传输

# cat > /dev/g_printer<number>

主机

# cat /dev/usb/lp0

可以使用Linux USB 打印机 Gadget 驱动程序中描述的 prn_example 进行更高级的测试。

20. UAC1 功能(虚拟 ALSA 声卡,使用 u_audio API)

此功能由 usb_f_uac1.ko 模块提供。它将创建一个虚拟 ALSA 声卡,音频流将简单地从该声卡输入和输出。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“uac1”。UAC1 功能在其功能目录中提供以下属性

c_chmask

捕获通道掩码

c_srate

捕获采样率列表(逗号分隔)

c_ssize

捕获样本大小(字节)

c_mute_present

捕获静音控制启用

c_volume_present

捕获音量控制启用

c_volume_min

捕获音量控制最小值(1/256 dB)

c_volume_max

捕获音量控制最大值(1/256 dB)

c_volume_res

捕获音量控制分辨率(1/256 dB)

p_chmask

播放通道掩码

p_srate

播放采样率列表(逗号分隔)

p_ssize

播放样本大小(字节)

p_mute_present

播放静音控制启用

p_volume_present

播放音量控制启用

p_volume_min

播放音量控制最小值(1/256 dB)

p_volume_max

播放音量控制最大值(1/256 dB)

p_volume_res

播放音量控制分辨率(1/256 dB)

req_number

捕获和播放预分配请求的数量

function_name

接口名称

p_it_name

播放输入终端名称

p_it_ch_name

播放通道名称

p_ot_name

播放输出终端名称

p_fu_vol_name

播放静音/音量功能单元名称

c_it_name

捕获输入终端名称

c_it_ch_name

捕获通道名称

c_ot_name

捕获输出终端名称

c_fu_vol_name

捕获静音/音量功能单元名称

这些属性具有合理的默认值。

测试 UAC1 功能

设备:运行 gadget 主机:aplay -l # 应列出我们的 USB 音频 Gadget

此功能不需要实际硬件支持,它只是向/从主机发送音频数据流。为了在设备端实际听到声音,必须在设备端使用类似以下命令

$ arecord -f dat -t wav -D hw:2,0 | aplay -D hw:0,0 &

例如

$ arecord -f dat -t wav -D hw:CARD=UAC1Gadget,DEV=0 | \
  aplay -D default:CARD=OdroidU3

21. MIDI2 功能

此功能由 usb_f_midi2.ko 模块提供。它将创建一个包含 UMP rawmidi 设备的虚拟 ALSA 声卡,其中 UMP 数据包被回环。此外,还会创建一个旧版 rawmidi 设备。UMP rawmidi 也与 ALSA 序列器客户端绑定。

功能专用 configfs 接口

创建功能目录时使用的功能名称是“midi2”。midi2 功能在其功能目录中提供以下属性作为声卡顶层信息

process_ump

处理 UMP 流消息的布尔标志(0 或 1)

static_block

静态块的布尔标志(0 或 1)

iface_name

可选接口名称字符串

该目录包含一个名为“ep.0”的子目录,该子目录提供了 UMP 端点的属性(即一对 USB MIDI 端点)

protocol_caps

MIDI 协议功能;1: MIDI 1.0, 2: MIDI 2.0, 或 3: 两种协议都支持

protocol

默认 MIDI 协议(1 或 2)

ep_name

UMP 端点名称字符串

product_id

产品 ID 字符串

manufacturer

制造商 ID 号(24 位)

family

设备家族 ID 号(16 位)

model

设备型号 ID 号(16 位)

sw_revision

软件修订版(32 位)

每个端点子目录都包含一个名为“block.0”的子目录,该子目录表示 Block 0 信息的函数块。其属性为

name

功能块名称字符串

direction

此功能块的方向 1:输入,2:输出,或 3:双向

first_group

第一个 UMP 组号(0-15)

num_groups

此功能块中的组数(1-16)

midi1_first_group

MIDI 1.0 的第一个 UMP 组号(0-15)

midi1_num_groups

MIDI 1.0 的组数(0-16)

ui_hint

此功能块的 UI 提示 0:未知,1:接收方,2:发送方,3:两者

midi_ci_version

支持的 MIDI-CI 版本号(8 位)

is_midi1

旧版 MIDI 1.0 设备 (0-2) 0:MIDI 2.0 设备,1:无限制 MIDI 1.0,或 2:低速 MIDI 1.0

sysex8_streams

SysEx8 流的最大数量(8 位)

active

功能块活动的布尔标志(0 或 1)

如果需要多个功能块,可以通过创建带有相应功能块编号(1、2、...)的子目录“block.”来添加更多功能块。功能块子目录也可以动态删除。请注意,功能块编号必须是连续的。

同样,如果需要多个 UMP 端点,可以通过创建子目录“ep.”来添加更多端点。编号必须是连续的。

为了模拟不支持 UMP v1.1 的旧版 MIDI 2.0 设备,请将 process_ump 标志设置为 0。然后将忽略所有 UMP v1.1 请求。

测试 MIDI2 功能

在设备上:运行 gadget,然后运行

$ cat /proc/asound/cards

将显示一个包含 MIDI2 设备的新声卡。

另一方面,在主机上

$ cat /proc/asound/cards

将显示一个包含 MIDI1 或 MIDI2 设备的新声卡,具体取决于 USB 音频驱动程序配置。

在这两者上,当主机上启用 ALSA 序列器时,您可以找到 UMP MIDI 客户端,例如“MIDI 2.0 Gadget”。

由于驱动程序只是简单地回环数据,因此仅为了测试目的不需要真实设备。

为了测试从 gadget 到主机的 MIDI 输入(例如模拟 MIDI 键盘),您可以发送如下 MIDI 流。

在 gadget 上

$ aconnect -o
....
client 20: 'MIDI 2.0 Gadget' [type=kernel,card=1]
    0 'MIDI 2.0        '
    1 'Group 1 (MIDI 2.0 Gadget I/O)'
$ aplaymidi -p 20:1 to_host.mid

在主机上

$ aconnect -i
....
client 24: 'MIDI 2.0 Gadget' [type=kernel,card=2]
    0 'MIDI 2.0        '
    1 'Group 1 (MIDI 2.0 Gadget I/O)'
$ arecordmidi -p 24:1 from_gadget.mid

如果您有支持 UMP 的应用程序,您也可以使用 UMP 端口发送/接收原始 UMP 数据包。例如,支持 UMP 的 aseqdump 程序可以从 UMP 端口接收。在主机上

$ aseqdump -u 2 -p 24:1
Waiting for data. Press Ctrl+C to end.
Source  Group    Event                  Ch  Data
 24:1   Group  0, Program change          0, program 0, Bank select 0:0
 24:1   Group  0, Channel pressure        0, value 0x80000000

为了测试从主机到 gadget 的 MIDI 输出(例如模拟 MIDI 合成器),它将只是反过来。

在 gadget 上

$ arecordmidi -p 20:1 from_host.mid

在主机上

$ aplaymidi -p 24:1 to_gadget.mid

主机上 altset 0 的 MIDI 1.0 访问受支持,并且在 gadget 上从/向 UMP 数据包进行转换。它仅绑定到功能块 0。

当前操作模式可以在 SND_CTL_IFACE_RAWMIDI 的 ALSA 控制元素“Operation Mode”中观察到。例如

$ amixer -c1 contents
numid=1,iface=RAWMIDI,name='Operation Mode'
  ; type=INTEGER,access=r--v----,values=1,min=0,max=2,step=0
  : values=2

其中 0 = 未使用,1 = MIDI 1.0 (altset 0),2 = MIDI 2.0 (altset 1)。上面的示例显示它正在模式 2 下运行,即 MIDI 2.0。