精华内容
下载资源
问答
  • VMware虚拟机USB驱动.zip

    2020-08-05 17:08:55
    VMware虚拟机USB驱动,具体为 vmusb.cat;vmusb.inf,vmusb.sys,安装方法csdn博客文章很多。
  • 介绍Linux 内核中USB 驱动的框架,图文并茂,设备的加载流程等等。
  • peak pcan_usb 驱动程序

    2018-09-21 14:45:09
    peak pcan_usb 驱动程序为peak公司开发的can总线硬件驱动模块,使用与windows系统下驱动程序。
  • 重点是usb驱动开发。学习完这三个文件后,你将拥有为usb设备开发windows驱动程序的能力。如需学习stm32 usb设备的开发,敬请关注本人csdn账号。本人有stm32 usb设备开发的相关文档:“STM32F10xxx全速USB设备开发...
  • console-usb驱动

    2017-07-20 00:24:46
    console-usb驱动,是电脑连接交换机必不可少的。
  • 安川SigmaWin+ USB驱动64bit(win10可用)
  • DAP下载器usb驱动

    2018-03-16 10:37:24
    DAP下载器usb驱动。stm32下载,好用稳定,不像jlink那样偶尔会过期失效。
  • 使用stm32F4的usb驱动4G模块,实现了通过USB虚拟出的串口,通过AT命令控制4G模块
  • 高通USB驱动QCUSB_Driver

    2016-11-02 15:24:45
    高通处理器手机ADB连接时需要的usb驱动,亲测可用
  • Xilinx 下载器Platform cable usb驱动 win7 32位亲测可用
  • mtp usb驱动32和64位下载(win7mtp usb驱动) Media Transfer Protocol Porting Kit 媒体传输协议移植工具包 解决手机连接电脑驱动安装失败导致手机识别不了的问题
  • 台达plc USB驱动

    2014-09-07 18:42:09
    台达PCL可编程控制器 USB驱动 ex2系列
  • Nexus5usb驱动

    2014-12-03 12:10:22
    Nexus % 官方驱动,适用于win 。
  • vas5054usb驱动

    2015-04-26 10:56:32
    vas-pc 破解安装usb驱动 支持win7 xp
  • 黑苹果mac无线网卡USB驱动,适用于mac sierra 10.12版本
  • 松下PLC USB驱动

    热门讨论 2012-12-05 08:27:49
    松下PLC , FP系列 ,USB驱动,用于PLC与计算机的通迅
  • cypress公司USB驱动

    热门讨论 2013-06-01 11:48:20
    cypress公司USB驱动包,有win 2000,win xp,win vista, win 7的32bit和64bit的驱动程序,API及相应例程和文档,需要先安装并在安装目录下找到这些文件
  • 霍尼韦尔1900USB驱动

    热门讨论 2013-06-30 07:03:14
    霍尼韦尔1900扫描枪USB驱动,honeywell 1900 扫描枪usb转com 设置在说明书里面扫描端口设置条码就可以了,不需要安装驱动
  • 高通HS-USB驱动 2.1.0.3,Qualcomm HS-USB Driver,QDLoader 9008

    千次下载 热门讨论 2015-03-28 17:15:46
    高通平台手机 Modem、网络、调试COM口 ...驱动版本 2.1.0.3 是目前最新版本的驱动了,支持如下 Qualcomm HS-USB QDLoader 9008 Qualcomm HS-USB Diagnostics Qualcomm HS-USB NMEA 等等很多高通平台手机调试所需的驱动
  • 串口转USB驱动 win7 64位。2015年10月12日已测试在win7 64位下可用。在添加驱动时,需要手工选择该驱动。
  • 三菱PLCUSB驱动程序

    2013-10-12 08:35:36
    三菱PLCFX系列编程软件编程完毕后利用电脑的USB接口将程序下载到PLC中去,这是编程电缆的驱动程序。
  • 设备驱动程序是操作系统内核和机器硬件之间的接口,由一组函数和一些私有数据组成,是应用程序和硬件设备之间的桥梁。在应用程序看来,硬件设备只是一个设备文件,应用程序可以像操作普通文件一样对硬件设备进行操作...
    
    

           设备驱动程序是操作系统内核和机器硬件之间的接口,由一组函数和一些私有数据组成,是应用程序和硬件设备之间的桥梁。在应用程序看来,硬件设备只是一个设备文件,应用程序可以像操作普通文件一样对硬件设备进行操作。

          设备驱动程序是内核的一部分,主要完成以下功能:对设备的初始化和释放把数据从内核传送到硬件设备和从硬件设备读取数据读取应用程序数据传送给设备文件和回送应用程序请求的数据检测和处理硬件设备出现的错误


    一、 Linux USB子系统分析

            在Linux系统中,USB主机驱动程序由3部分组成:USB主机控制器驱动(HCD)USB核心驱动(USBD)不同种类的USB设备类驱动,如下所示。其中HCD和USBD被称为协议软件或者协议栈,这两部分共同处理与协议相关的操作。

           USB设备类驱动可以包含多个,不同的功能接口对应不同的驱动程序,它们不直接与USB设备硬件打交道,而是通过协议软件的抽象处理来完成与设备的不同功能接口之间的通信

           在Linux USB子系统中,HCD是直接和硬件进行交互的软件模块是USB协议栈的最底层部分是USB主机控制器硬件和数据传输的一种抽象

          HCD向上仅对USB总线驱动程序服务,HCD提供了一个软件接口,即HCDI,使得各种USB主机控制器的硬件特性都被软件化,并受USB总线驱动程序的调用和管理。HCD向下则直接管理和检测主控制器硬件的各种行为。HCD提供的功能主要有:主机控制器硬件初始化;为USBD层提供相应的接口函数;提供根HUB(ROOT HUB)设备配置、控制功能;完成4种类型的数据传输等。

          USBD部分是整个USB主机驱动的核心,主要实现的功能有:USB总线管理;USB总线设备管理、USB总线带宽管理、USB的4种类型数据传输、USB HUB驱动、为USB设备驱动提供相关接口、提供应用程序访问USB系统的文件接口等。其中USB HUB作为一类特殊的USB设备,其驱动程序被包含在USBD层。

         在嵌入式Linux系统中,已经包含HCD模块和USB核心驱动USBD,不需要用户重新编写,用户仅仅需要完成USB设备类驱动即可。


    二、Linux系统中USB子系统的主要数据结构

            Linux系统中,USBD通过定义一组宏、数据结构和函数来抽象出所有硬件或是设备具有依赖关系的部分。

    USBD中主要有四个数据结构,分别是:

    1.usb_device保存一个USB设备的信息,包括设备地址,设备描述符,配置描述符等。

    2.usb_bus保存一个USB总线系统的信息,包括总线上设备地址信息,根集线器,带宽使用情况等。一个USB总线系统至少有一个主机控制器一个根集线器,Linux系统支持多USB总线系统。

    3.usb_driver保存客户驱动信息,包括驱动名称,以及驱动提供给USB内核使用的函数指针等。

    4.URB(Universal Request Block)是进行USB通信的数据结构,USBD通过URB在USB设备类驱动和USBD、USBD和HCD间进行数据传输。


    三、Linux系统中USB设备的加载与卸载

           当把一个USB设备插入到一个USB HUB的某个端口时,集中器就会检测到设备的接入,从而在下一次受到主机通过中断交互查询时就会向其报告。集中器的端口在没有设备接入时都处于关闭状态,插入设备之后也不会自动打开,必须由主机通过控制交互发出命令予以打开。所以,在得到集中器的报告之后,主机的USB驱动程序就会为新插入的设备调度若干个控制交互,并向集中器发出打开这个端口的命令,这样新插入的设备就会出现在USB总线上了,并为该设备分配唯一的地址

           HUB驱动程序调用函数usb_connect(struct usb_device *dev)usb_new_device(struct usb_device *dev)解析设备的各种描述符信息,分配资源,并与相应的设备驱动程序建立联系。

    函数usb_new_device主要完成以下工作:

    1.调用usb_set_address把新分配的设备地址传送给设备。

    2.调用usb_get_descriptor获得设备的设备描述符,得到设备端点的包的最大长度,接下来的控制传输按这个数据包最大长度进行。

    3.调用usb_get_configuration得到设备的所有配置描述符、接口描述符和端点描述符信息。

    4.调用usb_set_configuration激活当前的配置作为默认工作配置。

    5.在目录“proc/bus/usb”中为设备创建节点。

    6.在USB子系统中,通过函数usb_find_driversusb_find_interface_driver为设备的每一个接口寻找相应的驱动程序,驱动程序对接口进行配置并为它们分配所需的资源。当每个接口被成功驱动后,此设备就能正常工作了。

          设备拔下时,与之相联的集线器首先检测到设备的拔下信号,通过中断传输将信息传送给集线器的驱动,集线器的驱动先验证设备是否被拔下,如果是则调用usb_disconnect(struct usb_device **pdev)进行处理。设备断开后,USB系统找到设备当前活动配置的每个接口的驱动程序,调用它们提供的disconnect接口函数,中断它们与各个接口的数据传输操作,释放它们为每个接口分配的资源。如果此设备是集线器,则递归调用usb_disconnect来处理它的子设备,释放设备地址,通过usbdevfs_remove_device函数释放给设备创建的文件节点,通过usb_free_dev释放USBD给设备分配的资源。


    四、编写USB驱动程序步骤

    1、所有usb驱动都必须创建主要结构体struct usb_driver

    struct usb_driver

    ->struct module *owner

       (有他可正确对该驱动程序引用计数,应为THIS_MODULE)

    ->const char *name

       (驱动名字,运行时可在查看 /sys/bus/usb/drivers/)

    ->const struct usb_device_id *id_table

       (包含该驱动可支持的所有不同类型的驱动设备,没添探测回调函数不会被调用)

    ->int (*probe)(struct usb_interface *intf,const struct usb_device_id *id)

       (usb驱动探测函数,确认后struct usb_interface 应恰当初始化,然后返0,如果出错则返负值)

    ->void(*disconnect)(struct usb_interface *intf)

       (当struct usb_interface 被从系统中移除或驱动正从usb核心中卸载时,usb核心将调用此函数)

    代码实例:

    1. static struct usb_driver skel_driver={
    2. .owner = THIS_MODULE,
    3. .name = "skeleton",
    4. .id_table = skel_table,
    5. .probe = skel_probe,
    6. .disconnect = skel_disconnect,
    7. };

    2、usb_register()注册将struct usb_driver 注册到usb核心,传统是在usb驱动程序模块初始化代码中完成该工作的

    1. static int __ init usb_skel_init(void)
    2. {
    3. ...
    4. usb_register(&skel_driver);
    5. ...
    6. }

    3、struct usb_device_id usb核心用该表判断哪个设备该使用哪个驱动程序,热插拔脚本使用它来确定当一个特定的设备插入到系统时该自动装载哪个驱动程序

    ->__u16 match_flags(确定设备和结构体中下列字段中哪一个相匹配)
    ->__u16 idVendor(设备的usb制造商id)
    ->__u16 idProduct(设备的usb产品id) 


    4、USB骨架程序的关键几点如下:

    a -- USB驱动的注册和注销 

       Usb驱动程序在注册时会发送一个命令给usb_register,通常在驱动程序的初始化函数里。

       当要从系统卸载驱动程序时,需要注销usb子系统。即需要usb_unregister 函数处理。

    b -- 当usb设备插入时,为了使linux-hotplug(Linux中PCI、USB等设备热插拔支持)系统自动装载驱动程序,你需要创建一个MODULE_DEVICE_TABLE

    代码如下(这个模块仅支持某一特定设备):

    1. static struct usb_device_id skel_table [] = {
    2. { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
    3. { } /* Terminating entry */};
    4. MODULE_DEVICE_TABLE (usb, skel_table);

     USB_DEVICE宏利用厂商ID和产品ID为我们提供了一个设备的唯一标识。当系统插入一个ID匹配的USB设备到USB总线时,驱动会在USB core中注册。驱动程序中probe 函数也就会被调用。usb_device 结构指针、接口号和接口ID都会被传递到函数中。

    c -- static void * skel_probe(struct usb_device *dev,unsigned int ifnum, const struct usb_device_id *id)

           驱动程序需要确认插入的设备是否可以被接受,如果不接受,或者在初始化的过程中发生任何错误,probe函数返回一个NULL值。否则返回一个含有设备驱动程序状态的指针。通过这个指针,就可以访问所有结构中的回调函数。

    d -- 在骨架驱动程序里,最后一点是我们要注册devfs

          我们创建一个缓冲用来保存那些被发送给usb设备的数据和那些从设备上接受的数据,同时USB urb 被初始化,并且我们在devfs子系统中注册设备,允许devfs用户访问我们的设备。注册过程如下:

    1. /* initialize the devfs node for this device and register it */
    2. sprintf(name, "skel%d", skel->;minor);
    3. skel->devfs = devfs_register (usb_devfs_handle, name,DEVFS_FL_DEFAULT, USB_MAJOR,USB_SKEL_MINOR_BASE + skel->minor,
    4. S_IFCHR | S_IRUSR | S_IWUSR |S_IRGRP | S_IWGRP | S_IROTH, &skel_fops, NULL);
    如果devfs_register函数失败,不用担心,devfs子系统会将此情况报告给用户。

    当然最后,如果设备从usb总线拔掉,设备指针会调用disconnect 函数。驱动程序就需要清除那些被分配了的所有私有数据、关闭urbs,并且从devfs上注销调自己。
      /* remove our devfs node */devfs_unregister(skel->;devfs);


    5、其他

    a -- struct usb_host_endpoint(描述usb端点)

    →(包含)struct usb_endpoint_descriptor(含真正端点信息,数据格式,是真正驱动关心的字段)

     端点描述符:

    bEndpointAddress = 81(in)(第8位为1是输入设备)(usb的端点地址,包含端点方向)
    bmAttibutes = 03(interrupt)(端点类型,为中断传输)
    wMaxPacketSize = 0008(每次传8个字节)(端点每次可处理最大字节长度)
    bInterval = 08(8ms)(如端点为中断,该值为轮询间隔)

    b -- usb端点捆绑为接口,usb接口只处理一种usb逻辑连接,如鼠标键盘等

       一个usb设备可有多接口,usb扬声器:一个usb键盘用于按键,一个usb音频流,则需两个不同的驱动程序。

       usb驱动 通常将struct usb_interface 转成 struct usb_device 用函数 interface_to_usbdev转 

    c -- struct usb_interface 描述usb接口

       →struct usb_host_interface * altsetting(接口结构体数组,包含所有可能用于该接口的可选设置)
        →struct usb_host_endpoint
       →unsigned num_altsetting(可选设置的数量)
       →struct usb_host_interface * cur_altsetting(接口当前活动设置)
       →int minor(usb核心分配给接口的次设备号,成功调用usb_register_dev有效) 

    d -- usb设备非常复杂,由许多不同逻辑单元组成,简单关系如下:

       设备通常有一个以上的配置
       配置经常有一个以上接口
       接口通常有一个以上设置
       接口通常有一个以上端点
       设备描述-》配置描述-》接口描述-》端点描述 

    e -- usb sysfs设备命名方案

       根集线器-集线器端口号:配置。接口
       对于usb hub树中层次更高的字树命名方案
       根集线器-集线器端口号-集线器端口号:配置。接口 

    f --  linux内核的代码通过一个成为urb(usb请求块)和所有usb设备通信.  

     用struct urb描述(include/linux/usb.h中定义) 

       ->urb用异步同usb设备特定usb端点发送/接收数据,使用类似网络代码中的struct skbuff
       -> urb 被动态创建,随时可被驱动程序或usb核心取消,内部有引用计数,可被多次调用,使他们可在最后一个使用者释放他们时自动地销毁
       -> urb使得流处理或其他复杂的重叠的通信成为可能,获得高数据传输速度。 
       ->usb_alloc_urb() 创建urb包 usb_free_urb() 释放urb包 
       ->usb_fill_int_urb()正确初始化将发送到usb设备的中断端点urb
         usb_fill_bulk_urb() .. .. .. ... 批量传输端点urb
         usb_fill_control_urb() .. .. .. ... 控制端点urb
         等时urb在提交给核心时必须手动初始化(很不幸,没函数)
       ->usb_submit_urb()urb被usb驱动正确创建和初始化后,就可提交到usb核心,发送到usb设备上了,如果调用成功,函数返0,urb控制权转给usb核心
       ->usb_kill_urb() or usb_unlink_urb()取消已经被提交给核心的urb 


    五、USB驱动开发简单示例

    1、嵌入式Linux系统中USB摄像头驱动程序实现

         通常USB设备类驱动程序需要提供两个数据结构接口,一个针对USBD层,一个针对文件系统。USB摄像头驱动程序需要做的第一件事情就是在USB子系统里注册,并提供一些相关信息,包括该驱动程序支持哪些设备,当被支持的设备从总线插入或拔出时,会有哪些动作等,所有这些信息通过usb_driver的形式传送到USBD中,具体实现如下:

    1. static struct usb_driver cam_driver = {
    2. .name: "cam_video",
    3. .probe: cam_probe,
    4. .disconnect: cam_disconnect,
    5. .id_table: cam_ids,
    6. };

    其中

    cam_video是客户端驱动程序的字符串名称,用于避免驱动程序的重复安装和卸载;

    cam_probe则指向USB驱动程序的探测函数指针,提供给USB内核的函数用于判断驱动程序是否能对设备的某个接口进行驱动

    cam_disconnect指向USB驱动程序中的断开函数的指针,当从系统中被移除或者驱动程序正在从USB核心中卸载时,USB核心将调用该函数;

    cam_ids列表包含了一系列该驱动程序可以支持的所有不同类型的USB设备,如没有设置该列表,则该驱动程序中的探测回调函数不会被调用。

           当一个摄像头连接到USB总线上时,USB内核通过调用camDrive.c中的cam_probe函数判断是否支持该设备,如果支持,为该设备创建设备文件节点,以后应用程序就可以通过标准POSIX函数,把该设备当成普通文件来访问。摄像头驱动程序定义的文件系统接口如下:

    1. struct file_operations cam_fops = {
    2. .owner = THIS_MODULE,
    3. .open = cam_v 4l2_open,
    4. .release = cam_v4l2_release,
    5. .ioctl = cam_v4l2_ioctl,
    6. .llseek = no_llseek,
    7. .read = cam_v4l2_read,
    8. .mmap = cam_v4l2_mmap,
    9. .poll = cam_v4l2_poll,
    10. };
         在USB摄像头驱动程序的初始化函数中,通过usb_register进行设备注册;当从系统卸载驱动程序时,需要通过usb_deregister进行卸载。当驱动程序向USB子系统注册后,插入一个新的USB设备后总是要调用cam_probe函数进行设备驱动程序的查找,以确定新的USB设备硬件中的生产厂商ID和产品自定义ID是否与驱动程序相符,从而确定是否使用该驱动程序。


     2、USB摄像头驱动程序测试

           在嵌入式Linux系统中,USB摄像头被注册为一个标准的视频设备/dev/video,通过影像设备API接口Video4Linux来获取视频和音频数据。

    现有的Video4Linux有两个版本:v4l和v4l2。通过v4l2 API接口获取视频图像的主要操作步骤如下:

    a -- 打开视频设备

    在Linux系统中,摄像头的设备文件为/dev/video0,调用系统函数open打开该设备。

    fd = open (dev_name, O_RDWR);

    b -- 获取视频设备所支持的V4L2特性

          所有的V4L2设备驱动都需要支持VIDIOC_QUERYCAP_ioctl的系统调用。通过该调用,确定该驱动程序是否与V4L2规范相兼容,同时获取该设备所支持的V4L2特性。在摄像头应用程序的开发过程中,需要判定该设备是否支持视频捕获。

    ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);

    c -- 获取视频设备支持的各种特性

          接着,利用ioctl(fd,VIDIOC_QUERYCAP,&cap)函数读取struct v4l2_capability中有关摄像头的信息。该函数成功返回后,这些信息从内核空间拷贝到用户程序空间capability各成员分量中。

    ioctl(device_fd, VIDIOCGCAP, &vidcap);

    d -- 设置视频捕获的图像格式

    memset(&fmt, 0, sizeof(struct v4l2_format));
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width = vd->width;
    fmt.fmt.pix.height = vd->height;
    fmt.fmt.pix.pixelformat = vd->formatIn;
    ret = ioctl(fd, VIDIOC_S_FMT, &fmt);

    e -- 视频数据帧捕获

    ioctl (fd, VIDIOC_DQBUF, &buf);

    获取到视频数据之后,放到buf缓冲区中,通过QT桌面应用开发系统,显示到LCD显示屏上,通过触摸屏进行交互控制。

    展开全文
  • USB驱动框架

    千次阅读 2019-06-08 21:54:06
    一开始分析USB转串口驱动一头扎到源码,也就是追了个流程,但是还是什么都不懂,再后来看USB驱动框架也还是晕乎乎,之后再看了USB基础才慢慢理解一点。 一、USB基础知识 USB是Universal Serial Bus的缩写,中文译...

    一开始分析USB转串口驱动一头扎到源码,也就是追了个流程,但是还是什么都不懂,再后来看USB驱动框架也还是晕乎乎,之后再看了USB基础才慢慢理解一点。

    一、USB基础知识

    USB是Universal Serial Bus的缩写,中文译为通用串行总线,USB出现之前,计算机领域中的接口太多太繁杂,USB出现之后减少了接口的种类,总的来说就是设计出了一个万能的接口,各种外设都能用同一种接口,所以才冠以“通用(是Universal)”为名。

    USB设备,从物理上的逻辑结构来说,包含了主机Host端和设备Device端。

    其中,主机Host端,有对应的硬件的USB的主机控制器Host Controller,而设备端,连接的是对应的USB设备。

    USB Host(USB主机)

    主机就是USB总线中作主设备角色的设备, 负责管理USB总线中的数据传输及端口管理.

    比如一个U盘(USB大容量储存设备)和PC通讯, PC在这里就是USB Host.

    USB Device(USB设备)

    USB Device就是在USB总线中作从设备角色的设备

    USB Hub(USB集线器)

    USB Hub可以将一个USB口转换为多个,USB Host带有Root Hub,第一个USB设备是一个根集线器(Root_hub)它控制连接到其上的整个USB总线,该控制器是连接PCI总线和USB总线的桥,也是该总线上的第一个USB设备,USB Hub对于上游而言是一个USB Device, 对于下游而言扮演USB Host, 所以USB设备本身不知道自己连接在Hub还是Root Hub上

    先了解有这些东西,USB分主机端和设备端,知道有主机控制器(Host Controller)、设备(Device)、还有USB集线器(USB Hub)这些东西,下面再看到会眼熟,不会说是凭空出现一头雾水,这里也主要只讲主机端

    二、Linux内核USB驱动框架

    Linux内核支持两种主要类型的USB驱动程序:宿主(host)系统上的驱动程序和设备(device)上的驱动程序。从宿主的USB驱动程序控制插入其中的USB设备,而USB设备的驱动程序控制该设备如何作为一个USB设备和主机通信,由于“USB设备驱动程序”(USB devices drivers)容易混淆,USB开发者创建了术语“USB器件驱动程序”(USB gadget drivers)来描述控制连接到计算机的USB的设备驱动程序。

    USB的主机控制器(HUD),出现了多种不同的类型,即OHCI和UHCI,EHCI,和xHCI,不同USB控制器类型OHCI,UHCI,EHCI,xHCI的区别和联系

    USB采用树形拓扑结构,主机侧和设备侧的USB控制器分别称为主机控制器(Host Controller)和USB设备控制器(UDC),每条总线上只有一个主机控制器,负责协调主机和设备间的通信,设备不能主动向主机发送任何消息。

    主机侧:

    从主机侧去看,在Linux驱动中,处于USB驱动最底层的是USB主机控制器硬件,在其上的是USB主机控制器驱动,在主机控制器驱动上的为USB核心层,再上层为USB设备驱动层。因此,在主机侧的层级结构中,要实现的USB驱动包括:USB主机控制器驱动和USB设备驱动。

    USB核心层(USB core)向上为USB设备驱动提供编程接口,向下为USB主机控制器驱动提供编程接口,维护整个系统的USB设备信息,完成设备热插拔控制、总线数据传输控制等。

    USB设备驱动(USB Devices driver)负责驱动具体的设备,例如U盘,鼠标等设备。USB设备驱动既可以注册成某个类型的设备驱动,例如输入子系统,此时的主设备号依据具体的子系统而定;又可以作为一个独立的USB设备注册进系统,这时的主设备号是180(USB_MAJOR)。

    USB主机控制器驱动的代码位于:driver/usb/host,根据具体的硬件实现一个该硬件对应的主机控制器驱动的文件。

    USB核心层代码位于:driver/usb/core。

    USB设备驱动代码依据具体的设备放在对应的目录下。

    当然还不止这些,设备、USB控制器,还少了个USB集线器,主机通过根集线器连接到各种外围设备(集线器和功能部件),USB物理总线拓扑:

    当USB设备连接到集线器,集线器状态将发生相应的变化,并将状态变化信息传递给USB主机。USB主机通过根集线器向USB设备发送命令,获取USB设备的各种信息,包含USB设备传输类型、ID号、Product、USB速度等信息

    Linux内核通过USB代码通过一个称为(USB请求块)的东西和所有的USB设备通信。USB数据传输都以URB(USB Request Block)请求URB生成URB递交URB释放为主线。从上图可知,当加载控制器驱动之后,注册根据集线器,hub(集线器)和hcd(host controller driver)驱动成为一个整体。接着,主机通过控制传输获取设备的控制描述符等信息。
        USB从设备通过集线器或根集线器连接到USB主机上。比如:主机通过根集线器与外界进行数据交互,根集线器通过探测数据线状态的变化来通知USB主机是否有USB外围设备接入

    在主机端控制器驱动加载的过程中,注册了根集线器,然后匹配了相应的hub驱动程序,同时完成了对Hub轮询函数和状态处理函数的设置。这样一旦hub集线器的状态发生变化,就会产生相应的中断,主机端控制器就会执行相应的中断处理函数Hub集线器主要是用于USB的匹配识别。

    USB匹配识别的框架:

     

    下面贴出主机驱动框架也就好理解了:

    一旦hub集线器的状态发生变化,就会产生相应的中断,主机端控制器就会执行相应的中断处理函数完成USB设备的识别匹配,USB控制器通过根集线器获取USB设备的各种信息,包含USB设备传输类型、ID号、Product、USB速度等信息。从上图也可以看到USB通过一个称为Urb(USB请求块)的东西和所有的USB设备通信。USB数据传输都以URB(USB Request Block)请求URB生成URB递交URB释放为主线。从上图可知,当加载控制器驱动之后,注册根据集线器,hub(集线器)和hcd(host controller driver)驱动成为一个整体。接着,主机通过控制传输获取设备的控制描述符等信息。USB主机和USB设备之间的数据传输共有四种类型:控制传输、批量传输、中断传输和同频传输。与之对应,USB主机和USB设备之间有四种事务:控制、批量、中断和等时。

    三、Linux USB 驱动简单介绍

    USB驱动程序存在于不同的内核子系统(块设备、网络设备、字符设备等等)和USB硬件控制器之中。

     

    USB核心为USB驱动程序提供了一个用于访问和控制USB硬件的接口,而不必考虑系统当前存在的各种不同类型的USB硬件控制器

    USB协议中共定义了以下四种描述符:
       1) 设备描述符
       2) 配置描述符
       3) 接口描述符
       4) 端点描述符

    一个USB设备文件描述符可以有多个配置,一个配置又可以有多个接口,一个接口可以有多个端点。

    端点:

    从最基础的端点说起。USB通信最基本的形式是通过端点(endpoint)的东西。USB端点只能往一个方向传送数据,从主机到设备(称为输出端点out)或者从设备到主机(称为输入端点in),端点可以看作是单向的管道。需要注意的是每个USB设备都有一个名为“端口0”的控制端点

    USB端点有四种不同的类型,分别具有不同的传送数据的方式:

    控制、中断、批量、等时

    内核中使用struct usb_host_endpoint结构体来描述USB端口,该结构体在另一个名为struct usb_endpoint_descriptor的结构体中包含真正的端点信息。

    struct usb_endpoint_descriptor {
    
        __u8  bLength;                            /* 描述符长度 */
    
        __u8  bDescriptorType;                    /* 描述符类型 端点描述符类型值是5 */
    
    
    
        __u8  bEndpointAddress;                   /* 端点地址:0~3位是端点号,第7位是方向(0为输出,1为输入) */
    
        __u8  bmAttributes;                       /* 端点属性:bit[0:1]的值为00表示控制,为01表示同步,为02表示批量,为03表示中断 */
    
        __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接口只处理一种USB逻辑,例如鼠标,键盘或者音频流,一些USB设备具有多个接口,例如例如一个USB声卡有两个接口,一个用来播放声音,一个用来录音。因为一个USB接口代表一个基本功能,而每个USB驱动程序控制一个接口,因此,以USB声卡为例,需要两个不同的驱动程序来处理一个硬件设备。

    内核使用struct usb_interface结构体来描述USB接口。USB核心把该结构体传递给USB驱动程序,之后由USB驱动程序来负责控制该结构体,同样的struct usb_endpoint_descriptor的结构体中包含真正的接口信息

    struct usb_interface_descriptor {
    
        __u8  bLength;                            /* 描述符长度 */
    
        __u8  bDescriptorType;                    /* 描述符类型 接口描述符类型值是4 */
    
    
    
        __u8  bInterfaceNumber;                   /* 接口的编号,相同的编号代表相同的功能接口 */
    
        __u8  bAlternateSetting;                  /* 接口的设置的编号,同一个接口可以有一个或者多个设置代表该接口下不同的参数 */
    
        __u8  bNumEndpoints;                      /* 该接口下的端点数,不包括端点0 */
    
        __u8  bInterfaceClass;                    /* 接口类型 */
    
        __u8  bInterfaceSubClass;                 /* 接口子类型 */
    
        __u8  bInterfaceProtocol;                 /* 接口遵循的协议 */
    
        __u8  iInterface;                         /* 描述该接口的字符串索引值 */
    
    } __attribute__ ((packed));

    配置:

    USB接口被捆绑为配置。一个USB设备可以有多个配置,而且可以在配置之间切换以改变设备的状态。例如,一些允许下载固件到其上的设备包含多个配置以完成这个工作,而一个时刻只能激活一个配置

    struct usb_config_descriptor {
    
        __u8  bLength;                            /* 描述符长度 */
    
        __u8  bDescriptorType;                    /* 描述符类型 配置描述符类型值是2 */
    
    
    
        __le16 wTotalLength;                      /* 配置下面所有描述符的长度,包括这个配置描述符 */
    
        __u8  bNumInterfaces;                     /* 配置所支持的接口数 */
    
        __u8  bConfigurationValue;                /* 配置值 */
    
        __u8  iConfiguration;                     /* 描述该配置的字符串的索引值 */
    
        __u8  bmAttributes;                       /* 供电模式的选择 */
    
        __u8  bMaxPower;                          /* 设备从总线提取的最大电流 */
    
    } __attribute__ ((packed));

    设备:

    一个设备里包含了不同级别的配置,可以有一个或者多个配置。设备描述符描述了这个设备。

    在linux中,结构体usb_device_descriptor对应于协议中的设备描述符。

    struct usb_device_descriptor {
    
        __u8  bLength;                           /* 描述符长度 */
    
        __u8  bDescriptorType;                   /* 描述符类型 设备描述符类型值是1 */
    
    
    
        __le16 bcdUSB;                           /* USB版本号 */
    
        __u8  bDeviceClass;                      /* USB分配的设备类code */
    
        __u8  bDeviceSubClass;                   /* USB分配的子类code */
    
        __u8  bDeviceProtocol;                   /* USB分配的协议code */
    
        __u8  bMaxPacketSize0;                   /* 端点0最大包大小 */
    
        __le16 idVendor;                         /* 厂商编号 */
    
        __le16 idProduct;                        /* 产品编号 */
    
        __le16 bcdDevice;                        /* 设备出厂编号 */
    
        __u8  iManufacturer;                     /* 描述厂商字符串的索引 */
    
        __u8  iProduct;                          /* 描述产品字符串的索引 */
    
        __u8  iSerialNumber;                     /* 描述设备序列号字符串的索引 */
    
        __u8  bNumConfigurations;                /* 可能的配置数量 */
    
    } __attribute__ ((packed));

    URB

    Linux内核通过一个称为urb(USB请求块)的东西和所有的USB设备通信。这个请求块使用struct urb结构体来形容,可从include/linux/usb.h文件中找到。Urb被用来以一种异步的方式往特定的USB设备上的特定USB端点发送/接收数据。USB设备驱动可能会为单个端点分配许多urb,也可能对许多不同的端点重用单个的urb,这取决于驱动程序的需要。Urb典型的生命周期如下:

    1. 由USB设备驱动程序创建。
    2. 分配给一个特定的USB设备的特定端点。
    3. 由USB设备驱动程序递交到USB核心。
    4. 由USB核心地递交到特定的设备的特定的USB主控制器驱动程序。
    5. 由USB主控制器驱动程序处理,从设备进行USB传送。
    6. 当urb结束之后,USB主控制器驱动通知USB设备驱动程序

    Urb创建的时候就可以创建成中断urb【usb_fill_int_urb()】,批量urb【usb_fill_bulk_urb()】,控制urb【usb_fill_contorl_urb()】还有等时urb,对应USB端点有四种不同的类型,分别具有不同的传送数据的方式:控制、中断、批量、等时

    其他的就可以自己追源码再去理解了

     

    参考:USB设备开发基础知识整理(学习笔记)

    http://noodlefighter.com/post/note_usb_application/

    USB协议架构及驱动架构:

    https://blog.csdn.net/liangdapo/article/details/43699785

     

    展开全文
  • mac 万能usb驱动

    热门讨论 2011-11-24 17:08:48
    mac 万能usb驱动 苹果 万能usb驱动
  • VMware虚拟机USB驱动

    热门讨论 2012-03-09 13:46:56
    VMwareUSB驱动,把主机的USB挂载到VM虚拟机时需要安装!!
  • ubuntu USB驱动

    2011-01-06 13:17:09
    ubuntu USB驱动
  • linux下usb驱动开发

    2009-10-12 19:45:42
    基于linux的usb驱动开发的介绍,USB是英文Universal Serial Bus的缩写,意为通用串行总线。USB最初是为了替代许多不同的低速总线(包括并行、串行和键盘连接)而设计的,它以单一类型的总线连接各种不同的类型的设备...
  • 解决rt2800usb驱动问题

    2013-05-07 20:14:00
    解决rt2800usb驱动问题
  • FT2232USB驱动

    热门讨论 2012-05-19 12:02:05
    FT2232H应用芯片的USB驱动软件,主要用于FT2232H的应用
  • FriendlyARM 友善之臂 USB驱动 WIN7_64

    热门讨论 2015-01-07 12:09:01
    FriendlyARM 友善之臂 USB驱动 WIN7_64

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 147,585
精华内容 59,034
关键字:

usb驱动