linux usb gadget驱动详解(一)
由于PC的推广,USB(通用串行总线)是我们最熟知的通信总线规范之一,其他的还有诸如以太网、PCIE总线和RS232串口等。这里我们主要讨论USB。
USB是一个主从通信架构,但只能一主多从。其中usb主机控制器有ECHI(https://www.intel.com/content/www/us/en/products/docs/io/universal-serial-bus/ehci-specification.html)等规范支持,而usb设备则包含普通usb设备和hub两种。USB2.0规范、USB class等规范文档可以从https://www.usb.org/获得。另外,还有ULPI、UTMI接口(类比RGMII、MII)支持USB phy(类比以太网phy)与ip核(https://opencores.org/有开源的verilog USB ip核)对接。
linux usb驱动框架中包含很多有趣的玩意,其中drivers/usb/gadget就是其中一个。gadget是usb设备驱动,可以按照USB规范和设备类进行配置,使其成为各种各样的通用USB设备,如键鼠(HID class)、U盘(mass storage class)、网卡(CDC class)、摄像头(Video class)等。
在开始gadget源码分析前,我们先玩一下它!
先声明一下,我们分析的是linux4.4.19版本的gadget源码,其他版本的可能会有些出入,但原理上是相通的。测试平台为通用的硬件平台BeagleBone Black。
要使用linux内核为我们准备的gadget驱动demo,我们主要关注legacy这个文件夹,这个是遗留下来的驱动,已不建议使用了,以后的linux版本或许会消失。但我们这里先从传统入手!
编译内核前,make menuconfig修改一下配置。在usb菜单中选中gadget编译为模块(M),这样内核就可以编译出gadget驱动。编译好后,会在legacy下生成g_xxx.ko。譬如U盘设备驱动为g_mass_storage.ko。而function文件夹则是功能接口(interface)的具体实现,生成形如usb_f_xxx.ko,对应U盘驱动为usb_f_mass_storage.ko。
下面我们测试U盘设备驱动:
先ssh登录到BeagleBone Black板(简称BBB)上进行如下操作,生成一个FAT32格式的img,并挂载到sda文件夹上。
mkdir -p /var/sdcard;
cd /var/sdcard;
mkdir sda;
dd if=/dev/zero of=/var/sdcard/disk.img bs=1M count=20;
mkdosfs -F 32 disk.img
mount -t vfat -o sync /var/sdcard/disk.img /var/sdcard/sda
此时/var/sdcard/sda为FAT32格式的文件系统,这样我们就能在linux系统里查看disk.img里包含的文件,便于测试验证!
然后在BBB上加载USB相关驱动:
modprobe musb_am335x
modprobe g_mass_storage file=/var/sdcard/disk.img
此时,U盘设备驱动启动,同时指定操作文件为/var/sdcard/disk.img,这样的目的是让PC识别成一个“可移动磁盘”,同时在PC上读写磁盘时,实质上是对BBB板内的/var/sdcard/disk.img进行操作。
在BBB板上lsmod查看当前已加载的驱动:
<lsmod
g_mass_storage 4414 0
usb_f_mass_storage 37916 2 g_mass_storage
libcomposite 44392 2 usb_f_mass_storage,g_mass_storage
musb_dsps 8235 0
musb_hdrc 71550 1 musb_dsps
udc_core 12063 2 musb_hdrc,libcomposite
usbcore 195125 2 musb_hdrc,usbhid
musb_am335x 1426 0
USB线缆接入PC后,我们就能看到PC识别出“可移动磁盘”。我们可以拖一个文件进去,或者在其上创建文件。在BBB板上,我们在已挂载的/var/sdcard/sda上看到刚从PC上拷贝过来的文件。
最后,上面说过,这种方式是legacy的,现已不推荐使用。欲知后事如何,且听下回分解!我们《linux usb gadget驱动详解(二)》见。
更多推荐
所有评论(0)