• 《Linux驱动:USB设备驱动》


    一,前言

    这一篇学习分析USB设备驱动程序,主要涉及到USB子系统概览、USB总线驱动框架、USB总线-设备-驱动模型。最后模拟实现一个USB设备驱动程序。

    二,USB子系统

    2.1 USB驱动基础概念

    2.1.1 USB版本

    版本理论最大速率花名
    USB 1.01.5Mbps低速(Low-Speed)
    USB 1.112Mbps全速(Full-Speed)
    USB 2.0480Mbps高速(High-Speed)
    USB 3.05Gbps超高速(Super-Speed)
    USB 3.110Gbps超高速+(Super-speed+)
    USB 4.040Gbps

    2.1.2 USB主从结构

    USB分为USB 主机(USB Host)和USB device(USB设备)。比如USB鼠标插入到电脑,电脑就是USB Host,鼠标就是USB device。所有的USB传输,都是从USB主机这方发起的;USB设备没有"主动"通知USB主机的能力。

    2.1.3 USB的传输类型

    • 控制传输:控制传输是双向传输,数据量通常比较小,主要指由USB总线驱动程序用来进行查询、配置以及给USB设备发送通用的命令。控制传输典型地用在主计算机和USB外设之间的端点0(Endpoint 0)之间的传输,但是指定供应商的控制传输可能用到其它的端点。比如:USB设备的识别过程。
    • 批量传输:主要应用在数据大量传输,同时又没有带宽和间隔时间要求的情况下,进行可靠传输。比如:U盘拷贝数据。
    • 中断传输:中断传输主要用于定时查询设备是否有中断数据要传输,设备的端点模式器的结构决定了它的查询频率,从1到255ms之间。这种传输方式典型的应用在少量的、分散的、不可预测数据的传输,比如,键盘和鼠标就属于这一类型。中断传输是单向的并且对于host来说只有输入的方式。
    • 实时传输:实时传输提供了确定的带宽和间隔时间,它被用于时间严格并具有较强容错性的流数据传输,或者用于要求恒定的数据传输率的即时应用中。比如:USB摄像头。

    2.1.4 USB设备描述符

    在这里插入图片描述

    • 一个USB设备描述符中有多个配置描述符,一个配置描述符中有多个接口描述符,多个接口描述符中有多个节点描述符,多个接口描述符中有多个端点描述符。
    • 接口,表示逻辑上的设备,比如USB声卡可以分为接口1-录音设备,接口2-播放设备。
    • 访问设备时,即访问某个接口,接口表示逻辑设备。
    • 传输数据时,即读写某个端口,端口是数据通道。

    2.1.4.1 设备描述符

    /* USB_DT_DEVICE: Device descriptor */
    struct usb_device_descriptor {
    	__u8  bLength; //该结构体大小
    	__u8  bDescriptorType; //描述符类型
     
    	__le16 bcdUSB; //usb版本号 200->USB2.0
    	__u8  bDeviceClass; //设备类 
    	__u8  bDeviceSubClass; //设备类子类
    	__u8  bDeviceProtocol; //设备协议,以上三点都是USB官方定义
    	__u8  bMaxPacketSize0; //端点0最大包大小
    	__le16 idVendor; //厂家id
    	__le16 idProduct; //产品id
    	__le16 bcdDevice; //设备出厂编号
    	__u8  iManufacturer; //设备厂商字符串索引
    	__u8  iProduct; //产品描述
    	__u8  iSerialNumber; //设备序列号字符串索引 
    	__u8  bNumConfigurations; //配置的个数
    } __attribute__ ((packed));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.1.4.2 配置描述符

    struct usb_config_descriptor {
    	__u8  bLength; //该结构体大小
    	__u8  bDescriptorType;//描述符类型(本结构体中固定为0x02)  
     
    	__le16 wTotalLength; //该配置下,信息的总长度(包括接口描述符)
    	__u8  bNumInterfaces; //接口的个数
    	__u8  bConfigurationValue; //Set_Configuration命令所需要的参数值
    	__u8  iConfiguration; //描述该配置的字符串的索引值 
    	__u8  bmAttributes;//供电模式的选择  
    	__u8  bMaxPower;//设备从总线提取的最大电流
    } __attribute__ ((packed));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.1.4.3 接口描述符

    struct usb_interface_descriptor {
    	__u8  bLength;		//该结构体大小
    	__u8  bDescriptorType;//接口描述符的类型编号(0x04)
     
    	__u8  bInterfaceNumber;  //该接口的编号  
    	__u8  bAlternateSetting; //备用的接口描述符编号  
    	__u8  bNumEndpoints; //该接口使用的端点数,不包括端点0  
    	__u8  bInterfaceClass; //接口类
    	__u8  bInterfaceSubClass; //子类
    	__u8  bInterfaceProtocol; //协议
    	__u8  iInterface;//描述该接口的字符串索引值  
    } __attribute__ ((packed));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.1.4.4 端点描述符

    /* USB_DT_ENDPOINT: Endpoint descriptor */
    struct usb_endpoint_descriptor {
    	__u8  bLength;        //端点描述符字节数大小(7个字节)
    	__u8  bDescriptorType;//端点描述符类型编号(0x05) 
     
    	__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));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    USB的数据传输对象

    端点,一个USB设备可以有多个端点,和主机间的数据传输称为到设备端点的数据传输。比如说,对于一个U盘,可以细分为两个端点,把数据写到U盘的端点1、从U盘的端点2读取数据。

    2.2 USB子系统框架

    在这里插入图片描述

    三,USB总线驱动程序

    3.1 USB Core

    linux-2.6.22.6/drivers/usb/core/usb.c
    linux-2.6.22.6/drivers/usb/core/hub.c
    待梳理

    3.2 USB主机控制器驱动(HCD)

    linux-2.6.22.6/drivers/usb/host/ohci-hcd.c
    linux-2.6.22.6/drivers/usb/host/ohci-s3c2410.c
    待梳理

    四,USB设备驱动

    linux-2.6.22.6/drivers/hid/usbhid/usbmouse.c

    static struct usb_driver usb_mouse_driver = {
    	.name		= "usbmouse",
    	.probe		= usb_mouse_probe,
    	.disconnect	= usb_mouse_disconnect,
    	.id_table	= usb_mouse_id_table,
    };
    
    static int __init usb_mouse_init(void)
    {
    	int retval = usb_register(&usb_mouse_driver);
    	if (retval == 0)
    		info(DRIVER_VERSION ":" DRIVER_DESC);
    	return retval;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    五,实现一个USB设备驱动程序

  • 相关阅读:
    Linux进阶-控制硬件设备
    MySQL高级篇4
    /usr/lib/x86_64-linux-gnu/libQt5Core.so.5: version `Qt_5.15‘ not found
    城市大脑 术语
    antd a-list 添加分页
    Centos7扩容root分区
    第29课 绘制原理图——放置电源端口
    【MySQL数据库重点】第二节:MySQL基础知识(基本操作)
    store redux在项目中的应用
    【JAVASE】JDK8新特性
  • 原文地址:https://blog.csdn.net/qq_40709487/article/details/126474486