编写USB驱动程序步骤
USB驱动程序(较详细)一
USB驱动程序(较详细)一内核使用2.6.29.4拓扑结构上, 一个 USB 子系统并不是以总线的方式来分布; 它是一棵由几个点对点连接构成的树。
这些连接是连接设备和集线器的4线电缆(地, 电源, 和 2 个差分信号线), 如同以太网的双绞线。
USB主控制器负责询问每个USB设备是否有数据需要发送。
由于这个拓扑结构,一个 USB 设备在没有主控制器要求的情况下不能发送数据. 也就是说:USB是单主方式的实现,主机轮询各外设。
但是设备也可以要求一个固定的数据传输带宽,以保证可靠的音视频I/O。
USB只作为数据传输通道,对他所收发的数据格式没有特殊的内容和结构上的要求,也就是类似于透传。
Linux内核支持两种主要类型的USB驱动程序:Host系统上的驱动程序(USB device driver)和device上的驱动程序(USB gadget driver)(设备端驱动)。
USB 驱动程序存在于不同的内核子系统和USB硬件控制器之中。
USB核心为USB驱动程序提供了一个用于访问和控制USB硬件的接口,它隐藏了USB控制器的硬件细节。
从这里我们要知道:《LDD3》所谓的USB驱动是针对USB核心提供的接口而写的,并不是真正去操纵USB硬件控制器中的寄存器。
这样你必须保证你的板子上CPU的USB硬件控制器的驱动是可用的。
否则您就得先搞定CPU的USB硬件控制器的驱动才行。
以下是Linux内核中USB驱动的软件构架:如左下图所示,从主机侧的观念去看,在Linux驱动中,USB驱动处于最底层的是USB主机控制器硬件,在其之上运行的是USB主机控制器驱动,主机控制器之上为USB核心层,再上层为USB设备驱动层(插入主机上的U盘、鼠标、USB转串口等设备驱动)。
因此,在主机侧的层次结构中,要实现的USB驱动包括两类:USB主机控制器驱动和USB设备驱动,前者控制插入其中的USB设备,后者控制USB 设备如何与主机通信。
USB驱动程序开发全程
USB驱动程序开发全程编写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核心将调用此函数)代码实例:static struct usb_driver skel_driver={.owner = THIS_MODULE,.name = "skeleton",.id_table = skel_table,.probe = skel_probe,.disconnect = skel_disconnect,};↓2usb_register()注册将struct usb_driver 注册到usb核心,传统是在usb驱动程序模块初始化代码中完成该工作的static int __init usb_skel_init(void){...usb_register(&skel_driver);...}↓3struct usb_device_id usb核心用该表判断哪个设备该使用哪个驱动程序,热插拔脚本使用它来确定当一个特定的设备插入到系统时该自动装载哪个驱动程序。
Linux驱动之USB鼠标驱动编写
Linux驱动之USB⿏标驱动编写本篇博客分以下⼏部分讲解1、介绍USB四⼤描述符USB设备驱动程序⾥定义了许多与驱动程序密切相关的描述符。
这⾥介绍⼀下四种⽐较关键的描述符:设备描述符、配置描述符、接⼝描述符、端点描述符。
这⼏个描述符都位于include\linux\usb\ch9.h中,先看⼀下每个描述直接的关系,从图中可以看出每⼀个查到USB主机上的USB设备都有⼀个设备描述符,设备描述符下⾯可以接多个配置描述符,配置描述符下⾯⼜可以接多个当USB设备接到USB控制器上后,USB控制器第⼀次读取到的数据包,总共8字节/*当USB设备接到USB控制器上后,USB控制器第⼀次读取到的数据包,总共8字节*/struct usb_ctrlrequest {__u8 bRequestType;__u8 bRequest;__le16 wValue;__le16 wIndex;__le16 wLength;} __attribute__ ((packed));设备描述符是在设备连接时,主机第⼀个读取的描述符,包含了主机需要从设备读取的基本信息。
设备描述符有14个字段,如下所⽰。
依照功能来分,设备描述符的字段包含了描述符本⾝、设备、配置以及类别4⼤类。
/* USB_DT_DEVICE: Device descriptor */struct usb_device_descriptor {__u8 bLength; //描述符长度__u8 bDescriptorType; //描述符类型__le16 bcdUSB; //USB规范版本号码,BCD码表⽰__u8 bDeviceClass; //USB设备类别__u8 bDeviceSubClass; //USB设备⼦类别__u8 bDeviceProtocol; //USB设备协议码__u8 bMaxPacketSize0; //端点0的最⼤信息包⼤⼩(端点0⽤于控制传输,既能输出也能输⼊)__le16 idVendor; //⼚商ID__le16 idProduct; //产品ID__le16 bcdDevice; //设备版本编号,BCD码表⽰__u8 iManufacturer; //制造者的字符串描述符的索引值__u8 iProduct; //产品的字符串描述符的索引值__u8 iSerialNumber; //序号的字符串描述符的索引值__u8 bNumConfigurations;//可能配置的数⽬} __attribute__ ((packed));在读取设备描述符后,主机可以读取该设备的配置、接⼝以及端点描述符。
USB驱动程序编写
USB驱动程序编写linux下usb驱动编写(内核2.4)——2.6与此接口有区别2006-09-15 14:57我们知道了在Linux下如何去使用一些最常见的USB设备。
但对于做系统设计的程序员来说,这是远远不够的,我们还需要具有驱动程序的阅读、修改和开发能力。
在此下篇中,就是要通过简单的USB驱动的例子,随您一起进入USB驱动开发的世界。
USB骨架程序(usb-skel eton),是USB驱动程序的基础,通过对它源码的学习和理解,可以使我们迅速地了解USB驱动架构,迅速地开发我们自己的USB硬件的驱动。
USB驱动开发在掌握了USB设备的配置后,对于程序员,我们就可以尝试进行一些简单的USB驱动的修改和开发了。
这一段落,我们会讲解一个最基础U SB框架的基础上,做两个小的US B驱动的例子。
USB骨架在Linux kernel源码目录中driver/usb/u sb-skeleton.c为我们提供了一个最基础的USB驱动程序。
我们称为USB骨架。
通过它我们仅需要修改极少的部分,就可以完成一个USB设备的驱动。
我们的US B驱动开发也是从她开始的。
那些linux下不支持的USB设备几乎都是生产厂商特定的产品。
如果生产厂商在他们的产品中使用自己定义的协议,他们就需要为此设备创建特定的驱动程序。
当然我们知道,有些生产厂商公开他们的USB协议,并帮助Linux驱动程序的开发,然而有些生产厂商却根本不公开他们的USB协议。
因为每一个不同的协议都会产生一个新的驱动程序,所以就有了这个通用的USB驱动骨架程序,它是以pci 骨架为模板的。
如果你准备写一个lin ux驱动程序,首先要熟悉USB协议规范。
USB主页上有它的帮助。
一些比较典型的驱动可以在上面发现,同时还介绍了USB urbs的概念,而这个是usb驱动程序中最基本的。
USB驱动程序的编写采用WDM驱动程序
U S B驱动程序的编写采用W D M驱动程序Document serial number【UU89WT-UU98YT-UU8CB-UUUT-UUT108】USB驱动程序的编写采用WDM 驱动程序。
WDM 驱动程序是一些例程的集合,它们被动地存在,等待主机系统软件(PnP 管理器、I/O 管理器、电源管理器等)来调用或激活它们。
具体驱动程序不同,其所包含的例程也不同。
一个WDM 驱动程序的基本组成包括以下5个例程:(1)驱动程序入口例程:处理驱动程序的初始化。
(2)即插即用例程:处理PnP 设备的添加、删除和停止。
(3)分发例程:处理用户应用程序发出的各种 I/O 请求。
(4)电源管理例程:处理电源管理请求。
(5)卸载例程:处理驱动程序的卸载。
包含文件:, ,, , , makefile,sources)在文件中,包含了上述五个例程:中定义了各种数据结构还有各种IOCTL控制码,用于不同数据的读写。
中实现了各种驱动例程。
包含了上述五个所说例程外还包含了其他例程,课程从下面的驱动程序入口例程得出一些信息。
驱动程序入口例程:NTSTATUSDriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath){NTSTATUS ntStatus = STATUS_SUCCESS;PDEVICE_OBJECT deviceObject = NULL;DriverObject->MajorFunction[IRP_MJ_CREATE] = Ezusb_Create; DriverObject->MajorFunction[IRP_MJ_CLOSE] = Ezusb_Close; ources. If you want to add a new source # file to thiscomponent. This file merely indirects to the real make file # that is shared by all thedriver components of the Windows NT DDK # !INCLUDE $(NTMAKEENV) 不要编辑这个文件。
USB设备的驱动程序实现
USB设备的驱动程序实现
USB驱动是用来控制使用USB接口的设备的软件程序,其实现是将实
际的硬件设备抽象为虚拟的设备,使其能够在计算机操作系统上应用。
一
般来讲,当你将USB设备插入你的计算机时,它将通过计算机的USB主控
芯片找到USB设备,然后测试它的功能,并决定它是否能够被用来通信,
最后安装相应的驱动程序。
实际的USB驱动程序的实现有若干方法,其中
有两种常用的技术:应用程序编程接口(API)和驱动程序模板。
1、应用程序编程接口(API)
API是一组用于访问操作系统提供的服务和功能的特殊指令序列。
应
用程序编程接口(API)可以用来创建USB驱动程序,其实现包括以下步骤:
(1)定义硬件设备的描述
在编写USB驱动程序时,首先需要定义硬件设备,即定义设备的功能,记录其编号、最大支持通信速率、硬件连接方式、发送和接收设备数据的
方式以及支持的驱动软件要求等信息。
(2)实现设备驱动的关键函数
关键函数是控制USB设备正常工作所必需的函数,包括初始化函数、
发送和接收数据的函数、获取设备状态的函数以及关闭设备的函数等。
USB驱动程序编写
分类∙首页标签∙about love(8)∙recollect(6)∙Study DAY(17)∙FPGA(16)∙USB(3)∙VOIP(1)∙Linux(17)∙ C Language(25)日历<<< 2006 - 5 >>>日一二三四五六123456 78910111213 14151617181920 21222324252627 28293031登陆用户名:密码:记住密码登录用户注册忘记密码最新文章∙鬼故事下载∙鬼故事下载∙OS 推荐∙ARM的开发步骤∙s3c44b0x + uclinux∙74系列芯片资料∙集成电路应用索引∙密码学里的随机数发生器∙研究密码学的网站集锦∙10分钟完成一个USB驱动程序回复∙::签写留言::∙WISHBONE System-on站点统计∙日志总数:96∙评论数量:7∙留言数量:1∙访问次数:6461∙加为好友发送短信友情链接sunny sky with wind and rainWork Place10分钟完成一个USB驱动程序2006-5-16 9:45:0010分钟完成一个USB驱动程序很多写Windows Device Driver的开发人员基本上都是使用Windows DDK进行开发的。
但是,现在也有不少人都开始借助一些辅助工具。
笔者去年开始接触到riverStudio,发现它真的是一个不错的开发工具,不仅写代码的时候思路清晰,而且和DDK的结合很好。
当然,也有很多人觉得用DriverStudio不够正宗,或者说不能很好的理解Windows Device Driver的架构。
我感觉这就有点像MFC和SDK的关系,关于这个问题在很多地方都有争论,比如在万千新闻组上,就讨论了将近2个月。
每个人都有自己的最爱,都有自己的习惯,只要你能把事情做好,我想用什么方法应该都是一样的。
如果你已经习惯了用DDK开发,那完全还可以继续用下去;如果你觉得DriverStudio不错,那尝试用一个可以给你按照OOP概念来编程的工具有什么不好呢?在驱动开发网上,经常看到有人询问一些关于DriverStudio的使用的问题。
05-USB驱动程序开发
2、USB设备类型 USB设备类型
八、USB设备列举 USB设备列举
在USB规范中有一个非常重要的“动作” USB规范中有一个非常重要的 动作” 规范中有一个非常重要的“ 过程” 这个动作将会让PC PC机知道何 或“过程”。这个动作将会让PC机知道何 USB设备刚接上以及其所含的各种信息 设备刚接上以及其所含的各种信息。 种USB设备刚接上以及其所含的各种信息。 这样,PC机就可以与这个USB设备开始进行 机就可以与这个USB 这样,PC机就可以与这个USB设备开始进行 数据传输的工作了。 数据传输的工作了。这个动作称之为设备 列举(enumeration) (enumeration)。 列举(enumeration)。
7 . USB2.0 的 High-speed 模式支持音频和视频设备 , 可 USB2 High-speed模式支持音频和视频设备 模式支持音频和视频设备, 以保证其固定带宽; 以保证其固定带宽; 8 . 为了适应各种不同类型外围设备的要求 USB 提供了 为了适应各种不同类型外围设备的要求USB 四种不同的数据传输类型:控制传输,Bulk数据传输 数据传输, 四种不同的数据传输类型:控制传输, Bulk数据传输, 中断数据传输,同步数据传输。 中断数据传输, 同步数据传输。 同步数据传输可为音 频和视频等实时设备的实时数据传输提供固定带宽。 频和视频等实时设备的实时数据传输提供固定带宽。 的端口具有很灵活的扩展性。 一个USB 9 . USB 的端口具有很灵活的扩展性 。 一个 USB 端口串 接上一个USB 就可以扩展为多个USB 端口。 USB端口 接上一个 USB Hub 就可以扩展为多个 USB 端口 。 规范 中说,USB可以扩展到127个外设端口 可以扩展到127个外设端口。 中说,USB可以扩展到127个外设端口。
(简易USB驱动)开发指导
实验七(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块设备)的实际访问操作。
如何编写Linux下的USB键盘驱动
{
int result = usb_register(&usb_kbd_driver);/*注册USB键盘驱动*/
if (result == 0) /*注册失败*/
info(DRIVER_VERSION ":" DRIVER_DESC);
return result;
}
7. 编写模块卸载函数(每个驱动都会有一个卸载函数,由 module_exit 调用):
/*若同时只按下1个按键则在第[2]个字节,若同时有两个按键则第二个在第[3]字节,类推最多 可有6个按键同时按下*/ for (i = 2; i < 8; i++) { /*获取键盘离开的中断*/
if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) {/* 同时没有该KEY的按下状态*/
if (usb_kbd_keycode[kbd->old[i]]) {
input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0); } else
info("Unknown key (scancode %#x) released.", kbd->old[i]); }
接口类;鼠标为3,1,2*/
{}
/* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, usb_kbd_id_table);/*指定设备 ID 表*/
4. 定义 USB 键盘结构体:
USB驱动程序编写和安装导入
USB驱动程序编写和安装导入10分钟完成一个USB驱动程序很多写Windows Device Driver的开发人员基本上都是使用Windows DDK进行开发的。
但是,现在也有不少人都开始借助一些辅助工具。
笔者去年开始接触到riverStudio,发现它真的是一个不错的开发工具,不仅写代码的时候思路清晰,而且和DDK的结合很好。
当然,也有很多人觉得用DriverStudio不够正宗,或者说不能很好的理解Windows Device Driver的架构。
我感觉这就有点像MFC 和SDK的关系,关于这个问题在很多地方都有争论,比如在万千新闻组上,就讨论了将近2个月。
每个人都有自己的最爱,都有自己的习惯,只要你能把事情做好,我想用什么方法应该都是一样的。
如果你已经习惯了用DDK开发,那完全还可以继续用下去;如果你觉得DriverStudio不错,那尝试用一个可以给你按照OOP概念来编程的工具有什么不好呢?在驱动开发网上,经常看到有人询问一些关于DriverStudio的使用的问题。
我正好很有幸用它作了几个驱动程序,包括VXD, KMD和WDM,稍微有点心得,因此想写下来给大家作一个小小的参考。
如果其中有错误,欢迎大家给我指出,谢谢。
下面我就介绍一下用DriverStudio开发一个USB驱动程序的过程。
这个USB设备有3个双向端点,每个端点的配置如下:EP 类型地址buffer(Bytes)0 IN/OUT Control 0x80/0x00 16/161 IN/OUT Bulk 0x81/0x01 16/162 IN/OUT Bulk 0x82/0x02 64/64我们的驱动程序需要实现的功能就是控制设备上的LED灯的亮和灭,以及通过Endpoint 2对设备进行读写。
由于DriveStudio由几个部分组成,我们写这个驱动程序只要用到DriverWorks,因此下面我们就简称它为DW。
在这里,我们假定读者已经正确的安装了DW,并且已经编译好了各个库文件。
USB从设备驱动实现流程
USB从设备驱动实现流程1.硬件初始化:首先需要对USB从设备的硬件进行初始化。
这包括配置USB接口和相关寄存器,分配内存用于数据传输等。
2. 设备描述符定义:USB设备需要提供设备描述符,以描述其功能、厂商信息等。
设备描述符是一个结构体,包含各种属性,如设备的VID (Vendor Id)、PID(Product Id)、设备类别等。
3.端点描述符定义:端点描述符用于描述设备的输入输出端点。
从设备可以有多个端点,包括控制端点、批量端点、中断端点和等时端点。
每个端点都有一个端点地址、传输方向、传输类型、包大小等属性。
B设备注册和初始化:驱动程序需要注册USB设备,并进行初始化。
这包括获取USB总线的指针,通过指针与USB总线进行通信,并与USB总线驱动进行通信。
5.数据传输:驱动程序需要实现数据的传输功能,包括收发数据。
从设备收到主机的请求后,驱动程序需要根据请求进行相应的操作,如读取设备信息、发送数据等。
6.中断处理:从设备在一些情况下可能会触发中断,如数据接收完成、传输超时等。
驱动程序需要实现中断处理函数来处理这些中断事件,以确保设备的正常工作。
7.错误处理:在驱动程序的实现过程中,可能会遇到一些错误,如传输超时、报文解析错误等。
驱动程序需要通过错误处理函数来对这些错误进行处理,如重试传输、重新配置设备等。
8.资源释放:当USB设备不再使用时,驱动程序需要释放相应的资源,如内存、中断处理函数等。
9.调试和测试:在驱动程序的实现过程中,可以使用调试工具对代码进行调试和测试,以确保程序的正确性和可靠性。
总结来说,USB从设备驱动的实现流程包括硬件初始化、设备和端点描述符定义、设备注册和初始化、数据传输、中断处理、错误处理、资源释放以及调试和测试等步骤。
通过这些步骤,可以使USB从设备与主机进行正常的通信和数据传输。
usb 驱动开发原理
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驱动开发面临一些挑战,例如设备的兼容性、驱动程序的稳定性、传输性能的优化等。
28.5.1USB驱动程序_USB应用开发宝典_[共2页]
28.5.1USB驱动程序_USB应用开发宝典_[共2页]║688 应用开发宝典db StringDscr2End-StringDscr2 ;字符串描述符长度db DSCR_STRINGdb 'T',00db 'H',00db 'I',00db 'N',00db 'K',00db '!',00StringDscr2End:UserDscr:dw 0000Hend ;结束以上5部分便构成了一个完整的USB设备配置描述。
28.5 LabVIEW程序设计前面大部分实例都是采用Visual C++ 6.0来设计USB设备的上位机程序,这里讲解如何采用LabVIEW来设计上位机程序。
上位机程序主要完成USB控制传输的读和写、USB块传输的读和写以及USB描述符等的读取。
28.5.1 USB驱动程序为了能够在LabVIEW中识别该USB设备,需要使用NI-VISA的Driver Wizard工具创建USB设备的驱动程序。
这里需要注意驱动程序的安装顺序,可以参照如下的步骤来实现。
(1)按照前面章节所介绍的方法,修改CyLoad.inf文件,主要是将VID修改为VID为0x1234,PID修改为0x2211。
(2)连接该USB设备至计算机的USB 2.0高速端口,此时提示需要安装驱动程序。
(3)按照提示安装CyLoad驱动程序。
安装完毕后,系统提示需要再次安装驱动程序。
此时,需要采用NI-VISA来创建驱动程序。
(4)打开Driver Wizard软件,弹出选择硬件总线对话框,如图28.12所示。
这里选择USB 即可。
(5)单击“Next”按钮,弹出USB设备信息对话框。
在其中输入该USB设备重列举之后的VID为“0x1234”,PID为“0x1111”,制造商名称为“Cypress”,模块名称为“EZ-USB”,如图28.13所示。
开发usb驱动程序的方法连载一
开发usb驱动程序的方法(连载一)开始驱动程序设计下面的文字是从Microsoft的DDK帮助中节选出来的,它让我们明白在开始设计驱动程序应该注意些什么问题,这些都是具有普遍意义的开发准则。
应该支持哪些I/O请求在开始写任何代码之前,应该首先确定我们的驱动程序应该处理哪些IRP例程。
如果你在设计一个设备驱动程序,你应该支持和其他相同类型设备的NT驱动程序相同的IRP_MJ_XXX 和IOCTL请求代码。
如果你是在设计一个中间层NT驱动程序,应该首先确认你下层驱动程序所管理的设备,因为一个高层的驱动程序必须具有低层驱动程序绝大多数IRP_MJ_XXX例程入口。
高层驱动程序在接到I/O 请求时,在确定自身IRP当前堆栈单元参数有效的前提下,设置好IRP中下一个低层驱动程序的堆栈单元,然后再调用IoCallDriver 将请求传递给下层驱动程序处理。
一旦决定好了你的驱动程序应该处理哪些IRP_MJ_XXX,就可以开始确定驱动程序应该有多少个Dispatch例程。
当然也可以考虑把某些 RP_MJ_XXX处理的例程合并为同一例程处理。
例如在ChangerDisk 和 VDisk里,对IRP_MJ_CREATE和IRP_MJ_CLOSE处理的例程就是同一函数。
对IRP_MJ_READ和IRP_MJ_WRITE处理的例程也是同一个函数。
应该有多少个Device对象?一个驱动程序必须为它所管理的每个可能成为I/O请求的目标的物理和逻辑设备创建一个命名Device对象。
一些低层的驱动程序还可能要创建一些不确定数目的Device对象。
例如一个硬盘驱动程序必须为每一个物理硬盘创建一个Device对象,同时还必须为每个物理磁盘上的每个逻辑分区创建一个Device对象。
一个高层驱动驱动程序必须为它所代表的虚拟设备创建一个Device 对象,这样更高层的驱动程序才能连接它们的Device对象到这个驱动程序的Device对象。
一文入门usb设备的驱动编写方法
一文入门usb设备的驱动编写方法USB设备驱动编写入门USB(通用串行总线)是一种广泛使用的协议,用于在计算机和外围设备之间建立通信渠道。
编写USB设备驱动程序需要对USB规范以及操作系统提供的底层机制有深入的理解。
1. 理解USB规范USB规范定义了设备之间的通信协议、设备类型和描述符格式等方面。
理解规范对于编写符合标准且能够与其他USB设备交互的驱动程序至关重要。
2. 选择操作系统平台不同操作系统对USB设备驱动程序的要求有所不同。
为Windows环境编写驱动程序与为Linux或macOS编写驱动程序具有不同的方法。
了解目标操作系统的特定要求至关重要。
3. 设置开发环境设置开发环境包括安装必要的工具和库。
这可能需要安装USB 开发工具包或编译器。
阅读操作系统的文档以设置正确的环境。
4. 创建USB描述符USB描述符是描述设备功能和配置的数据结构。
驱动程序需要创建这些描述符才能注册设备并向操作系统公开其功能。
5. 实现USB端点USB端点是设备与计算机之间的数据传输通道。
驱动程序需要实现端点处理程序来处理数据传输和控制请求。
6. 处理USB事件驱动程序需要处理各种USB事件,例如设备插入、拔出和配置更改。
实现事件处理程序来响应这些事件并更新设备状态。
7. 使用USB堆栈操作系统提供USB堆栈,为驱动程序提供与底层USB硬件接口的抽象层。
了解USB堆栈的API和功能对于与硬件交互至关重要。
8. 调试驱动程序调试USB设备驱动程序需要专门的工具和技术。
使用调试器、日志记录和分析工具来识别并解决问题。
9. 测试驱动程序在不同环境和条件下全面测试驱动程序至关重要。
执行功能测试、兼容性测试和压力测试以验证驱动程序的可靠性和稳定性。
10. 提交并分发驱动程序开发完成后,需要向操作系统供应商提交驱动程序以进行认证和分发。
遵守供应商的准则并提供必要的文档。
开发usb驱动程序的方法
开发驱动程序的方法(连载一)开始驱动程序设计下面的文字是从的帮助中节选出来的,它让我们明白在开始设计驱动程序应该注意些什么问题,这些都是具有普遍意义的开发准则。
应该支持哪些请求在开始写任何代码之前,应该首先确定我们的驱动程序应该处理哪些例程。
如果你在设计一个设备驱动程序,你应该支持和其他相同类型设备的驱动程序相同的和请求代码。
如果你是在设计一个中间层驱动程序,应该首先确认你下层驱动程序所管理的设备,因为一个高层的驱动程序必须具有低层驱动程序绝大多数例程入口。
高层驱动程序在接到请求时,在确定自身当前堆栈单元参数有效的前提下,设置好中下一个低层驱动程序的堆栈单元,然后再调用将请求传递给下层驱动程序处理。
一旦决定好了你的驱动程序应该处理哪些,就可以开始确定驱动程序应该有多少个例程。
当然也可以考虑把某些处理的例程合并为同一例程处理。
例如在和里,对和处理的例程就是同一函数。
对和处理的例程也是同一个函数。
应该有多少个对象?一个驱动程序必须为它所管理的每个可能成为请求的目标的物理和逻辑设备创建一个命名对象。
一些低层的驱动程序还可能要创建一些不确定数目的对象。
例如一个硬盘驱动程序必须为每一个物理硬盘创建一个对象,同时还必须为每个物理磁盘上的每个逻辑分区创建一个对象。
一个高层驱动驱动程序必须为它所代表的虚拟设备创建一个对象,这样更高层的驱动程序才能连接它们的对象到这个驱动程序的对象。
另外,一个高层驱动程序通常为它低层驱动程序所创建的对象创建一系列的虚拟或逻辑对象。
尽管你可以分阶段来设计你的驱动程序,因此一个处在开发阶段的驱动程序不必一开始就创建出所有它将要处理的所有对象。
但从一开始就确定好你最终要创建的所有对象将有助于设计者所要解决的任何同步问题。
另外,确定所要创建的对象还有助于你定义对象的的内容和数据结构。
开始驱动程序开发驱动程序的开发是一个从粗到细逐步求精的过程。
的\ 目录下有一个庞大的样板代码,几乎覆盖了所有类型的设备驱动程序、高层驱动程序和过滤器驱动程序。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编写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核心将调用此函数)代码实例:
static struct usb_driver skel_driver={
.owner = THIS_MODULE,
.name = "skeleton",
.id_table = skel_table,
.probe = skel_probe,
.disconnect = skel_disconnect,
};
↓
2usb_register()注册将struct usb_driver 注册到usb核心,传统是在usb驱动程序模块初始化代码中完成该工作的
static int __init usb_skel_init(void)
{
...
usb_register(&skel_driver);
...
}
↓
3struct usb_device_id usb核心用该表判断哪个设备该使用哪个驱动程序,热插拔脚本使用它来确定当一个特定的设备插入到系统时该自动装载哪个驱动程序。
->__u16 match_flags(确定设备和结构体中下列字段中哪一个相匹配)
->__u16 idVendor(设备的usb制造商id)
->__u16 idProduct(设备的usb产品id)
↓
4USB骨架程序的关键几点如下:
1. USB驱动的注册和注销
Usb驱动程序在注册时会发送一个命令给usb_register,通常在驱动程序的初始化函数里。
当要从系统卸载驱动程序时,需要注销usb子系统。
即需要usb_unregister 函数处理。
2 当usb设备插入时,为了使linux-hotplug(Linux中PCI、USB等设备热插拔支持)系统自动装载驱动程序,你需要创建一个MODULE_DEVICE_TABLE。
代码如下(这个模块仅支持某一特定设备): static struct usb_device_id skel_table [] = {
{ USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
{ } /* Terminating entry */};
MODULE_DEVICE_TABLE (usb, skel_table);
USB_DEVICE宏利用厂商ID和产品ID为我们提供了一个设备的唯一标识。
当系统插入一个ID匹配的USB设备到USB总线时,驱动会在USB core中注册。
驱动程序中probe 函数也就会被调用。
usb_device 结构指针、接口号和接口ID都会被传递到函数中。
3 static void * skel_probe(struct usb_device *dev,unsigned int ifnum, const struct
usb_device_id *id)
驱动程序需要确认插入的设备是否可以被接受,如果不接受,或者在初始化的过程中发生任何错误,probe函数返回一个NULL值。
否则返回一个含有设备驱动程序状态的指针。
通过这个指针,就可以访问所有结构中的回调函数。
4 在骨架驱动程序里,最后一点是我们要注册devfs。
我们创建一个缓冲用来保存那些被发送给usb 设备的数据和那些从设备上接受的数据,同时USB urb 被初始化,并且我们在devfs子系统中注册设备,允许devfs用户访问我们的设备。
注册过程如下:
/* initialize the devfs node for this device and register it */sprintf(name, "skel%d", skel->;minor);
skel->devfs = devfs_register (usb_devfs_handle, name,DEVFS_FL_DEFAULT,
USB_MAJOR,USB_SKEL_MINOR_BASE + skel->minor,
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其他
1 struct usb_host_endpoint(描述usb端点)
→(包含) struct usb_endpoint_descriptor(含真正端点信息,数据格式,是真正驱动关心的字段)
端点描述符:
bEndpointAddress = 81(in)(第8位为1是输入设备)(usb的端点地址,包含端点方向)
bmAttibutes = 03(interrupt)(端点类型,为中断传输)
wMaxPacketSize = 0008(每次传8个字节)(端点每次可处理最大字节长度)
bInterval = 08(8ms)(如端点为中断,该值为轮询间隔)
2 usb端点捆绑为接口,usb接口只处理一种usb逻辑连接,如鼠标键盘等.
一个usb设备可有多接口,usb扬声器:一个usb键盘用于按键,一个usb音频流,则需两个不同的驱动程序。
usb驱动通常将struct usb_interface 转成 struct usb_device 用函数 interface_to_usbdev 转
3 struct usb_interface 描述usb接口
→struct usb_host_interface * altsetting(接口结构体数组,包含所有可能用于该接口的可选设置)
→struct usb_host_endpoint
→unsigned num_a ltsetting(可选设置的数量)
→struct usb_host_interface * cur_altsetting(接口当前活动设置)
→int minor(usb核心分配给接口的次设备号,成功调用usb_register_dev有效)
4 usb设备非常复杂,由许多不同逻辑单元组成,简单关系如下:
设备通常有一个以上的配置
配置经常有一个以上接口
接口通常有一个以上设置
接口通常有一个以上端点
设备描述-》配置描述-》接口描述-》端点描述
5 usb sysfs设备命名方案
根集线器-集线器端口号:配置。
接口
对于usb hub树中层次更高的字树命名方案
根集线器-集线器端口号-集线器端口号:配置。
接口
6 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。