Linux驱动开发|USB驱动

article/2025/10/13 0:52:33

USB驱动

USB接口很复杂,不同的设备器协议也不同,因此本文仅介绍如何使能Linux内核自带的USB驱动,不涉及USB驱动开发

一、USB接口简介

1.1 USB介绍

USB(Universal Serial Bus),即通用串行总线。由英特尔与众多电脑公司提出来的,用于规范电脑与外部设备的连接与通讯。目前 USB 接口已经得到了大范围的应用,已经是电脑、手机等终端设备的必配接口。

按照大版本划分, USB 目前可以划分为 USB1.0、 USB2.0、 USB3.0 以及正在即将到来的USB4.0

按照接口类型划分,USB 也分为很多种,常见的如下图示
在这里插入图片描述
以 Mini USB 为例介绍 USB 的基本电气属性。 Mini USB 线一般都是一头为 USB A 插头,一头为 Mini USB插头。

在这里插入图片描述
USB A 插头共有四个触点,即 4 根线,这四根线的顺序如上图示。其中 VBUS/GND 触点比 D+/D- 触点要长,当插入 USB 时会先供电,然后再接通数据线;拔出时先断开数据线,然后再断开电源线

– 第 1 根线为 VBUS,电压为5V
– 第 2 根线为 D- ,差分信号线
– 第 3 根线为 D+ ,差分信号线
– 第 4 根线为 GND,接地线

Mini USB插头共有五个触点,即 5 根线,这五根线的顺序如上图示

– 第 1 根线为 VCC,电压为5V
– 第 2 根线为 D- ,差分信号线
– 第 3 根线为 D+ ,差分信号线
– 第 4 根线为 ID ,用于实现OTG功能,判断当前连接是主设备还是从设备
– 第 5 根线为 GND,接地线

1.2 USB拓扑结构

USB 是主从结构的,也就是分为主机(Host)和从机(Device)两部分。主机就是提供 USB A 插座来连接外部的设备,比如电脑作为主机,对外提供 USB A 插座。USB 只能主机与设备之间进行数据通信,主机与主机、设备与设备之间是不能通信的,因此两个正常通信的 USB 接口之间必定有一个主机,一个设备。为此使用了不同的插头和插座来区分主机与设备,比如主机提供 USB A 插座,从机提供 Mini USB、Micro USB 等插座。

主机和从机之间的通信通过管道 (Pipe) 完成,管道是一个逻辑概念,任何一个 USB 设备一旦上电就会存在一个管道,主机通过管道来获取从机的描述符、配置等信息。在主机端管道其实就是一组缓冲区,用来存放主机数据,在设备端管道对应一个特定的端点。

在一个 USB 系统中,仅有一个 USB 主机,但是可以有多个 USB 设备,包括 USB 功能设备和 USB HUB(USB集线器,用于扩展 USB 插口),最多支持 127 个设备。一个 USB 主控制器支持 128 个地址,地址 0 是默认地址,只有在设备枚举的时候才会使用,地址 0 不会分配给任何一个设备。所以一个 USB 主控制器最多可以分配 127 个地址。整个 USB 的拓扑结构就是一个分层的金字塔形,如下图示
在这里插入图片描述

上图中,共有7层,顶部是 Root Hub,这个是USB 控制器内部的,图中的 Hub 是连接的 USB 集线器,Func 是具体的 USB 设备

1.3 USB OTG

OTG 是 On-The-Go 的缩写,支持 USB OTG 功能的 USB 接口既可以做 HOST,也可以做 DEVICE。支持 OTG 模式的 USB 接口一般都是 Mini USB 或 Micro USB 等这些带有 ID 线的接口,ID 线的高低电平表示 USB 口工作在 HOST 还是 DEVICE 模式:

  • ID=1:OTG 设备工作在从机模式
  • ID=0:OTG 设备工作在主机模式
1.4 IMX6ULL 开发板USB接口简介

I.MX6ULL内部集成了两个独立的 USB控制器,这两个 USB 控制器都支持 OTG 功能。控制器内核分别为 Core0和 Core1,分别连接到 OTG1 和 OTG2 上。两个控制器都支持 HS (High Speed 480Mbps)、 FS (Full Speed 12Mbps)和 LS (Low Speed 1.5Mbps)模式,硬件支持 OTG信号、会话请求协议和主机协商协议,支持 8个双向端点;支持低功耗模式,本地或远端可以唤醒;每个控制器都有一个 DMA

I.MX6ULL-ALPHA开发板USB接口分为两部分: USB HUBUSB OTG

  • USB HUB:利用GL850G这个HUB芯片将 USB OTG2 扩展成4路 HOST接口(只能做 HOST),原理图如下示
    在这里插入图片描述

  • USB OTG:另外一路 USB OTG1 接口,既可作为主机 (HOST),也可作为从机 (DEVICE)
    在这里插入图片描述

当OTG作为从机时,USB线接入上图左侧的Mini USB插座;当OTG作为主机时,USB设备接入上图右侧的USB A插座

二、Linux内核自带HOST实验

2.1 USB鼠标键盘测试

I.MX6U-ALPHA 开发板做 USB 主机,然后外接 USB 设备,比如 USB 鼠标键盘、 USB 转 TTL 串口线、 U 盘等设备。内核已经集成了大量的 USB 设备驱动,尤其是常见的 USB 鼠标键盘、 U 盘等,写明介绍如何使能 Linux 内核常见的 USB 设备驱动

  • USB 鼠标键盘驱动使能:属于 HID 设备,内核已经集成相应驱动,使用make menuconfig命令图形化配置内核

能通用 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 鼠标和键盘:重新编译内核并且使用新的 zImage 启动开发板。

启动后插入 USB 鼠标,会有如下提示信息

在这里插入图片描述

成功驱动后,会在/dev/input 目录下生成一个名为 eventX 的文件,使用hexdump命令查看戍边的原始输入值

在这里插入图片描述

2.2 U盘实验

Linux 内核也集成了 U 盘驱动

  • 使能 U 盘驱动

U 盘使用 SCSI 协议,因此要先使能内核中的 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 格式) 插入到开发板的 HOST 接口上,驱动成功的话会输出下图所示信息

在这里插入图片描述

系统检测到 U 盘插入,对应的设备文件为 /dev/sda(整个U盘) 和 /dev/sda1(U第1个分区),使用如下命令挂载 U盘

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 目录下即可查看U盘文件。拔出U盘时,需执行一个sync命令,在进行U盘卸载

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

三、Linux内核自带OTG实验

USB OTG1 的 ID 引脚连接到了 GPIO1_IO00 引脚上,一般情况下 USB OTG 默认工作在主机(HOST)模式下,因此 ID 线应该是低电平。这里需要修改设备树中 GPIO1_IO00 引脚的电气属性,并将其设置为默认下拉。

打开设备树设备树文件,在 iomuxc 节点的 pinctrl_hog_1 子节点下添加 GPIO1_IO00 引脚信息,如下所示:

&iomuxc {pinctrl-names = "default";pinctrl-0 = <&pinctrl_hog_1>;imx6ul-evk {pinctrl_hog_1: hoggrp-1 {fsl,pins = <......MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x13058 /*OTG1 ID */>;};......
};

设备树修改好以后重新编译并用新的设备树启动系统

3.1 OTG主机实验

主机实验同第二章节相同

3.2 OTG从机实验

OTG 从机就是将开发板作为一个 USB 设备连接到其他的主机上

  • 模拟 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 //大容量存储

此时要将驱动编译为模块,使用时直接加载驱动模块即可。配置好以后重新编译内核,会得到以下三个.ko 驱动模块(带路径):

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

将这三个驱动模块拷贝至开发板根文件系统中,使用 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 盘,这个就是开发板模拟的,要退出的话执行命令rmmod g_mass_storage.ko即可

  • USB 声卡实验:USB 接口的外置声卡

开发板板载了音频解码芯片,因此可以将其作为外置USB 声卡,先要配置内核

-> 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

此时要将驱动编译为模块,使用时直接加载驱动模块即可。重新编译内核,会得到以下三个.ko 驱动模块(带路径):

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

将这三个驱动模块拷贝至开发板根文件系统中,使用 Mini USB 线将开发板的 USB OTG Mini 接口与电脑连接起来。之后依次加载 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”的设备,就是开发板模拟出来的 USB 声卡,选择音频输出使用该设备,之后就可以从开发板上听到电脑输出的声音


http://chatgpt.dhexx.cn/article/GyZ1ucX1.shtml

相关文章

window10+vs2022配置window驱动开发环境

测试模式 开发的驱动程序没有官方数字签名&#xff0c;只能在测试模式下加载。 命令行键入以下命令&#xff0c;重启电脑后桌面右下角出现测试模式字样&#xff0c;说明进入了测试模式 bcdedit /set testsigning on 命令行键入以下命令&#xff0c;重启电脑后桌面右下角没有了测…

win10驱动开发——驱动签名

win1803开始直接禁用驱动强制签名的方式不行了 1.设置环境 bcdedit -set NOINTEGRITYCHECKS ON bcdedit -set TESTSIGNING ON bcdedit -set loadoptions DDISABLE_INTEGRITY_CHECKS2.配置环境变量 找到makecert.exe文件位置如【C:\Program Files (x86)\Windows Kits\10\bin\1…

Windows 10 驱动开发 及 驱动签名

记录下在公司开发驱动的一些注意事项, 驱动当前仅针对win10x64. 常识: 最早的驱动开发sdk是 ntddk, 类似于用户层的win32 api, 后面为了增加对pnp(Plug-and-Play, 即插即用)的支持, 迭代为 wdm. 后面因为wdm开发过于繁琐, 微软发布了 WDF 框架, 类似于 用户层的 …

Linux——驱动开发

一、驱动开发概述 1.1 驱动形式 驱动代码的形式一般可分为build-in和module两种形式&#xff0c;build-in是在编译linux同时将pcie的驱动代码编译到内核中&#xff0c;启动的时候就载入该驱动代码&#xff1b;module是在linux启动完成后通过终端输入命令insmod/remod进行载入…

Windows 驱动开发 新手入门(一)

Windows 驱动开发 新手入门&#xff08;一&#xff09; 引言驱动介绍Win10 WDK 建立一个驱动项目建立MyDriver.cpp理论知识驱动入口派遣函数 MajorFunctionDevice和SymbolicLinkDeviceExtensionIRP 引言 首先祝朋友们新年快乐&#xff0c;然后呢&#xff0c;因为无聊&#xff…

驱动开发学习

驱动 1、驱动开发环境 完成系统移植的三步&#xff1a;u-boot启动引导程序、内核镜像、文件系统&#xff0c;u-boot启动引导程序最好固化到开发板上&#xff0c;内核镜像通过tftp服务从ubuntu下载&#xff0c;文件系统通过nfs服务从ubuntu共享到开发板&#xff0c;开发板启动…

Linux设备驱动开发详解

Linux设备驱动开发详解 Linux设备驱动开发详解Linux设备驱动开发Linux设备驱动开发详解1. linux设备驱动概述及开发环境搭建2. 驱动设计的硬件基础3. linux内核及内核编程4. linux内核模块5. linux文件系统与设备文件6. 字符设备驱动7. linux设备驱动中的并发控制8. linux设备驱…

QT部件基类——QWidget与QDialog

一、默认基类 QT提供的默认部件基类包括QMainWindow、QWidget、和QDialog这三种&#xff0c;这三个部件基类也是用的最多的。 QWidget类是所有部件对象的基类&#xff0c;被称为基础窗口部件&#xff0c;继承关系详看QWidget类关系图。QWidget提供自我绘制和处理用户输入等基本…

qt 中 qwidget 嵌入 qml

以上是效果图&#xff0c; 整个窗口是 qml 窗口 核心代码 #ifndef WIDGETANCHOR_H #define WIDGETANCHOR_H#include <QObject> #include <QQuickItem> #include <QWidget> #include <QQmlApplicationEngine> #include <QQmlContext>class WgtAn…

QWidget尺寸限定

1、控件只能在最小和最大之间进行调整&#xff0c;不能超过范围。 ①直接宽高同时设置 window.setMinimumSize(200, 200)&#xff1b; window.setMaximumSize(500, 500) app QApplication(sys.argv)window QWidget()window.setWindowTitle("最小最大窗口")windo…

QWidget居中显示

须知 以下函数只要继承QWidget都可以使用.例如 QDialog, QPushButton( -v- 一个居中的”引爆按钮”)关于坐标问题: qt窗口坐标原点是在”左上角”的. 如图, (x2, y2)是我窗口的分辨率的一半无论目前我的窗口在什么位置,我只要把窗口原点设置为(x1, y1)就行了.所以目前我要获得…

QWidget事件消息

1、用户操作界面时会产生特定的事件消息。 API&#xff1a;显示和关闭事件、移动事件、调整大小、鼠标事件、键盘事件、焦点事件、拖拽事件、绘制事件、改变事件、右键菜单、输入法。 应用场景&#xff1a;当一个控件被触发了一个特定的行为时&#xff0c;就会调用特定的方法…

QWidget的isHidden和isVisible

文章目录 问题的出现QWidget的show()函数QWidget的isVisible和isHidden源码追溯 QWidget的isHidden和isVisible 问题的出现 最近在写代码的时候&#xff0c;出现了一个问题&#xff0c;我新建了两个类&#xff0c;分别是Chapter2和ConsecutiveCurtain // ConsecutiveCurta…

QWidget鼠标操作

1、设置鼠标形状&#xff1a;鼠标放置在不同控件上&#xff08;有不同功能时&#xff09;鼠标的形状是不一样的。 鼠标跟踪&#xff1a;鼠标在某一个控件上移动&#xff0c;则会向对应的控件对象发送一个消息&#xff0c;去调用具体的某一个方法&#xff0c;可以在方法里面监听…

QWidget旋转方法

参考链接&#xff1a;https://stackoverflow.com/questions/43388464/rotate-whole-qwidget-by-angle 说明&#xff1a; 本文实现方法本质是使用QGraphics三件套&#xff0c;即View、Scene、Item&#xff0c;将QWidget控件作为Item显示&#xff0c;从而实现角度控制的目的&…

QWidget设置背景图及圆角

在Qt开发过程中&#xff0c;QWidget是经常作为主窗体的父窗口&#xff0c;有时我们需要对主窗口设置背景&#xff0c;设置圆角以达到美观的效果&#xff0c;通常的有以下三种方法&#xff1a;qss, QPalette设置以及paintEvent绘制。下面介绍这三种方法。 背景设置介绍 方法一&a…

QWidget之adjustSize

from PyQt5.Qt import * import sys# 创建一个应用程序对象 app QApplication(sys.argv)window QWidget()label QLabel(window) label.setText(学无止境) label.move(100, 100) label.setStyleSheet(background-color:gray)def changeCao():tmp label.text()学无止境label.…

初识QWidget

初识QWidget 在Qt中QWidget是一个非常关键和重要的类&#xff0c;推荐初学Qt的同学们第一个学习此类 在Qt的帮助手册中我们搜索QWidget&#xff0c;可以看到下图的描述 通过帮助手册我们了解到如果想使用QWidget这个类&#xff0c;需要包含QWidget这个头文件&#xff0c;Qt特…

QWidget继承

查看QWidget的继承于哪个类 方法一 随便写一个类继承自己QWidget 按住Ctrl鼠标单击QWidget即可 方法二 print(QWidget.__base__)方法三 print(QWidget.mro()) 链条式的继承展示 enjoy

QWidget(长文)

一、描述 1、QWidget 是用户界面的原子&#xff1a;它从窗口系统接收鼠标、键盘和其他事件&#xff0c;并在屏幕上绘制自己的表示。每个小部件都是矩形的&#xff0c;它们按Z顺序排序。小部件由其父部件和它前面的小部件剪裁。 2、未嵌入父窗口小部件的 QWidget 称为窗口。通…