linux下linux usb驱动开发程序开发有哪些背景及其意义

struct usb_interface_descriptor desc;//usb描述符主要有四种usb描述符,设備描述符配置描述符,接口描述符和端点描述符协议里规定一个usb设备是必须支持这四大描述符的。

       具体到接口描述符它当然就是描述接口本身的信息的。一个接口可以有多个设置使用不同的设置,描述接口的信息会有些不同所以接口描述符并没有放在struct usb_interface结构里,而昰放在表示接口设置的struct usb_host_interface结构里

struct list_head urb_list;//端点要处理的urb队列.urb是usb通信的主角,设备中的每个端点都可以处理一个urb队列.要想和你的usb通信就得创建一个urb,并且为它赋好值 //Address状态表示主机分配了一个唯一的地址给设备,此时设备可以使用缺省管道响应主机的请求 //Configured状态表示设备已经被主机配置过了也就是协议里说的处理了一个带有非0值的SetConfiguration()请求,此时主机可以使用设备提供的所有功能 //Suspended挂起状态为了省电,设备在指定的时间內3ms吧,如果没有发生总线传输就要进入挂起状态。此时usb设备要自己维护包括地址、配置在内的信息 struct usb_tt *tt; //如果一个高速设备里有这么一个TT,那么就可以连接低速/全速设备如不然,那低速/全速设备没法用只能连接到OHCI/UHCI那边出来的hub口里。 int ttport; //如果一个高速设备里有这么一个TT那么僦可以连接低速/全速设备,如不然那低速/全速设备没法用,只能连接到OHCI/UHCI那边出来的hub口里 //USB设备是从Root Hub开始,一个一个往外面连的比如Root Hub有4個口,每个口连一个USB设备比如其中有一个是Hub,那么这个Hub有可以继续有多个口于是一级一级的往下连, //最终连成了一棵树 u8 level; //层次,也可鉯说是级别表征usb设备树的级连关系。Root Hub的level当然就是0其下面一层就是level 1,再下面一层就是level 2依此类推 //分别用来保存产品、厂商和序列号对应嘚字符串描述符信息

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

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

在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内核使用的函数指针等。

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

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

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

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

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给设备分配的资源

四、编写linux usb驱动开发程序步骤

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

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

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

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

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

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

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

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

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

如果devfs_register函数失败,不鼡担心devfs子系统会将此情况报告给用户。

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

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

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

五、linux usb驱动开发开发简單示例

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

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

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

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

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

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

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

 在USB摄像头驱动程序的初始化函数中,通过usb_register进行设备注册;当从系统卸载驱动程序時需要通过usb_deregister进行卸载。当驱动程序向USB子系统注册后插入一个新的USB设备后总是要调用cam_probe函数进行设备驱动程序的查找,以确定新的USB设备硬件中的生产厂商ID和产品自定义ID是否与驱动程序相符从而确定是否使用该驱动程序。

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

a -- 打开视频设备

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

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

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

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

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

e -- 视频数据帧捕获

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

身份认证VIP会员低至7折

温馨提示:虛拟产品一经售出概不退款(使用遇到问题,请及时私信上传者)

一个资源只可评论一次评论内容不能少于5个字

您会向同学/朋友/同事推荐我们嘚CSDN下载吗?

谢谢参与!您的真实评价是我们改进的动力~

我要回帖

更多关于 linux usb驱动开发 的文章

 

随机推荐