USB设备驱动开发深度解析
- 格式:pdf
- 大小:615.66 KB
- 文档页数:31
Linux 下wifi 驱动开发(四)——USB接口WiFi驱动浅析前面学习了SDIO接口的WiFi驱动,现在我们来学习一下USB接口的WiFi驱动,二者的区别在于接口不同。
而USB接口的设备驱动,我们前面也有学习,比如USB摄像头驱动、USB鼠标驱动,同样都符合LinuxUSB驱动结构:USB设备驱动(字符设备、块设备、网络设备)|USB 核心|USB主机控制器驱动不同之处只是在于USB摄像头驱动是字符设备,而我们今天要学习的WiFi驱动是网络设备;当然由我们编写的部分还是USB设备驱动部分,下面进入USB接口WiFi驱动的分析,如何分析呢?我们下面从这几个方面入手:从硬件层面上看,WIFI设备与CPU通信是通过USB接口的,与其他WIFI设备之间的通信是通过无线射频(RF)。
从软件层面上看,Linux操作系统要管理WIFI设备,那么就要将WIFI设备挂载到USB总线上,通过USB子系统实现管理。
而同时为了对接网络,又将WIFI设备封装成一个网络设备。
我们以USB接口的WIFI模块进行分析:a -- 从USB总线的角度去看,它是USB设备;b -- 从Linux设备的分类上看,它又是网络设备;c -- 从WIFI本身的角度去看,它又有自己独特的功能及属性,因此它又是一个私有的设备;通过上述的分析,我们只要抓住这三条线索深入去分析它的驱动源码,整个WIFI驱动框架就会浮现在你眼前。
一、框架整理1、USB设备驱动现在我们先从USB设备开始,要写一个USB设备驱动,那么大致步骤如下:a -- 需要针对该设备定义一个USB驱动,对应到代码中即定义一个usb_driver结构体变量代码如下:[cpp]view plain copyb -- 填充该设备的usb_driver结构体成员变量代码如下:[cpp]view plain copyc -- 将该驱动注册到USB子系统代码如下:[cpp]view plain copy以上步骤只是一个大致的USB驱动框架流程,而最大和最复杂的工作是填充usb_driver结构体成员变量。
边干边写之——USB设备开发过程解析(前台VB+驱动VC+固件GCC)[声明:]1、本文为开发工作过程中的心得体会,认识粗浅表述不周之处请见谅;2、本文内容供广大爱好者学习交流之用,如需转载请注明出处并告知本人。
KKND 08年11月21日清晨发表于VBGood论坛Dreamon-II Labs.******************************************************************************[正文]其实弄清楚USB的工作流程后开发USB设备是很简单的事情。
简单来说无非是这样的过程:开发设备硬件-> 编写设备固件程序-> 编写驱动程序-> 开发应用程序其中后3项主要是软件编程工作,也是本文讨论的重点。
应用程序与USB硬件设备通信自底向上需要完成三部分程序的开发:固件程序 <-USB总线驱动程序-> 设备驱动程序 <-系统I/O管理器-> 用户应用程序以下分别将这三部分程序中用于实现通信的核心代码加以介绍。
固件程序:固件程序也就是所谓的“下位机”程序,它运行于设备上,由设备上的单片机执行,用于控制USB接口芯片与主机进行通信。
开发环境:GCC + AVR Studio……/******************************************************************* USB中断处理,该中断由USB接口芯片产生,由下位机CPU处理******************************************************************/void usb_isr(void){……if ( D12_int_flags & D12_INT_ENDP0OUT ) control_out_handler(); // 产生USB控制端点接收中断时调用该函数……}/******************************************************************* 处理USB控制端点接收事件******************************************************************/ void control_out_handler( void ){……control_dispatcher(); // 调用分发处理函数}/******************************************************************* 分发处理,根据URB 的请求类型和请求号选择相应的处理函数******************************************************************/ void control_dispatcher( void ){uchar type, req;type = ControlData.DeviceRequest.bmRequestType & USB_REQUEST_TYPE_MASK;req = ControlData.DeviceRequest.bRequest;……if ( type == USB_VENDOR_REQUEST ) // 处理用户自定义请求{// 根据请求号选择请求处理函数表入口if ( req < NUMBER_VENDOR_REQ ) (*VendorDeviceRequest[req])();}……}/******************************************************************* 用于处理用户请求的函数入口表******************************************************************/ const pfnvoid VendorDeviceRequest[] ={fun0,fun1,fun2,……};/******************************************************************* 用户请求处理函数实现******************************************************************/void fun0(void){uint8_t txdata[LEN];……single_transmit(txdata, LEN);}驱动程序:目前Windows系统下的驱动程序通常采用WDM模型(Win32 Driver Model,Win32驱动模型),采用Microsoft提供的DDK开发,借助第三方驱动程序开发工具比如DriverStudio 可以大大简化开发过程。
嵌入式USB设备驱动的研究与设计开发随着科技的飞速发展,嵌入式系统已经成为现代生活中不可或缺的一部分。
而作为嵌入式系统中最常见的外设之一,USB设备的驱动程序对于系统的正常运行起着至关重要的作用。
因此,对嵌入式USB设备驱动的研究与设计开发具有极高的实用价值和深远的意义。
嵌入式USB设备驱动的研究主要涉及到硬件和软件两个方面。
在硬件方面,需要对USB接口的工作原理进行深入研究,了解USB设备的接口规范以及各种USB设备的特性和使用场景。
同时,还需要研究与开发USB设备的驱动电路,确保其能够与嵌入式系统正常通信,并能实现数据的传输和交互。
在软件方面,嵌入式USB设备驱动的设计开发主要包括驱动程序的编写和优化。
首先,需要针对不同的USB设备类型和功能,编写相应的驱动程序。
例如,对于USB存储设备,需要编写文件系统的驱动程序,实现对存储设备的读写操作;对于USB打印机,需要编写打印机控制命令的驱动程序,实现打印功能等。
其次,还需要优化驱动程序的性能,提高系统的响应速度和稳定性。
这需要通过对驱动程序进行调试和测试,发现并修复可能存在的问题,确保驱动程序能够在不同的嵌入式平台上正常运行。
嵌入式USB设备驱动的研究与设计开发还涉及到与操作系统的兼容性和互通性。
不同的嵌入式系统可能采用不同的操作系统,如Linux、Windows等。
因此,在进行驱动程序的设计和开发时,需要考虑到不同操作系统的特点和要求,确保驱动程序能够在不同的操作系统环境下正常运行和兼容。
总之,嵌入式USB设备驱动的研究与设计开发是一个涉及到硬件和软件的综合性工作。
通过对USB接口的研究和了解,编写和优化驱动程序,考虑与操作系统的兼容性和互通性,可以实现嵌入式系统与USB设备之间的良好交互和数据传输,为现代生活中的各种嵌入式系统提供稳定可靠的外设支持。
这将进一步推动嵌入式系统的发展和应用,为人们的生活带来更多便利和创新。
第17章USB设备驱动USB设备驱动和PCI设备驱动是PC中最主要的两种设备驱动程序。
与PCI协议相比,USB协议更复杂,涉及面较多。
本章将介绍USB设备驱动开发。
首先介绍USB协议,使读者对USB协议有个整体认识。
然后介绍USB设备在WDM中的开发框架。
由于操作系统的USB总线驱动程序提供了丰富的功能调用,因此开发USB驱动开发变得相对简单,只需要调用USB总线驱动接口。
17.1 USB总线协议USB总线协议比PCI协议复杂的多,涉及USB物理层协议,又涉及USB传输层协议等。
对于USB驱动程序开发者来说,不需要对USB协议的每个细节都很清楚。
本节概要地介绍USB总线协议,并对驱动开发者需要了解的地方进行详细介绍。
17.1.1 USB设备简介USB即通用串行总线(Universal Serial Bus),是一种支持即插即用的新型串行接口。
也有人称之为“菊链(daisy-chaining)”,是因为在一条“线缆”上有链接127 个设备的能力。
USB要比标准串行口快得多,其数据传输率可达每秒4Mb~12Mb(而老式的串行口最多是每秒115Kb)。
除了具有较高的传输率外,它还能给外围设备提供支持。
需要注意的是,这不是一种新的总线标准,而是计算机系统连接外围设备(如键盘、鼠标、打印机等)的输入/输出接口标准。
到现在为止,计算机系统连接外围设备的接口还没有统一的标准,例如,键盘的插口是圆的、连接打印机要用9针或25针的并行接口、鼠标则要用9针或25针的串行接口。
USB能把这些不同的接口统一起来,仅用一个4针插头作为标准插头,如图17-1所示。
通过这个标准插头,采用菊花链形式可以把所有的外设连接起来,并且不会损失带宽。
USB正在取代当前PC上的串口和并口。
第17章 USB 设备驱动431图17-1 USB 的四条传输线以USB 方式连接设备时,所有的外设都在机箱外连接,连接外设不必再打开机箱;允许外设热插拔,而不必关闭主机电源。
linux设备驱动(28)usb驱动开发过程总结设备驱动程序是操作系统内核和机器硬件之间的接⼝,由⼀组函数和⼀些私有数据组成,是应⽤程序和硬件设备之间的桥梁。
在应⽤程序看来,硬件设备只是⼀个设备⽂件,应⽤程序可以像操作普通⽂件⼀样对硬件设备进⾏操作。
设备驱动程序是内核的⼀部分,主要完成以下功能:对设备的初始化和释放;把数据从内核传送到硬件设备和从硬件设备读取数据;读取应⽤程序数据传送给设备⽂件和回送应⽤程序请求的数据;检测和处理硬件设备出现的错误。
1 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层。
USB驱动分析一这个故事中使用的是2.6.10的内核代码.Linux内核代码目录中, 所有去设备驱动程序有关的代码都在drivers/目录下面,在这个目录中我们用ls命令可以看到很多子目录. localhost:/usr/src/linux-2.6.10/drivers # lsKconfig atm cdrom eisa ide macintosh message net parport s390 tc w1Makefile base char fc4 ieee1394 mca misc nubuspci sbus telephony zorroacorn block cpufreq firmware input md mmc oprofile pcmcia scsi usbacpi bluetooth dio i2c isdn media mtd parisc pn p serial video其中usb目录包含了所有usb设备的驱动,而usb目录下面又有它自己的子目录,进去看一下,localhost:/usr/src/linux-2.6.10/drivers # cd usb/locahost:/usr/src/linux-2.6.10/drivers/usb # lsKconfig Makefile README atm class core gadget host image input me dia misc net serial storage usb-skeleton.c注意到每一个目录下面都有一个Kconfig文件和一个Makefile,这很重要.稍后会有介绍. 而我们的故事其实是围绕着drivers/usb/storage这个目录来展开的.实际上这里边的代码清清楚楚地展示了我们日常频繁接触的U盘是如何工作的,是如何被驱动起来的.但是这个目录里边的冬冬并不是生活在世外桃源,他们总是和外面的世界有着千丝万缕的瓜葛.可以继续进来看一下,localhost:/usr/src/linux-2.6.10/drivers/usb # cd storage/localhost:/usr/src/linux-2.6.10/drivers/usb/storage # lsKconfig debug.c freecom.c isd200.c protocol.c sddr09.c shuttle_ usbat.c unusual_devs.hMakefile debug.h freecom.h isd200.h protocol.h sddr09.h shuttle _usbat.h usb.cdatafab.c dpcm.c initializers.c jumpshot.c scsiglue.c sddr55.c transport.c usb.hdatafab.h dpcm.h initializers.h jumpshot.h scsiglue.h sddr55.h transpor t.h咋一看,着实吓了一跳,用`wc -l *`这个命令统计一下,12076行,晕死...wc [ -c | -m ] [ -l ] [ -w ] [文件]或者wc -k [ -c ] [ -l ] [ -w ] [文件]注:缺省情况下,wc 命令对File 参数指定的文件中的行数、字数和字节数进行计数。
实验七(2)设备驱动开发指导块设备种类多,使用广泛,其驱动程序的开发也比字符设备复杂。
通过本实验,大家要开发一个实际块设备(U盘)的驱动程序,将能够更深入地掌握块设备驱动程序的开发方法。
Linux下已经有一个通用的U盘驱动程序usb-storage.o,其源程序放在目录drivers\usb\storage下(相对于内核源码根目录)。
但这个驱动的实现相当复杂,本实验希望开发一个相对简单些的U盘驱动程序,不求高性能,只求结构明朗、清晰易懂,主要是让大家掌握一个实际块设备的驱动方式,从而加深理解。
事实上,本实验开发的驱动程序应该能够适用于所有基于Bulkonly传输协议的USB大容量存储设备(USB Mass Storage),比如USB移动硬盘和USB外置光驱,USB闪存盘(U 盘)只是其中的一种。
由于USB大容量存储设备具有容量大、速度快、连接灵活、即插即用、总线供电等优点,它们得到了广泛使用,掌握这类设备驱动程序的开发技术无疑具有很强的实用性。
实验内容编写一个U盘驱动程序myudisk,只要求能够驱动某个型号的U盘,能够支持U盘的常规操作,如命令hexdump、mke2fs和mount等。
同时,要求在系统内核日志中显示出U盘的容量。
若有余力,可增加多分区支持功能。
实验基础和思路在教材中P130,讲解了如何编写一个Ramdisk块设备驱动程序(sbull.c),称为radimo;在文献《Linux Device Drivers》讲解了如何编写一个USB设备驱动程序,并以Linux源代码中的usb-skeleton.c为例。
虽然前者驱动的并不是一个实际的块设备,且后者又只是针对usb字符设备,但是它们提供了一个不错的基础,通过合并我们就能基本得到一个支持usb块设备的驱动程序。
之所以说基本得到,是因为合并后只是有了块设备、USB设备的驱动支持框架,但还缺一样:对U盘(USB块设备)的实际访问操作。
USB设备驱动开发-USBGadgetDriver一、Linux USB Gadget Driver功能为了与主机端驱动设备的USB Device Driver概念进行区别,将在外围器件中运行的驱动程序称为USB Gadget Driver。
其中,Host 端驱动设备的驱动程序是master或者client driver,设备端gadget driver是slave或者function driver。
Gadget Driver和USB Host端驱动程序类似,都是使用请求队列来对I/O包进行缓冲,这些请求可以被提交和取消。
它们的结构、消息和常量的定义也和USB技术规范第九章的内容一致。
同时也是通过bind和unbind将driver与device建立关系。
二、Linux USB Gadget Driver核心数据结构1. USB_Gadget对象struct usb_gadget {/* readonly to gadget driver */const struct usb_gadget_ops *ops; //Gadget设备操作函数集struct usb_ep *ep0; //控制端点,只对setup包响应struct list_head ep_list;//将设备的所有端点连成链表,ep0不在其中enum usb_device_speed speed;//高速、全速和低速unsigned is_dualspeed:1; //是否同时支持高速和全速unsigned is_otg:1; //是否支持OTG(On-To-Go)unsigned is_a_peripheral:1;unsigned b_hnp_enable:1;unsigned a_hnp_support:1;unsigned a_alt_hnp_support:1;const char *name; //器件名称struct device dev; //内核设备模型使用};2. Gadget器件操作函数集操作UDC硬件的API,但操作端点的函数由端点操作函数集完成struct usb_gadget_ops {int (*get_frame)(struct usb_gadget *);int (*wakeup)(struct usb_gadget *);int (*set_selfpowered) (struct usb_gadget *, int is_selfpowered);int (*vbus_session) (struct usb_gadget *, int is_active);int (*vbus_draw) (struct usb_gadget *, unsigned mA);int (*pullup) (struct usb_gadget *, int is_on);int (*ioctl)(struct usb_gadget *, unsigned code, unsigned long param);};3. USB Gadget driver对象struct usb_gadget_driver {char *function; //驱动名称enum usb_device_speed speed; //USB设备速度类型int (*bind)(struct usb_gadget *); //将驱动和设备绑定,一般在驱动注册时调用void (*unbind)(struct usb_gadget *);//卸载驱动时调用,rmmod时调用int (*setup)(struct usb_gadget *, const struct usb_ctrlrequest *); //处理ep0的控制请求,在中断中调用,不能睡眠void (*disconnect)(struct usb_gadget *); //可能在中断中调用不能睡眠void (*suspend)(struct usb_gadget *); //电源管理模式相关,设备挂起void (*resume)(struct usb_gadget *);//电源管理模式相关,设备恢复/* FIXME support safe rmmod */struct device_driver driver; //内核设备管理使用};4.描述一个I/O请求struct usb_request {void *buf; //数据缓存区unsigned length; //数据长度dma_addr_t dma; //与buf关联的DMA地址,DMA传输时使用unsigned no_interrupt:1;//当为true时,表示没有完成函数,则通过中断通知传输完成,这个由DMA控制器直接控制unsigned zero:1; //当输出的最后一个数据包不够长度是是否填充0unsigned short_not_ok:1; //当接收的数据不够指定长度时,是否报错void (*complete)(struct usb_ep *ep, struct usb_request *req);//请求完成函数void *context;//被completion回调函数使用struct list_head list; //被Gadget Driver使用,插入队列int status;//返回完成结果,0表示成功unsigned actual;//实际传输的数据长度};5.端点struct usb_ep {void *driver_data; //端点私有数据const char *name; //端点名称const struct usb_ep_ops *ops; //端点操作函数集struct list_head ep_list; //Gadget设备建立所有端点的链表unsigned maxpacket:16;//这个端点使用的最大包长度};6.端点操作函数集struct usb_ep_ops {int (*enable) (struct usb_ep *ep, const struct usb_endpoint_descriptor *desc);int (*disable) (struct usb_ep *ep);struct usb_request *(*alloc_request) (struct usb_ep *ep, gfp_t gfp_flags);void (*free_request) (struct usb_ep *ep, struct usb_request *req);int (*queue) (struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags);int (*dequeue) (struct usb_ep *ep, struct usb_request *req);int (*set_halt) (struct usb_ep *ep, int value);int (*set_wedge) (struct usb_ep *ep);int (*fifo_status) (struct usb_ep *ep);void (*fifo_flush) (struct usb_ep *ep);};7.字符串结构struct usb_gadget_strings {u16 language; /* 0x0409 for en-us */struct usb_string *strings;};struct usb_string {u8 id; //索引const char *s;};8. UDC驱动程序需要实现的上层调用接口int usb_gadget_register_driver(struct usb_gadget_driver *driver);int usb_gadget_unregister_driver(struct usb_gadget_driver *driver);三、UDC驱动程序1.UDC层主要数据结构,以S3C2410为例,在driver/usb/gadget/s3c2410_udc.c和s3c2410_udc.h 文件中。
usb 驱动开发原理USB驱动开发原理USB(Universal Serial Bus,通用串行总线)是一种用于连接计算机与外部设备的通信接口标准。
USB驱动开发是为了实现计算机与USB设备之间的数据传输而进行的软件编程。
本文将介绍USB驱动开发的原理和步骤。
一、USB驱动开发的基本原理USB驱动开发的基本原理是通过驱动程序与USB设备之间的通信来实现数据的传输。
USB驱动程序负责管理和控制USB设备,将计算机的请求传递给USB设备,并将USB设备的响应传递给计算机。
USB驱动开发的基本流程如下:1. 初始化USB驱动程序:驱动程序需要初始化USB控制器和USB设备。
这包括初始化数据结构、分配内存空间、设置中断处理程序等操作。
2. 建立通信连接:驱动程序需要与USB设备建立通信连接。
这包括检测和识别USB设备、分配端点和接口、设置传输模式等操作。
3. 数据传输:驱动程序通过读取和写入USB设备的寄存器来实现数据的传输。
这包括发送和接收数据包、处理中断和错误等操作。
4. 终止通信连接:在完成数据传输后,驱动程序需要关闭通信连接。
这包括释放端点和接口、清除中断和错误等操作。
二、USB驱动开发的步骤USB驱动开发的步骤如下:1. 确定USB设备的功能和特性:USB设备可以具有多种功能和特性,例如存储设备、打印机、摄像头等。
驱动程序需要了解USB设备的功能和特性,以便正确地管理和控制USB设备。
2. 编写驱动程序:驱动程序是实现USB驱动开发的核心部分。
驱动程序需要根据USB设备的功能和特性编写相应的代码,以实现数据的传输和设备的控制。
3. 进行调试和测试:在编写驱动程序后,需要进行调试和测试来验证驱动程序的正确性和稳定性。
这包括检查驱动程序的功能、性能和兼容性等方面。
4. 发布和维护驱动程序:在通过调试和测试后,可以将驱动程序发布给用户使用。
同时,还需要对驱动程序进行维护,以修复bug和提升性能。
三、USB驱动开发的挑战和解决方案USB驱动开发面临一些挑战,例如设备的兼容性、驱动程序的稳定性、传输性能的优化等。
嵌入式Linux下USB设备驱动开发解析华清远见Copyright 2007-2008 Farsight.All rights reserved.LINUX的USB设备驱动程序开发}USB及驱动框架简介}USB主机端驱动}USB设备端驱动usb 驱动程序功能演示}步骤1: 插入MMC卡到fs2410开发板,出现设备/dev/mmcblk0}步骤2: 插入4GB Kingston优盘到fs2410开发板的usb host接口.fs2410将识别这个插入过程并出现设备/dev/uba1(或者/dev/sda1)}步骤3: 将fs2410开发板的usb device接口插入windows USB口,使得fs2410的本机nandflash/dev/mtdblock3和上述两个设备(mmc卡/4GB优盘)都能在电脑上通过优盘形式来访问(出现3个盘符).usb 驱动程序功能演示}/dev/mtdblock3=> fs2410开发板上nandflash}/dev/mmcblk0=> 接在fs2410开发板上的MMC卡}/dev/uba1=> 接在fs2410开发板上的Kingston 优盘}=> 这个演示,涉及了usb host和usb device功能(也涉及了sd卡驱动的功能).usb 驱动程序功能演示: 解释}fs2410 usb host: 插入优盘到fs2410 usb主机端,fs2410 usb 主机端检测到插入优盘设备并完成枚举和初始化过程.然后调用一个具体的设备驱动(如storage设备驱动)并产生一个设备节点/dev/sda1}fs2410 usb device: usb设备端驱动在用户的要求下将3个设备(mmcblk0/sda1/mtdblock3)作为优盘设备接入windows usb主机端.并对windows发起的枚举过程作出正确的响应,返回三个设备的相关信息,使得最终windows能正确识别出这三个设备,并出现3个优盘盘符供用户方便的访问这些存储介质.}Linux-USB 子系统}Linux-USB 子系统Linux对USB规范的支持}USB-通用串行总线是目前使用最广泛的外部总线}USB是采用单一的主从设备通信模式。