USB总线驱动程序
USB主机控制器:UHCI OHCI EHCI
UHCI:intel 低速(1.5Mbps)(USB1.1)/全速(12Mbps)(USB2.0,USB2.0又分为全速和高速)
OHCI:microsoft:低速/全速
EHCI:高速(480Mbps)
USB总线驱动程序的作用:
1. 识别USB设备
1.1 分配地址
1.2 并告诉USB设备(set address)
1.3 发出命令,获取描述符
描述符的信息可以在include\linux\usb\ch9.h中看到
2. 查找并安装对应的设备驱动程序
3. 提供USB读写函数
在程序中是如何调用的,简单的看一下:
在drivers/usb/core/hub.c文件中:
每一个USB控制器都自带有一个hub
hub_irq
kick_khubd
hub_thread
hub_events
hub_port_connect_change
choose_devnum //给新设备选择新的编号(地址)
hub_port_init
hub_set_address//把编号(地址)告诉USB设备,以后就使用这个地址了。
usb_get_device_descriptor(udev, 8);//获取设备描述符
retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);
usb_new_device(udev)
//把device放入bus的dev链表,从bus的driver链表中取出driver,如果能够匹配,调用driver的probe
device_add(&udev->dev);
注意:这个中断是主机控制器里面注册的中断,不是usb设备的中断。当接上一个USB设备之后,硬件上的手脚就使得D+或D-由低电平变为高电平,硬件上就感知了有USB设备接入,里面就会产生某个中断。从而就有了上面的调用过程。
hub_port_connect_change
choose_devnum //给新设备选择新的编号(地址)
/* Try to allocate the next devnum beginning at bus->devnum_next. */
//查找下一个0位,显然某个地址用了,里面的相应的地址就会设置为1,表示这个地址正在使用。从1找到128,如果找不到,就会从头找。假设你上次插入USB设备号,它devnum=5,那么它就会从5开始找,找到128后,如果没找到,它会从1开始再找。就是找一圈后,如果没找到,再回来。从这个地方也可以看出,一个USB主机控制器最多可以接128个USB设备。
devnum = find_next_zero_bit(bus->devmap.devicemap, 128,bus->devnum_next);
2、分析几个重要的数据结构
设备描述符:
/* USB_DT_DEVICE: Device descriptor */
struct usb_device_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 bcdUSB; //USB版本号
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0; //最大包大小,0表示端点0.每个设备都有端点0,因为是通过端点0识别出USB设备的
__le16 idVendor; //厂家ID
__le16 idProduct; //产品ID
__le16 bcdDevice;
__u8 iManufacturer;
__u8 iProduct;
__u8 iSerialNumber;
__u8 bNumConfigurations;
} __attribute__ ((packed));
配置描述符:
struct usb_config_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 wTotalLength;
__u8 bNumInterfaces;
__u8 bConfigurationValue;
__u8 iConfiguration;
__u8 bmAttributes;
__u8 bMaxPower;
} __attribute__ ((packed));
接口描述符:
/* USB_DT_INTERFACE: Interface descriptor */
struct usb_interface_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bInterfaceNumber;
__u8 bAlternateSetting;
__u8 bNumEndpoints;
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
__u8 iInterface;
} __attribute__ ((packed));
端点描述符
/* USB_DT_ENDPOINT: Endpoint descriptor */
struct usb_endpoint_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bEndpointAddress;
__u8 bmAttributes;
__le16 wMaxPacketSize; //从端点中一次写入或读出多少数据
__u8 bInterval;用查询的方式实现实时性的,此变量就表示查询的时间间隔。
/* NOTE: these two are _only_ in audio endpoints. */
/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
__u8 bRefresh;
__u8 bSynchAddress;
} __attribute__ ((packed));
它们的关系:
每一个USB设备,都有一个设备描述符,可以发出某些命令,得到USB设备描述符。一个硬件里面有一个设备描述符,
一个设备描述符里面还有配置描述符,一个设备描述符里面可能有多个配置描述符。
本节只是进行了简单的分析,并没有进行深入分析。需看《linux内核源码代码情景分析》
USB总线驱动程序的更多相关文章
- Linux驱动之USB总线驱动程序框架简析
通用串行总线(USB)是主机和外围设备之间的一种连接.USB总线规范有1.1版和2.0版,当然现在已经有了3.0版本.USB1.1支持两种传输速度:低速为1.5Mbps,高速为12Mbps.USB2. ...
- USB驱动程序之USB总线驱动程序学习笔记
USB总线驱动程序的作用 1. 识别USB设备 1.1 分配地址 1.2 并告诉USB设备(set address) 1.3 发出命令获取描述符 描述符的信息可以在include\linux\usb\ ...
- USB设备驱动程序学习笔记(一)
现象:把USB设备接到PC1. 右下角弹出"发现android phone"2. 跳出一个对话框,提示你安装驱动程序 问1. 既然还没有"驱动程序",为何能知道 ...
- USB驱动程序之USB设备驱动程序1简单编写
1.驱动编写分析 (1)usb总线驱动程序在我们接入USB设备的时候会帮我们构造一个新的usb_device.注册到总线里面来.左边这一块已经帮我们做好了,我们要做的是右边这一块.我们要构造一个usb ...
- USB驱动程序之USB设备驱动程序2鼠标用作键盘学习笔记
1.usbmouse.c (1)probe函数 在这个probe函数后判断是不是一个鼠标,先得到usb_host_interface结构体,除了端点0外,端点个数如果不是1,返回错误,表示不是自己能支 ...
- USB设备驱动程序(二)
首先我们来看USB设备描述符的结构: 在USB总线识别设备阶段就将USB描述符发送给了USB总线驱动程序,设备的数据传输对象是端点,端点0是特殊端点,在USB总线驱动程序识别阶段, 会分配一个地址给U ...
- USB设备驱动程序(一)
USB驱动编程原理: 当我们把USB设备插入USB口时会提示需要安装相对应的驱动,如USB鼠标.USB键盘等,这些电脑自己自身已经自带有相对于的驱动程序, 当电脑检查到该USB设备类型相同就去帮你安装 ...
- 12、USB设备驱动程序
linux-3.4.2\driver\hid\usbhid\usbmouse.c 内核只带USB驱动程序 (hub和usb是两个不同的设备,hub在内核上电的过程中在usb_hub_init函数中调用 ...
- USB设备驱动程序1
目的:USB鼠标用作按键,左键相当于字母L,右键相当于字母S,中键相当于Enter.如何来实现?用到输入子系统:1)分配input_dev2)设置3)注册4)硬件相关操作对于USB鼠标来说,硬件操作应 ...
随机推荐
- nginx日志说明
一.日志说明 nginx日志主要有两种:访问日志和错误日志.访问日志主要记录客户端访问nginx的每一个请求,格式可以自定义:错误日志主要记录客户端访问nginx出错时的日志,格 式不支持自定义.两种 ...
- [LeetCode] 882. Reachable Nodes In Subdivided Graph 细分图中的可到达结点
Starting with an undirected graph (the "original graph") with nodes from 0 to N-1, subdivi ...
- Unity Shader 屏幕后效果——高斯模糊
高斯模糊是图像模糊处理中非常经典和常见的一种算法,也是Bloom屏幕效果的基础. 实现高斯模糊同样用到了卷积的概念,关于卷积的概念和原理详见我的另一篇博客: https://www.cnblogs.c ...
- Prometheus 监控Mysql服务器及Grafana可视化
Prometheus 监控Mysql服务器及Grafana可视化. mysql_exporter:用于收集MySQL性能信息. 使用版本 mysqld_exporter 0.11.0 官方地址 使用文 ...
- nginx 的一些优化(突破十万并发)
一般来说 nginx 配置文件中对优化比较有作用的为以下几项: worker_processes 8; nginx 进程数,建议按照 cpu 数目来指定,一般为它的倍数. worker_cpu_aff ...
- 关于thinkphp3.2.3集成phpmailer
关于thinkphp3.2.3集成phpmailer 1 我用的是phpmailer5.1的版本 先把文件解压缩放到这个位置 2 封装到函数里面 function email($email,$tit ...
- C#配置文件configSections详解
一.问题需求: 在项目中经常遇到需要写配置文件地方,目的就是不想在程序中关于一些信息写死,发布的时候只需要修改一下配置文件就可以,不需要每次都修改程序,如项目名称.数据库连接字符串.IP端口之类 的: ...
- 正则表达式(RegEx)官方手册/权威指南【Python】
前言 正则表达式(称为RE,或正则,或正则表达式模式)本质上是嵌入在Python中的一种微小的.高度专业化的编程语言,可通过 re 模块获得. 使用这种小语言,你可以为要匹配的可能字符串集指定规则:此 ...
- 洛谷 p1387最大正方形
洛谷 p1387最大正方形 题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入格式 输入文件第一行为两个整数n,m(1<=n,m<=100),接下来 ...
- Nuxt中使用Vant,完成通知栏Notify的提示
第一次移动端开发,UI方面选择了使用vant框架,但是vant官网写的使用,在nuxt项目中照搬官方的实例,各种报错,所以还得靠自己(使用方法在最后) 官方实例: 方法一:直接复制粘贴的时候,报错No ...