实现Linux usb复合从机设备

812 阅读2分钟

    Linux端当需要作为从机时,我们可以根据内核配置编译gadget驱动模块,如libcomposite.ko,usb_f_uac1.ko,g_audio.ko, insmod或modprobe加载驱动模块即可拥有对应的外置声卡的功能在这里插入图片描述

    那么我们需要拥有多功能的复合usb从机设备时该怎么办呢,有人可能会想到多次加载模块,实际上这样是实现不了功能叠加的,因为usb驱动里的UDC(USB设备控制器)数量不够,会报错 udc资源已占用。所以使用insmod、modprobe等加载模块的方式一次只能有一个功能(内核定值好的三功能模块g_multi.ko除外),所以需要使用另一种方式USB Gadget Configfs

使用USB Gadget Configfs实现linux复合从机设备

    linux内有一个Gadget Configfs,一种文件系统规则,来供使用者任意配置具有需要的组合功能的复合设备,这里需要确保内核配置FunctionFs是打开的。
在这里插入图片描述     需要注意的USB Gadget Configfs创建usb从机设备和insmod加载方式使用的ko文件不同,这里需要有usb_f_ 命令的驱动模块,如没有也需在内核中配置并编译生成。脚本内容(三功能的usb从机设备):

modprobe gadgetfs
modprobe libcomposite

mount -t configfs none /sys/kernel/config

# create a gadget
mkdir /sys/kernel/config/usb_gadget/g1
# cd to its configfs node
cd /sys/kernel/config/usb_gadget/g1
# configure it (vid/pid can be anything if USB Class is used for driver compat)
echo 0x2b73 > idVendor
echo 0x0010 > idProduct

echo 0x0100 > bcdDevice 
echo 0x0200 > bcdUSB 
echo 0x00 > bDeviceClass
echo 0x00 > bDeviceSubClass
echo 0x00 > bDeviceProtocol
echo 0x40 > bMaxPacketSize0

# configure its serial/mfg/product
mkdir strings/0x409
echo "Pioneer DJ Corporation" > strings/0x409/manufacturer
echo "DDJ-WeGO4" > strings/0x409/product
echo "RFMP000209CN" > strings/0x409/serialnumber

# create a config
mkdir configs/c.1
# configure it with attributes if needed
echo 0x45 > configs/c.1/MaxPower

# create the function (name must match a usb_f_<name> module such as 'acm')
mkdir functions/uac1_legacy.0
mkdir functions/midi.0

mkdir -p functions/hid.usb0
echo 0x00 > functions/hid.usb0/protocol
echo 0x00 > functions/hid.usb0/subclass
echo 0x40 > functions/hid.usb0/report_length

echo -ne \\x06\\xa0\\xff\\x09\\x01\\xa1\\x01\\x09\\x02\\xa1\\x00\\x06\\xa1\\xff\\x09\\x03\\x09\\x04\\x15\\x80\\x25\\x7f\\x35\\x00\\x45\\xff\\x75\\x08\\x95\\x40\\x81\\x02\\x09\\x05\\x09\\x06\\x15\\x80\\x25\\x7f\\x35\\x00\\x45\\xff\\x75\\x08\\x95\\x40\\x91\\x02\\xc0\\xc0 > functions/hid.usb0/report_desc


# associate function with config
ln -s functions/uac1_legacy.0 configs/c.1
ln -s functions/midi.0 configs/c.1

ln -s functions/hid.usb0 configs/c.1/

# enable gadget by binding it to a UDC from /sys/class/udc
echo ci_hdrc.0 > UDC
# to unbind it: echo "" UDC; sleep 1; rm -rf /sys/kernel/config/usb_gadget/

参考linux官方文档: www.kernel.org/doc/html/la…
events.static.linuxfound.org/sites/event…