I.MX6ULL_Linux_驱动篇(53)linux USB驱动

news2024/9/23 23:29:37

I.MX6ULL USB 接口简介

I.MX6ULL 内部集成了两个独立的 USB 控制器,这两个 USB 控制器都支持 OTG 功能。I.MX6ULL 内部 USB 控制器特性如下:
①、有两个 USB2.0 控制器内核分别为 Core0 和 Core1,这两个 Core 分别连接到 OTG1 和OTG2。
②、两个 USB2.0 控制器都支持 HS、 FS 和 LS 模式,不管是主机还是从机模式都支持HS/FS/LS,硬件支持 OTG 信号、会话请求协议和主机协商协议,支持 8 个双向端点。
③、支持低功耗模式,本地或远端可以唤醒。
④、每个控制器都有一个 DMA。
每个 USB 控制器都有两个模式:正常模式(normal mode)和低功耗模式(low power mode)。每个 USB OTG 控制器都可以运行在高速模式(HS 480Mbps)、全速模式(LS 12Mbps)和低速模式
(1.5Mbps)。正常模式下每个 OTG 控制器都可以工作在主机(HOST)或从机(DEVICE)模式下,每个 USB 控制器都有其对应的接口。低功耗模式顾名思义就是为了节省功耗, USB2.0 协议中要
求,设备在上行端口检测到空闲状态以后就可以进入挂起状态。在从机(DEVICE)模式下,端口停止活动 3ms 以后 OTG 控制器内核进入挂起状态。在主机(HOST)模式下, OTG 控制器内核不
会自动进入挂起状态,但是可以通过软件设置。不管是本地还是远端的 USB 主从机都可以通过产生唤醒序列来重新开始 USB 通信。
两个 USB 控制器都兼容 EHCI,这里我们简单提一下 OHCI、 UHCI、 EHCI 和 xHCI,这三个是用来描述 USB 控制器规格的,区别如下:

OHCI: 全称为 Open Host Controller Interface,这是一种 USB 控制器标准,厂商在设计 USB控制器的时候需要遵循此标准,用于 USB1.1 标准。 OHCI 不仅仅用于 USB,也支持一些其他的
接口,比如苹果的 Firewire 等, OHCI 由于硬件比较难,所以软件要求就降低了,软件相对来说比较简单。 OHCI 主要用于非 X86 的 USB,比如扩展卡、嵌入式 USB 控制器。

UHCI: 全称是 Universal Host Controller Interface, UHCI 是 Inter 主导的一个用于 USB1.0/1.1的标准,与 OHCI 不兼容。与 OHCI 相比 UHCI 硬件要求低,但是软件要求相应就高了,因此
硬件成本上就比较低。

EHCI: 全称是 Enhanced Host Controller Interface,是 Inter 主导的一个用于 USB2.0 的 USB控制器标准。 I.MX6ULL 的两个 USB 控制器都是 2.0 的,因此兼容 EHCI 标准。 EHCI 仅提供
USB2.0 的高速功能,至于全速和低速功能就由 OHCI 或 UHCI 来提供。

xHCI: 全称是 eXtensible Host Controller Interface,是目前最流行的 USB3.0 控制器标准,在速度、能效和虚拟化等方面比前三个都有较大的提高。 xHCI 支持所有速度种类的 USB 设备,
xHCI 出现的目的就是为了替换前面三个。

USB 协议简析

USB 描述符

USB 描述符就是用来描述 USB 信息的,描述符就是一串按照一定规则构建的字符串, USB 设备使用描述符来向主机报告自己的相关属性信息,常用的描述符如下表所示:

描述符类型
Device Descriptor设备描述符1
Configuration Descriptor配置描述符2
String Descriptor字符串描述符3
Interface Descriptor接口字符串4
Endpoint Descriptor端点描述符5
设备描述符

设备描述符用于描述 USB 设备的一般信息, USB 设备只有一个设备描述符。设备描述符里面记录了设备的 USB 版本号、设备类型、 VID(厂商 ID)、 PID(产品 ID)、设备序列号等。设备描述符结构如表所示:

偏移大小(B)值类型描述
0bLength1数字此设备描述符长度, 18 个字节
1bDescriptorType1常量描述符类型,为 0X01
2bcdUSB2BCD 码USB 版本号
4bDeviceClass1设备类
5bDeviceSubClass1子类设备子类
6bDevicePortocol1协议设备协议
7bMaxPacketSize01数字端点 0 的最大包长度
8idVendor2ID厂商 ID
10idProduct2ID产品 ID
12bcdDevice2BCD 码设备版本号
14iManufacturer1索引厂商信息字符串描述符索引值
15iProduct1索引产品信息字符串描述符索引值
16iSerialNumber1索引产品序列号字符串描述符索引值
17bNumConfigurations1索引可能的配置描述符数目
配置描述符

设备描述符的 bNumConfigurations 域定义了一个 USB 设备的配置描述符数量,一个 USB设备至少有一个配置描述符。配置描述符描述了设备可提供的接口(Interface)数量、配置编号、
供电信息等,配置描述符结构如表所示:

偏移大小(B)值类型描述
0bLength1数字此配置描述符长度, 9 个字节
1bDescriptorType1常量配置描述符类型,为 0X02
2wTotalLength2数字整个配置信息总长度(包括配置、接
口、端点、设备类和厂家定义的描述
符)
4bNumInterfaces1数字此配置所支持的接口数
5bConfigurationValue1数字该配置的值,一个设备支持多种配
置,通过配置值来区分不同的配置。
6bConfiguration1数字描述此配置的字符串描述索引
7bmAttributes1数字该设备的属性:
D7:保留
D6:自给电源
D5:远程唤醒
D4:0:保留
8bMaxPower1数字此配置下所需的总线电流(单位 2mA)
字符串描述符

字符串描述符是可选的,字符串描述符用于描述一些方便人们阅读的信息,比如制造商、设备名称啥的。如果一个设备没有字符串描述符,那么其他描述符中和字符串有关的索引值都
必须为 0,字符串描述符结构如表所示:

偏移大小(B)值类型描述
0bLength1N+2此字符串描述符长度
1bDescriptorType1常量字符串描述符类型,为 0X03
2wLANGID[0]2数字语言标识码 0
2数字
NwLANGID[x]2数字语言标识码 x

wLANGID[0]~wLANGID[x] 指 明 了 设 备 支 持 的 语 言 , 具 体 含 义 要 查 阅 文 档《 USB_LANGIDs.pdf》.
主机会再次根据自己所需的语言向设备请求字符串描述符,这次会主机会指明要得到的字符串索引值和语言。设备返回 Unicode 编码的字符串描述符,结构如表所示:

偏移大小(B)值类型描述
0bLength1N+2此字符串描述符长度
1bDescriptorType1常量字符串描述符类型,为 0X03
2bStringN数字Unicode 编码的字符串
接口描述符

配置描述符中指定了该配置下的接口数量,配置可以提供一个或多个接口,接口描述符用于描述接口属性。接口描述符中一般记录接口编号、接口对应的端点数量、接口所述的类等,接口描述符结构如表所示:

偏移大小(B)值类型描述
0bLength1数字此接口描述符长度, 9 个字节
1bDescriptorType1常量描述符类型,为 0X04
2bInterfaceNumber1数字当前接口编号,从 0 开始
3bAlternateSetting1数字当前接口备用编号
4bNumEndpoints1数字当前接口的端点数量
5bInterfaceClass1当前接口所属的类
6bInterfaceSubClass1子类当前接口所属的子类
7bInterfaceProtocol1协议当前接口所使用的协议
8iInterface1索引当前接口字符串的索引值
端口描述符

接口描述符定义了其端点数量,端点是设备与主机之间进行数据传输的逻辑接口,除了端点 0 是双向端口,其他的端口都是单向的。端点描述符描述了树传输类型、方向、数据包大小、
端点号等信息,端点描述符结构如表所示:

偏移大小(B)值类型描述
0bLength1数字此端点描述符长度, 7 个字节
1bDescriptorType1常量描述符类型,为 0X05
2bEndpointAddress1数字端点地址和方向:
bit3:0:端点号
bit6:4:保留,为零。
bit7:方向, 0 输出端点(主机到设
备), 1 输入端点(设备到主机)
3bmAttributes1数字端点属性, bit1:0 表示传输类型:
00:控制传输
01:同步传输
10:批量传输
11:中断传输
其他位保留
4wMaxPacketSize2数字端点能发送或接收的最大数据包长度
6bInterval1子类端点数据传输中周期时间间隙值,此
域对于批量传输和控制传输无效,同
步传输的话此域必须为 1ms,中断传
输此域可以设置 1ms~255ms。
USB 数据包类型

USB 是串行通信,需要一位一位的去传输数据, USB 传输的时候先将原始数据进行打包,所以 USB 中传输的基本单元就是数据包。根据用途的不同, USB 协议定义了 4 种不同的包结
构:令牌(Token)包、数据(Data)包、握手(Handshake)包和特殊(Special)包。这四种包通过包标识符 PID 来区分, PID 共有 8 位, USB 协议使用低 4 位 PID3~PID0,另外的高四位 PID7~PID4 是PID3~PID0 的取反,传输顺序是 PID0、 PID1、 PID2、 PID3…PID7。令牌包的 PID1~0 为 01,数据包的 PID1~0 为 11,握手包的 PID1~0 为 10,特殊包的 PID1~0 为 00。每种类型的包又有多种具体的包,如表所示:

一个完整的包分为多个域,所有的数据包都是以同步域(SYNC)开始,后面紧跟着包标识符(PID),最终都以包结束(EOP)信号结束。不同的数据包中间位域不同,一般有包目标地址(ADDR)、
包目标端点(ENDP)、数据、帧索引、 CRC 等,这个要具体数据包具体分析。接下来简单看一下这些数据包的结构。

令牌包

令牌包结构如图所示:

上图是一个 SETUP 令牌包结构,首先是 SYNC 同步域,包同步域为 00000001,也就是连续 7 个 0,后面跟一个 1,如果是高速设备的话就是 31 个 0 后面跟一个 1。紧跟着是 PID,这里是 SETUP 包,为 0XB4,大家可能会好奇为什么不是 0X2D(00101101), 0XB4 的原因如下:
①、 SETUP 包的 PID3~PID0 为 1101,因此对应的 PID7~PID4 就是 0010。
②、 PID 传输顺序为 PID0、 PID1、 PID2…PID7,因此按照传输顺序排列的话此处的 PID 就是 10110100=0XB4,并不是 0X2D。
PID 后面跟着地址域(ADDR)和端点域(ENDP),为目标设备的地址和端点号。 CRC5 域是 5位 CRC 值,是 ADDR 和 ENDP 这两个域的校验值。最后就是包结束域(EOP),标记本数据包结束。其他令牌包的结构和 SETUP 基本类似,只是 SOF 令包中间没有 ADDR 和 ENDP 这两个域,而是只有一个 11 位的帧号域。

数据包

数据包结构如图所示:

数据包比较简单,同样的,数据包从 SYNC 同步域开始,然后紧跟着是 PID,这里就是DATA0, PID 值为 0XC3。接下来就是具体的数据,数据完了以后就是 16 位的 CRC 校验值,最后是 EOP。

握手包

握手包结构如图所示:

上图是 ACK 握手包,很简单,首先是 SYNC 同步域,然后就是 ACK 包的 PID,为0X4B,最后就是 EOP。其他的 NAK、 STALL、 NYET 和 ERR 握手包结构都是一样的,只是其中的 PID 不同而已。

USB 传输类型

在端点描述符中 bmAttributes 指定了端点的传输类型,一共有 4 种,本节我们来看一下这四种传输类型的区别。

控制传输

控制传输一般用于特定的请求,比如枚举过程就是全部由控制传输来完成的,比如获取描述符、设置地址、设置配置等。控制传输分为三个阶段:建立阶段(SETUP)、数据阶段(DATA)和状态阶段(STATUS),其中数据阶段是可选的。建立阶段使用 SETUP 令牌包, SETUP 使用DATA0 包。数据阶段是 0 个、 1 个或多个输入(IN)/输出(OUT)事务,数据阶段的所有输入事务必须是同一个方向的,比如都为 IN 或都为 OUT。数据阶段的第一个数据包必须是 DATA1,每次正确传输以后就在 DATA0 和 DATA1 之间进行切换。数据阶段完成以后就是状态阶段,状态阶段的传输方向要和数据阶段相反,比如数据阶段为 IN 的话状态阶段就要为 OUT,状态阶段使用 DATA1 包。比如一个读控制传输格式如图所示:

同步传输

同步传输用于周期性、低时延、数据量大的场合,比如音视频传输,这些场合对于时延要求很高,但是不要求数据 100%正确,允许有少量的错误。因此,同步传输没有握手阶段,即使数据传输出错了也不会重传。

批量传输

提起“批量”,我们第一反应就是“多”、“大”等,因此,批量传输就是用于大批量传输大块数据的,这些数据对实时性没有要求,比如 MSD 类设备(存储设备), U 盘之类的。批量传输分为批量读(输入)和批量写(输出),如果是批量读的话第一阶段的 IN 令牌包,如果是批量写那么第一阶段就是 OUT 令牌包。
我们就以批量写为例简单介绍一下批量传输过程:
①、主机发出 OUT 令牌包,令牌包里面包含了设备地址、端点等信息。
②、如果 OUT 令牌包正确的话,也就是设备地址和端点号匹配,主机就会向设备发送一个数据(DATA)包,发送完成以后主机进入接收模式,等待设备返回握手包,一切都正确的话设备就会向主机返回一个 ACK 握手信号。
批量读的过程刚好相反:
①、主机发出 IN 令牌包,令牌包里面包含了设备地址、端点等信息。发送完成以后主机就进入到数据接收状态,等待设备返回数据。
②、如果 IN 令牌包正确的话,设备就会将一个 DATA 包放到总线上发送给主机。主机收到这个 DATA 包以后就会向设备发送一个 ACK 握手信号。

中断传输

这里的中断传输并不是我们传统意义上的硬件中断,而是一种保持一定频率的传输,中断传输适用于传输数据量小、具有周期性并且要求响应速度快的数据,比如键盘、鼠标等。中断的端点会在端点描述符中报告自己的查询时间间隔,对于时间要求严格的设备可以采用中断传输。
 

USB 枚举

当 USB 设备与 USB 主机连接以后主机就会对 USB 设备进行枚举,通过枚举来获取设备的描述符信息,主机得到这些信息以后就知道该加载什么样的驱动、如何进行通信等。 USB 枚举过程如下:
①、第一回合,当 USB 主机检测到 USB 设备插入以后,主机会发出总线复位信号来复位设备。USB 设备复位完成以后地址为 0,主机向地址 0 的端点 0 发送数据,请求设备的描述符。设备得到请求以后就会按照主机的要求将设备描述符发送给主机,主机得到设备发送过来的设备描述符以后,如果确认无误就会向设备返回一个确认数据包(ACK)。
②、第二回合,主机再次复位设备,进入地址设置阶段。主机向地址 0 的端点 0 发送设置地址请求数据包,新的设备地址就包含在这个数据包中,因此没有数据过程。设备进入状态过程,等待主机请求状态返回,收到以后设备就会向主机发送一个 0 字节状态数据包,表明设备已经设置好地址了,主机收到这个 0 字节状态数据包以后会返回一个确认包(ACK)。设备收到主机发送的 ACK 包以后就会使用这个新的设备地址,至此设备就得到了一个唯一的地址。
③、第三回合,主机向新的设备地址端点 0 发送请求设备描述符数据包,这一次主机要获取整个设备描述符,一共是 18 个字节。
④、和第③步类似,接下来依次获取配置描述符、配置集合、字符串描述符等等。
 

Linux 内核自带 HOST 实验

USB 鼠标键盘测试

首先做一下 USB HOST 试验,也就是 I.MX6U-ALPHA 开发板做 USB 主机,然后外接 USB设备,比如 USB 鼠标键盘、 USB 转 TTL 串口线、 U 盘等设备。 Linux 内核已经集成了大量的USB 设备驱动,尤其是我们常见的 USB 鼠标键盘、 U 盘等,本节我们就来学习一下如何使能Linux 内核常见的 USB 设备驱动。

USB 鼠标键盘属于 HID 设备,内核已经集成了相应的驱动, NXP 官方提供的 linux 内核默认已经使能了 USB 鼠标键盘驱动,但是我们还要学习一下如何手动使能这些驱动。输入“make
menuconfig”打开 linux 内核配置界面,首先打开 HID 驱动,按照如下路径到相应的配置项目:

-> Device Drivers
        -> HID support
                -> HID bus support (HID [=y])
                        -> <*> Generic HID driver //使能通用 HID 驱动

接下来需要使能 USB 键盘和鼠标驱动,配置路径如下:

-> Device Drivers
        -> HID support
                -> USB HID support
                        -> <*> USB HID transport layer //USB 键盘鼠标等 HID 设备驱动

大家可以将光标放到图中“USB HID Transport layer”这一行,然后按下“?”键打开对应的帮助信息就可以看到对于这个配置项的描述,简单总结一下:
此选项对应配置项就是 CONFIG_USB_HID,也就是 USB 接口的 HID 设备。如果要使用USB 接口的 keyboards(键盘)、 mice(鼠标)、 joysticks(摇杆)、 graphic tablets(绘图板)等其他的 HID设备,那么就需要选中“USB HID Transport layer”。但是要注意一点,此驱动和 HIDBP(Boot Protocol)键盘、鼠标的驱动不能一起使用!所以大家要是在网上查阅 linux 内核 USB 键盘鼠标
驱动的时候,发现推荐使用“USB HIDBP Keyboard (simple Boot) support”和“USB HIDBP Mouse(simple Boot) support”这两个配置项也是可以的。

完成以后重新编译 linux 内核并且使用得到的 zImage 启动开发板。启动以后插入 USB 鼠标,会有如图所示的提示信息:

从图可以看出,系统检测到了 Logitech(罗技)的鼠标,如果成功驱动的话就会在/dev/input 目录下生成一个名为 eventX(X=0,1,2,3…)的文件,这个就是我们前面讲的输入子系统,鼠标和键盘都是作为输入子系统设备的。笔者这里对应的就是/dev/input/event3 这个设备,使用如下命令查看鼠标的原始输入值,结果如图所示:

上图就是鼠标作为输入子系统设备的原始输入值,这里就不去分析了,我们在移植GUI 图形库以后就可以直接使用鼠标,比如 QT 等。
注意,有些鼠标可能会出现隔一段时间自动断开重连的现象,比如我测试的电脑城送的几块钱的罗技鼠标就会这样,我用 NXP 官方的 EVK 开发板测试也有这个问题!我自己用的雷蛇鼠标就不会有这种现象。但是,如果你一直使用这个鼠标,比如用 hexdump 命令一直查看鼠标上报值,或者在 QT 里面一直使用鼠标,那么这些鼠标就不会自动断开并重连。最后再来测试一下 USB 键盘,屏幕已经驱动起来了,所以我们可以直接将屏幕作为终端,然后接上键盘直接输入命令来进行各种操作。首先将屏幕设置为控制台,打开开发板根文件系统中的/etc/inittab 文件,然后在里面加入下面这一行:

tty1::askfirst:-/bin/sh

完成以后重启开发板,此时屏幕就会作为终端控制台,会有“Please press Enter to activatethis console.”这样提示,如图所示:

接上键盘,然后根据图中的提示,按下键盘上的 Enter(回车)键即可使能 LCD 屏幕控制台,然后我们就可以输入各种命令来执行相应的操作,如图所示:

U 盘实验

NXP 提供的 Linux 内核默认也已经使能了 U 盘驱动,因此我们可以直接插上去使用。但是我们还是需要学习一下如何手动配置 Linux 内核,使能 U 盘驱动。

U 盘使用 SCSI 协议,因此要先使能 Linux 内核中的 SCSI 协议,配置路径如下:

-> Device Drivers
        -> SCSI device support
                -> <*> SCSI disk support //选中此选项

我们还需要使能 USB Mass Storage,也就是 USB 接口的大容量存储设备,配置路径如下:

-> Device Drivers
        -> USB support (USB_SUPPORT [=y])
                -> Support for Host-side USB (USB [=y])
                        -> <*> USB Mass Storage support //USB 大容量存储设备

准备好一个 U 盘,注意 U 盘要为 FAT32 格式的!NTFS 和 exFAT 由于版权问题所以在 Linux下支持的不完善,操作的话可能会有问题,比如只能读,不能写或者无法识别等。准备好以后将 U 盘插入到开发板 USB HUB 扩展出来的 HOST 接口上,此时会输出如图所示信息:

从图可以看出,系统检测到 U 盘插入,大小为 32GB,对应的设备文件为/dev/sda和/dev/sda1,大家可以查看一下/dev 目录下有没有 sda 和 sda1 这两个文件。 /dev/sda 是整个 U盘, /dev/sda1 是 U 盘的第一个分区,我们一般使用 U 盘的时候都是只有一个分区。要想访问 U盘我们需要先对 U 盘进行挂载,理论上挂载到任意一个目录下都可以,这里我创建一个
/mnt/usb_disk 目录,然后将 U 盘挂载到/mnt/usb_disk 目录下,命令如下:

mkdir /mnt/usb_disk -p //创建目录
mount /dev/sda1 /mnt/usb_disk/ -t vfat -o iocharset=utf8 //挂载

-t 指定挂载所使用的文件系统类型,这里设置为 vfat,也就是 FAT 文件系统,“-o iocharset”设置硬盘编码格式为 utf8,否则的话 U 盘里面的中文会显示乱码!
挂载成功以后进入到/mnt/usb_disk 目录下,输入 ls 命令查看 U 盘文件。

至此 U 盘就能正常读写操作了,直接对/mnt/usb_disk 目录进行操作就行了。如果要拔出 U盘要执行一个 sync 命令进行同步,然后在使用 unmount 进行 U 盘卸载,命令如下所示:

sync //同步
cd / //如果处于/mnt/usb_disk 目录的话先退出来,否则卸载的时候提示设备忙,导致卸载失败,切记!
umount /mnt/usb_disk //卸载

Linux 内核自带 OTG 实验

OTG 主机实验

系统重启成功以后就可以正常使用 USB OTG1 接口, OTG 既可以做主机,也可以做从机,做主机的话测试方法和上一小节一模一样,直接在 ALPHA 的 OTG HOST 接口上插入 USB 鼠标键盘、 U 盘等设备。

OTG 从机实验

OTG 从机就是将开发板作为一个 USB 设备连接到其他的主机上,这里我们来做两个 USB从机实验:模拟 U 盘以及 USB 声卡。

模拟 U 盘实验

模拟 U 盘实验就是将开发板当做一个 U 盘,可以将开发板上的 U 盘或者 TF 卡挂载到 PC上去,首先需要配置 Linux,配置路径如下:

-> Device Drivers
        -> USB support (USB_SUPPORT [=y])
                -> USB Gadget Support (USB_GADGET [=y]
                        -> [M]USB Gadget Drivers (<choice> [=m]) //选中 USB Gadget 驱动
                                ->[M]Mass Storage Gadget //大容量存储

这里我们需要将驱动编译为模块!使用的时候直接输入命令加载驱动模块即可。配置好以后重新编译 Linux 内核,会得到三个.ko 驱动模块(带路径):

drivers/usb/gadget/libcomposite.ko
drivers/usb/gadget/function/usb_f_mass_storage.ko
drivers/usb/gadget/legacy/g_mass_storage.ko

将上述三个.ko 模块拷贝到开发板根文件系统中,命令如下:

cd drivers/usb/gadget/ //进入 gadget 目录下
sudo cp libcomposite.ko /home/xxx/linux/nfs/rootfs/lib/modules/4.1.15/
sudo cp function/usb_f_mass_storage.ko /home/xxx/linux/nfs/rootfs/lib/modules/4.1.15/
sudo cp legacy/g_mass_storage.ko /home/xxx/linux/nfs/rootfs/lib/modules/4.1.15/

拷贝完成以后使用新编译出来的 zImage 启动开发板,在开发板上插入一个 U 盘,记住这个 U 盘对应的设备文件,比如我们这里是/dev/sda 和/dev/sda1,以后要将/dev/sda1 挂载到 PC 上,
也就是把/dev/sda1 作为模拟 U 盘的存储区域。使用 Mini USB 线将开发板的 USB OTG Mini 接口与电脑连接起来。连接好以后依次加载 libcomposite.ko、 usb_f_mass_storage.ko 和 g_mass_storage.ko 这三个驱动文件,顺序不能错了!命令如下:

depmod
modprobe libcomposite.ko
modprobe usb_f_mass_storage.ko
modprobe g_mass_storage.ko file=/dev/sda1 removable=1

加载 g_mass_storage.ko 的时候使用 file 参数指定使用的大容量存储设备,我这里使用 U 盘对应的/dev/sda1。如果加载成功的话电脑就会出现一个 U 盘,这个 U 盘就是我们开发板模拟的,如图所示:

我们可以直接在电脑上对这个 U 盘进行读写操作,实际上操作的就是插在开发板上的 U盘。操作完成以后要退出的话执行如下命令:

rmmod g_mass_storage.ko
USB 声卡实验

USB 声卡就是 USB 接口的外置声卡,一般电脑内部都自带了声卡,但是内部自带的声卡效果相对来说比较差,不能满足很多 HIFI 玩家的需求。 USB 声卡通过 USB 接口来传递音频数据,具体的 ADC 和 DAC 过程由声卡完成,摆脱了电脑主板体积的限制,外置 USB 声卡就可以做的很好。 ALPHA 开发板板载了音频解码芯片,因此可以将 ALPHA 开发板作为一个外置USB 声卡,配置 Linux 内核,配置路径如下:

-> Device Drivers
        -> USB support (USB_SUPPORT [=y])
                -> USB Gadget Support (USB_GADGET [=y]
                        -> [M]USB Gadget Drivers //选中 USB Gadget 驱动
                                ->[M] Audio Gadget //选中音频
                                        ->UAC 1.0 (Legacy) //选中 UAC

注意,这里也是编译为驱动模块,配置完成以后重新编译内核,得到新的 zImage 和三个.ko驱动模块文件:

drivers/usb/gadget/libcomposite.ko
drivers/usb/gadget/function/usb_f_uac1.ko
drivers/usb/gadget/legacy/g_audio.ko

将上述三个.ko 模块拷贝到开发板根文件系统中。拷贝完成以后使用新编译出来的 zImage 启动开发板,首先按照音频驱动章节讲解的方法配置 ALPHA 的声卡,保证声卡播放正常!使用 Mini USB 线将开发板与电脑连接起来,最后依次加载 libcomposite.ko、 usb_f_uac1.ko 和 g_audio.ko 这三个驱动模块,命令如下:

depmod
modprobe libcomposite.ko
modprobe usb_f_uac1.ko
modprobe g_audio.ko

加载完成以后稍等一会虚拟出一个 USB 声卡,打开电脑的设备管理器,选择“声音、视频和游戏控制器”,会发现有一个名为“AC Interface”设备,如图所示:

图中的“AC Interface”就是开发板模拟出来的 USB 声卡,设置 windows,选择音频输出使用“AC Interface”, Windows10 设置如图所示:

一切设置好以后就可以从开发板上听到电脑输出的声音,此时开发板就完全是一个 USB 声卡设备了。
关于 USB 驱动就讲解到这里,本章并没有深入到 USB 驱动具体编写方式,只是对 USB 的协议做了简单的介绍,后面讲解了一下 Linux 内核自带的 USB HOST 和 DEVICE 驱动的使用,Linux 内核已经集成了大量的 USB 设备驱动。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1420957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于STM32的CAN通信协议选择与实现

基于STM32的控制器区域网络&#xff08;CAN&#xff09;通信协议是一种常见的实时数据通信方案&#xff0c;适用于需要高速、可靠通信的应用场景&#xff0c;比如汽车网络、工业控制系统等。在这里&#xff0c;我们将详细介绍基于STM32的CAN通信协议的选择与实现。 ✅作者简介&…

使用Win32API实现贪吃蛇小游戏

目录 C语言贪吃蛇项目 基本功能 需要的基础内容 Win32API 介绍 控制台程序部分指令 设置控制台窗口的长宽 设置控制台的名字 控制台在屏幕上的坐标位置结构体COORD 检索指定标准设备的句柄&#xff08;标准输入、标准输出或标准错误&#xff09; 光标信息结构体类型CONSOLE_CUR…

excel给数据库初始化/旧数据处理(自动sql拼装)

思路&#xff1a; 首先导出数据到excel编写单条数据操作的sql利用excel CONCATENATE 函数自动生成&#xff0c;每一行数据的操作sql 小技巧:对于需要套娃的字段值&#xff0c;可以加一个临时列同样使用CONCATENATE函数进行sql拼装 案例&#xff1a; 1.临时列:CONCATENATE(C2, …

HBase(docker版)简单部署和HBase shell操作实践

文章目录 说明HBase部署访问HBase Shell常见命令数据定义语言(DDL) 数据操作语言(DML)通用操作访问HBase WebUI 说明 本文适合HBase初学者快速搭建HBase环境&#xff0c;练习常见shell使用本文参考资料 《大数据技术原理和应用》&#xff08;林子雨 编著 第三版&#xff09;zh…

一文彻底搞懂redis数据结构及应用

文章目录 1. Redis介绍2.五种基本类型2.1 String字符串2.2 List列表2.3 Set集合2.4 Zset有序集合2.5 Hash散列 3. 三种基本类型3.1 Bitmap &#xff08;位存储&#xff09;3.2 HyperLogLogs&#xff08;基数统计&#xff09;3.3 geospatial (地理位置) 4. Stream详解4.1 Stream…

NTRU-Based GSW-Like FHE:Faster Blind Rotation

参考文献&#xff1a; [XZD23] Xiang, B., Zhang, J., Deng, Y., Dai, Y., Feng, D. (2023). Fast Blind Rotation for Bootstrapping FHEs. In: Handschuh, H., Lysyanskaya, A. (eds) Advances in Cryptology – CRYPTO 2023. CRYPTO 2023. Lecture Notes in Computer Scien…

C++_list

目录 一、模拟实现list 1、list的基本结构 2、迭代器封装 2.1 正向迭代器 2.2 反向迭代器 3、指定位置插入 4、指定位置删除 5、结语 前言&#xff1a; list是STL(标准模板库)中的八大容器之一&#xff0c;而STL属于C标准库的一部分&#xff0c;因此在C中可以直接使用…

实现扫码登录

扫码登录是如何实现的&#xff1f; 二维码信息里主要包括唯一的二维码ID,过期的时间&#xff0c;还有扫描状态&#xff1a;未扫描、已扫描、已失效。 扫码登录流程 用户打开网站登录页面的时候&#xff0c;浏览器会向二维码服务器发送一个获取登录二维码的请求。二维码服务器收…

雨云VPS搭建幻兽帕鲁服务器,PalWorld开服联机教程(Windows),0基础保姆级教程

雨云VPS用Windows系统搭建幻兽帕鲁私服&#xff0c;PalWorld开服联机教程&#xff0c;零基础保姆级教程&#xff0c;本教程使用一键脚本来搭建幻兽帕鲁服务端&#xff0c;并讲了如何配置游戏参数&#xff0c;如何更新服务端等。 最近这游戏挺火&#xff0c;很多人想跟朋友联机…

顶象点选验证码

要放假了好颓废。。。。 没啥事儿干&#xff0c;就把之前剩余的顶象点选系列的验证码类型看了下。 之前分享了一篇关于这个顶象的滑块的 DX算法还原_dx算法还原_逆向学习之旅-CSDN博客&#xff0c;感兴趣可以去看看。 咱们以文字点选为例&#xff1a; def get_image_arry(s…

Spring Boot如何统计一个Bean中方法的调用次数

目录 实现思路 前置条件 实现步骤 首先我们先自定义一个注解 接下来定义一个切面 需要统计方法上使用该注解 测试 实现思路 通过AOP即可实现&#xff0c;通过AOP对Bean进行代理&#xff0c;在每次执行方法前或者后进行几次计数统计。这个主要就是考虑好如何避免并发情况…

AI绘画:PhotoMaker Win11本地安装记录!

昨天介绍一个叫PhotoMaker的AI绘画开源项目。挺不错的&#xff01; 通过这个项目可以快速制作特定人脸的AI绘画作品&#xff0c;相比传统的技术效果会好很多&#xff0c;效率也高很多。 今天趁热打铁&#xff0c;本地电脑装装看&#xff0c;并且记录&#xff0c;分享一下&#…

城建档案数字化管理系统

城市建设档案数字化管理系统是指将城市建设相关档案纸质化资料转换为数字化形式&#xff0c;并通过信息技术手段进行存储、检索、管理和利用的系统。该系统旨在解决传统纸质档案管理存在的问题&#xff0c;提高档案管理的效率和准确性。 专久智能城市建设档案数字化管理系统主要…

自学C语言-7

第7章 循环控制 生活中总会有许多简单而重复的工作&#xff0c;为完成这些重复性工作&#xff0c;需要花费很多时间。使用循环语句来处理程序开发中简单、重复性的工作是最好不过的了。 本章致力于使读者了解while、do…while和for3种循环结构的特点&#xff0c;以及转移语句的…

Python第三方扩展库Matplotlib

Python第三方扩展库Matplotlib Matplotlib 是第三方库&#xff0c;不是Python安装程序自带的库&#xff0c;需要额外安装&#xff0c;它是Python的一个综合性的绘图库&#xff0c;提供了大量的绘图函数用于创建静态、动态、交互式的图形和数据可视化&#xff0c;可以帮助用户创…

Python实现时间序列分析AR定阶自回归模型(ar_select_order算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 时间序列分析中&#xff0c;AR定阶自回归模型&#xff08;AR order selection&#xff09;是指确定自回…

Springboot使用数据库连接池druid

springboot框架中可以使用druid进行数据库连接池&#xff0c;下面介绍druid在springboot中使用和参数配置介绍。 数据库连接池&#xff08;Druid&#xff09;是一种用于管理数据库连接的机制&#xff0c;其工作原理和常见使用方法如下&#xff1a; 原理&#xff1a;数据库连接…

Android 12 系统开机动画

一、查找Android系统提供的开机动画 在Android系统源码目录下输入 find ./ -name "bootanimation.zip" 如图所示 所输出的路劲即为bootanimation.zip所在路径&#xff0c;每个系统都不一样&#xff0c;建议用命令查找 二、复制到对应目录下 android12\out\target\…

vue使用mpegts.js教程

vue使用mpegts.js教程 最简单好用的H265网页播放器-mpegts.js简介特征受限性 使用步骤安装引入HTML 中添加视频标签video知识扩展 在容器里创建播放器 最简单好用的H265网页播放器-mpegts.js H265是新一代视频编码规范&#xff0c;与H264相比压缩比更高&#xff0c;同样的码率下…

Web实战丨基于Django的简单网页计数器

文章目录 写在前面Django简介主要程序运行结果系列文章写在后面 写在前面 本期内容 基于django的简单网页计数器 所需环境 pythonpycharm或vscodedjango 下载地址 https://download.csdn.net/download/m0_68111267/88795604 Django简介 Django 是一个用 Python 编写的高…