USB开发步骤之软件篇
- 格式:doc
- 大小:70.00 KB
- 文档页数:8
收稿日期:2001205211USB 软件系统的开发刘少峰,韦克平(北京航空航天大学电子工程系,北京100083)摘 要:介绍了在W indows98和W indows2000下开发US B 的W DM (W indows Driver M odule )设备驱动程序过程及US B 软件系统的组成,并提供了相应的例程。
关键词:US B ;W DM中图法分类号:TP311.1 文献标识码:A 文章编号:100123695(2002)0320102203Development of the US B S oftware SystemLI U Shao 2feng ,WEI K e 2ping(Dept.o f Electronic Engineering ,Beijing University o f Aeronautics &Astronautics ,Beijing 100083,China )Abstract :T his paper introduced the process of developing the W DM device driver for US B in W ind ows 98and W ind ows 2000and the com ponents of the US B s oftware system ,and put forward the corresponding routines.K ey w ords :US B ;W DM US B 是由Intel ,C om paq ,Digital ,I BM ,M icrosoft ,NEC ,N orthern T elecom 等七家世界著名的计算机和通信公司共同推出的新一代接口标准。
由于US B 具有传输速率高,扩展方便,可以热插拔,支持PNP 等优点,迅速得到了众多PC 厂商和半导体厂商的大力支持,外设向US B 过渡成为必然的趋势。
边干边写之——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 接口驱动程序开发1 引言随着微机技术水平的日益提高,传统的计算机接口已经不能满足当前计算机高速发展的需求,计算机业迫切需要一种新的通用型、高速总线接口,通用外设接口标准USB 就应运而生。
USB,全称是Universal Serial Bus(通用串行总线),是一种新型的、基于令牌的、高速的串行总线标准,由Compaq、Microsoft、Intel、IBM 等七家公司共同开发的, 旨在解决日益增加的PC 外设与有限的主板插槽和端口之间的矛盾而制定的一种串行通信标准[3],自1995年在Comdex 上亮相以来已广泛地为各PC 厂家支持。
现在市场上几乎所有的P C 机器都配备了US B 接口,USB 接口之所以能够得到广泛支持和快速普及,是因为它具备以下优点:正由于上述优点, 开发USB 接口的设备已成为一种发展趋势。
然而随着USB 技术的迅猛发展, 传统的USB1 . 1 接口已经不能适应用户的需求, 于是在1 9 9 9年在I nt e l 的开发者论坛大会上又提出了USB2 . 0 技术, 使得US B 不仅支持1 . 5Mb / s 的“低速”, 传输和12Mb/s 的“全速”传输,而且支持480Mb/s 的“高速”传输,比USB1.1 标准快40 倍左右,速度的提高对于用户的最大好处就是意味着用户可以使用到更高效的外部设备, 而且具有多种速度的周边设备都可以被连接到USB 2.0 的线路上,而且无需担心数据传输时发生瓶颈效应。
2 USB 驱动程序设计一个完整的USB 系统包括主机系统包括主机系统和USB 设备。
所有的传输事务都是由主机发起的。
一个主机系统又可以分为以下几个层次结构, 。
USB 总线接口包括USB 主控制器和根集线器,其中USB 主控制器负责处理主机与设备之间电气和协议层的互连,根集线器提供USB 设备连接点。
USB开发基础:USB设备的开发流程
USB设备的开发一般包括主机端(上位机)驱动程序的开发(如果您的USB设备符合某一标准设备类且主机端已经提供了此类设备的驱动程序的话,则可以省掉此步骤)和USB设备端驱动程序的开发,有时还可能包括主机端
应用程序的设计工作。
1、设备系统需求分析
设备系统需求分析是进行USB设备设计的第一步,通过对USB设备功能特性和USB主机端操作系统的分析,可以获得实现该USB设备的软硬件设计需求。
在该阶段,设计者需要充分了解该设备的应用环境(如USB主机的软件、
硬件平台),这样以用来确定是否需要提供USB主机端相关软件工作,以便该设备能得到广泛地应用。
为了提供合理的软硬件设计方案,设计者还需要充分了解市场上的USB接口芯片,不同的USB接口芯片在USB协议上有着不同程度的支持,比如,对数据包地址的硬件自动识别、CRC16和CRC5的自动生成等等。
当然,在确定具体的软硬件需求时,产品的开发费用和开发周期也是必须考虑的因素。
2、设备硬件需求
通过设备系统需求分析,以及对市场上USB接口芯片的充分了解,设计者
必须确定相应的设备硬件结构以及可能采用的硬件。
在选择器件时,需要考虑到器件体积、功耗等,因为,小的设备功耗,有利于采用总线供电模式。
必须通过设备系统的功耗来确定是否需要提供本地电源。
3、设备软件需求
在确定了设备的硬件结构以后,该设备的软件结构就会同时产生。
不同的硬。
USB开发步骤之软件篇(二)关于AssociatedIrp.SystemBuffer、MdlAddress和UserBuffer将在下面的I/O缓冲区策略里面更详细地讨论。
NT还有更多其他的对象,例如中断对象、Controller对象、定时器对象等等,但在我们开发的驱动程序中并没有用到,因此在这里不做介绍。
I/O缓冲策略很明显的,驱动程序和客户应用程序经常需要进行数据交换,但我们知道驱动程序和客户应用程序可能不在同一个地址空间,因此操作系统必须解决两者之间的数据交换。
这就就设计到设备的I/O缓冲策略。
读写请求的I/O缓冲策略前面说到通过设置Device对象的Flag可以选择控制处理读写请求的I/O缓冲策略。
下面对这些缓冲策略分别做一介绍。
1、缓冲I/O(DO_BUFFERED_IO)在读写请求的一开始,I/O管理器检查用户缓冲区的可访问性,然后分配与调用者的缓冲区一样大的非分页池,并把它的地址放在IRP的AssociatedIrp.SystemBuffer域中。
驱动程序就利用这个域来进行实际数据的传输。
对于IRP_MJ_READ读请求,I/O管理器还把IRP的UserBuffer域设置成调用者缓冲区的用户空间地址。
当请求完成时,I/O管理器利用这个地址将数据从驱动程序的系统空间拷贝回调用者的缓冲区。
对于IRP_MJ_WRITE写请求,UserBuffer被设置为NULL,并把用户缓冲区的数据拷贝到系统缓冲区中。
2、直接I/O(DO_DIRECT_IO)I/O管理器首先检查用户缓冲区的可访问性,并在物理内存中锁定它。
然后它为该缓冲区创建一个内存描述表(MDL),并把MDL的地址存放在IRP的MdlAddress域中。
AssociatedIrp.SystemBuffer和UserBuffer都被设置为NULL。
驱动程序可以调用函数MmGetSystemAddressForMdl得到用户缓冲区的系统空间地址,从而进行数据操作。
diy-usb software 用法[diyusb软件使用方法]本篇文章将详细介绍diyusb软件的使用方法,并提供一步一步的指导。
diyusb 是一款用于自制USB设备的开源软件,它提供了一种简便的方法来设计、开发和测试USB设备。
无论你是一位电子爱好者还是一位专业设计师,diyusb都能帮助你快速实现自己的USB设备创意。
在开始之前,我们首先需要了解diyusb软件的运行环境和基本要求。
diyusb 支持Windows、Linux和Mac OS X操作系统,同时还需要安装Python解释器和相应的USB驱动程序。
确保你的电脑已经满足这些要求,并且已经安装了最新版本的diyusb软件。
一、安装diyusb软件首先,我们需要获取diyusb软件的最新版本。
你可以在diyusb官方网站上下载安装包,或者直接从GitHub上获取源代码。
不论你选择哪种方式,确保你下载的是最新版本的diyusb软件。
一旦你获得了安装包或源代码,接下来就可以开始安装diyusb软件。
对于Windows用户,只需运行安装程序并按照提示完成安装即可。
如果你选择了源代码,那么你需要在命令提示符或PowerShell中运行安装脚本。
对于Linux和Mac OS X用户,你需要打开终端,并在终端中输入以下命令:./configuremakesudo make install这将自动配置、编译和安装diyusb软件。
二、创建新项目安装完成后,我们可以开始创建新项目并准备开发自己的USB设备。
打开diyusb软件,你会看到一个简洁的界面,包含菜单栏、工具栏和项目列表。
点击菜单栏中的"文件",然后选择"新建项目"。
在弹出的对话框中,输入项目名称和路径,然后点击"确定"。
现在,你已经成功创建了一个新的diyusb项目,并可以看到它在项目列表中显示出来。
三、设计USB设备接下来,我们可以开始设计自己的USB设备。
USB驱动程序开发DDKVCDS3.2安装与配置USB驱动程序开发DDK VC DS3.2安装与配置1.软件的安装顺序:VC6.0 -> DDK_XP -> DriverStudio3.2 ,如果装错了,把DS3.2删除再重装就OK了.2.编译库文件:(1).启动VC6.0,进入菜单DriverStudio>>DDK Build Settings指向DDK安装位置;(2).进入菜单Open Workspace,打开位于DS安装目录的\DriverWorks\Source\vdwlibs.dsw;(3).进入Build菜单,选择batch Build,在之后的对话框中选择你想如何编译;(4).对于32位编译,最好选择全部复选框,但没有必要选择64位的;(5).点击Rebuild AlL,过一会就生成文件;注:如果出现无法打开文件这类的错误,一般都是DDK Build Settings 指向不对,或安装顺序有误;3.使用Driver wizard生成驱动程序:(1).在VC6.0的界面下,进入Driver wizard进行设置;(2).设置好后将生成驱动文件,然后用VC6.0进行编译;(3).进行Build菜单,Rebuild AlL将生成.sys文件,说明生成驱动成功;注:如果出现无法打开ntstrsafe.lib的错误,进入菜单Project=>Settings去掉Link里的ntstrsafe.lib,就OK了.(说是什么DS3.2的BUG,郁闷)注:DDK对OS敏感,VC用英文原版,最好不要用汉化版,DS3.2是最新版,已经停止更新了.附上别人的安装方法,感觉他讲的非常好,我有一半抄他的了:出处:/5313096.htmlDriverStudio驱动程序开发工具包的安装说明(DS3.2及以下版本)以下为DS3.2以下版本的安装方式在winme下安装DS:1.安装NTDDK(98DDK不行);/////////////////////////////////////////////////////////2.安装VC6.0.在安装的最后要选上Register选项;////////////////////////////////////////////////////////3.NTDDK4.0的设置:随便用一个文本编辑器打开……\ddk\bin\目录下的setenv.bat文件,在该文件的第三行(不含空白行)之后加入如下一行并保存:call ……\vc98\bin\vcvars32.bat(……是VC所在路径)。
USB应用程序开发1 前言USB开发跟其他文件设备(如串口)开发一样,难点是找到该USB设备的路径,本文以DDK里src/usb/bulkusb例子为参考,阐述一个非HID的USB调试器软件的开发过程。
2 设备GUID一般设备会有两个GUID, 一个为Class GUID, 在INF文件中,另一个为Device GUID,在SYS文件中。
CreateFile使用的是SYS中的GUID,想得到它有两个办法:1 跟设备的提供者索要。
2在注册表里找,一般在:HKEY_LOCAL_MACHINE/SYSTEM/ControlSet001/Control/DeviceClasses/3 设备路径根据设备GUID,枚举所有USB HOST,找匹配的USB设备,然后获取其路径。
3.1 头文件 usbport.h#define WINVER 0x0500#include <windows.h>#include <setupapi.h>#include <basetyps.h>#include <usbdi.h>#include <initguid.h>#include <stdio.h>#pragma comment(lib,"setupapi.lib")#pragma comment(lib,"hid.lib")#pragma comment(lib,"comctl32.lib")#ifndef BULKUSBH_INC#define BULKUSBH_INC#define BULKUSB_IOCTL_INDEX 0x0000#defineIOCTL_BULKUSB_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN, /BULKUSB_IOCTL_INDE X,/METHOD_BUFFERED, / FILE_ANY_ACCESS)#define IOCTL_BULKUSB_RESET_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN, / BULKUSB_IOCTL_INDE X+1,/METHOD_BUFFERED, / FILE_ANY_ACCESS)#define IOCTL_BULKUSB_RESET_PIPE CTL_CODE(FILE_DEVICE_UNKNOWN, /BULKUSB_IOCTL_INDE X+2,/METHOD_BUFFERED, / FILE_ANY_ACCESS)extern HANDLE open_file(char *filename);extern int GetUsbPath(char *path);extern int WriteUsb(HANDLE hUsb,char *Outbuff, int len); extern int ReadUsb(HANDLE hUsb,BYTE inbuff[],DWORD&nBytesRead,int nToRead);3.2 源文件 usbport.cpp#include "usbport.h"//8a3bf75d-83c7-440e-8276-5ae3f3ea6e77DEFINE_GUID(GUID_CLASS_I82930_BULK,0x8a3bf75d, 0x83c7, 0x440e,0x82,0x76, 0x5a, 0xe3, 0xf3, 0xea, 0x6e, 0x77);BOOL GetUsbDeviceFileName( LPGUID pGuid, char *outNameBuf); HANDLE OpenUsbDevice( LPGUID pGuid, char *outNameBuf); HANDLE OpenOneDevice (HDEVINFO HardwareDeviceInfo,PSP_INTERFACE_DEVICE_DATA DeviceInfoData,char *devName);int GetUsbPath(char *path);int WriteUsb(HANDLE hUsb,char *Outbuff, int len);int ReadUsb(HANDLE hUsb,BYTE inbuff[], DWORD&nBytesRead,int nToRead);/*名称:open_file功能:打开USB设备参数:filename 定义为”PIPE00” pipe name for bulk input pipe on our test board ,”PIPE01” pipe name for bulk output pipe on our test board。
官方USB程序和例程一、USB的“JoyStickMouse”例程结构分析1、例程的结构(1)底层结构包括5个文件:usb_core.c(USB总线数据处理的核心文件),usb_init.c,usb_int.c(用于端点数据输入输入中断处理),usb_mem.c(用于缓冲区操作),usb_regs.c(用于寄存器操作)。
它们都包含了头文件“usb_lib.h”。
在这个头文件中,又有以下定义:#include "usb_type.h"#include "usb_regs.h"#include "usb_def.h"#include "usb_core.h"#include "usb_init.h"#include "usb_mem.h"#include "usb_int.h"usb_lib.h中又包含了七个头文件,其中usb_type.h中主要是用typedef为stm32支持的数据类型取一些新的名称。
usb_def.h中主要是定义一些相关的数据类型。
还有一个未包含在usb_lib.h中的头文件,usb_conf.h用于USB 设备的配置。
(2)上层结构上层结构总共5个文件:hw_config.c(用于USB硬件配置)、usb_pwr.c(用于USB连接、断开操作)、usb_istr.c(直接处理USB 中断)、usb_prop.c(用于上层协议处理,比如HID协议,大容量存储设备协议)、usb_desc.c(具体设备的相关描述符定义和处理)。
可见,ST的USB操作库结构十分清晰明了,我先不准备直接阅读源代码。
而是先利用MDK的软件模拟器仿真执行,先了解一下设备初始化的流程。
2、设备初始化所做的工作(1)Set_System(void)这个是main函数中首先调用的函数,它位于hw_config.c文件中。
USB开发步骤之软件篇2000年03月20日,上午08:25:01,来自的...地说:COMMUNICATION MAKES ADVANCE!USB开发步骤之软件篇我这里重点的介绍如何写驱动程序,对于一些应用程序我就不做介绍了,因为我对于那些高层的东西写得很少。
作为WIN98和WIN2K推荐的一项新技术来说,USB的驱动程序和以往的直接跟硬件打交道的WIN95的VXD的方式的驱动程序不同,,它属于WDM类型的。
USB的WDM接口框图如下(这个图可以说是USB软件总体框图)/photo/wdmusb1.gif对于HID的设备,就可以采用上图左上边的结构,其它类的话采用右上的结构,其实右边的结构可以又细分成两层,一层是CLASS DRIVER,一层是MINIPORT DRIVER。
而倒数第三行的UHCD 和OpenHCI分别是由INTEL和COMPAQ提供的一个和硬件有关的底层驱动程序,两者的关系是二选一。
对于USB的驱动程序,大家还得去了解WDM驱动程序的写法,或者早些时候的NT驱动程序,其实WDM驱动程序可以看做是NT驱动程序的一个update,只是增加了一些新的特性。
“写驱动程序是一个很漫长和繁琐的工作,在此之前,你最好要熟悉硬件,熟悉C/C++,还要用过DDK,会用一些调试程序,如SOFTICE和WINDBG之类。
如果一切就绪,你就可以开始写驱动程序,工作的进程有时侯会取决于你的运气”。
(这是一位留美的朋友对我说的,我写出来和大家共享)下面是我从一个朋友那里得到的一篇文章的摘要(对于初次理解可能会比较困难一些):--------------------------------------------------------------------------------NT驱动程序的分层结构驱动程序是指管理某个外围设备的一段程序代码。
NT采用更灵活的方法,允许杂应用程序和硬件之间存在几个驱动程序层次。
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驱动开发面临一些挑战,例如设备的兼容性、驱动程序的稳定性、传输性能的优化等。
一、概述CY7CxxxUSB是一款功能强大的USB控制器芯片,具有广泛的应用领域。
本文将介绍CY7CxxxUSB的编程例,并详细讲解其编程操作步骤和注意事项,以帮助开发者更好地理解和应用该芯片。
二、CY7CxxxUSB编程概述1. CY7CxxxUSB是一款USB控制器芯片,集成了USB2.0设备控制器、8位多功能微控制器和大量外设接口。
它具有丰富的接口和功能,可以满足各种USB设备的控制需求。
2. 该芯片支持多种开发工具,可通过C语言或汇编语言进行编程。
三、CY7CxxxUSB编程步骤1. 下载并安装CYxxx开发工具要开始CY7CxxxUSB的编程,首先需要下载和安装Cypress公司提供的CYxxx开发工具。
该开发工具可以在Cypress官全球信息站免费下载,安装完成后即可开始编程操作。
2. 创建工程和配置环境在CYxxx开发工具中,选择“新建工程”并设置相关工程参数,包括芯片型号、时钟频率等。
然后配置开发环境,包括引脚分配、中断设置等。
3. 编写程序在CYxxx开发工具中,进行源代码的编写。
开发者可以根据自己的需求编写具体的功能代码,例如USB设备的数据传输、中断处理、外设控制等。
4. 编译和下载完成程序编写后,进行代码的编译和下载。
通过CYxxx开发工具的编译和下载功能,将程序烧录到CY7CxxxUSB芯片中。
四、CY7CxxxUSB编程注意事项1. 理解芯片的规格书和技术手册,熟悉芯片的功能和特性。
2. 注意引脚分配和连接,确保芯片与外围电路的正常连接。
3. 注意时钟频率和时序要求,保证芯片工作的稳定性和可靠性。
五、结语通过本文的介绍,相信读者对CY7CxxxUSB的编程有了更深入的了解。
该芯片具有丰富的功能和广泛的应用领域,是一款非常优秀的USB控制器芯片。
希望本文的内容能帮助开发者更好地应用和开发CY7CxxxUSB,为各种USB设备的控制提供更好的解决方案。
六、CY7CxxxUSB编程实例在本节中,我们将以一个具体的示例来演示如何使用CY7CxxxUSB进行编程。
开发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开发步骤之标准篇通用串行总线(Universal Serial Bus)是用于将适用USB的外围设备连接到主机的外部总线结构,其主要是用在中速和低速的外设。
USB是通过PCI总线和PC的内部系统数据线连接,实现数据的传送。
USB同时又是一种通信协议,他支持主系统(host)和USB的外围设备(device)之间的数据传送,在USB的网络协议中,每个USB的系统有且只有一个host,因此,很多的朋友问我是否可以将两台PC的USB口通过A-A头连接起来,是否可以实现通信,这样是不行的,因为对于电脑主板上的USB设备,都是host,如果连起来就是两个host的通信,这样一来的一个USB的系统有了两个的host,与它的网络协议冲突。
Anchorchip 出了一个可以直接连接的设备(好象是AN2720SC),实际上是一个由两个背靠背的USB的device组合起来的一块芯片,要卖80多个刀乐,太贵了,呵呵!USB的优点有以下几条:USB为所有的USB外设提供了单一的、易于操作的标准的连接类型。
这样一来就简化了USB外设的设计,同时也简化了用户在判断哪个插头对应哪个插槽时的任务,实现了单一的数据通用接口。
USB排除了各个设备象鼠标、调制解调器、键盘和打印机设备对去系统资源的需求,因而减少了硬件的复杂性和对端口的占用,整个的USB的系统只有一个端口和一个中断,节省了系统资源。
USB支持热插拔(hot plug),也就是说在不关PC的情况下可以安全的插上和断开USB设备,动态的加载驱动程序。
其他普通的外围连接标准,如SCSI设备等必须在关掉主机的情况下才能增加或移走外围设备。
USB支持PNP。
当插入USB设备的时候,计算机系统检测该外设并且通过自动的加载相关的驱动程序来对该设备进行配置,并使其正常工作。
USB在设备供电方面提供了灵活性。
USB直接连接到Hub或者是连接到Host的设备可以通过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块设备)的实际访问操作。
Windows DDK + DriverStudio + VC 驱动开发环境搭建说明编者按:本文的内容主要由DriverStudio的随机文档翻译整理而来。
本文的读者最好有以下软件:DriverStudio2.5,VisualStudio6.0,以及Windows2000DDK。
本文假设你已安装了这些软件。
DriverStudio2.5可在驱动开发网()下载到测试版,Windows2000DDK 可在微软的网站免费下载,VisualStudio6.0需要购买。
作者:杨军E-mail:y9980@用DriverWorks为Windows98,WindowsMe,WindowsNT,Windows2000,和WindowsXP开发驱动程序简介DriverWorks通过提供强大并且先进的代码生成向导——DriverWizard,还有库和例子中成千上万行经过严格测试的代码,简化了设备驱动程序的开发。
WindowsNT和WDM驱动程序接口为面向对象方法的应用提供了良好的条件。
DriverWorks充分利用操作系统面向对象的优良特性,与微软的DDK相比,它为设计基于WindowsNT和WDM(驱动程序设计模型)的驱动程序提供了更加友好的方式。
使用Driverworks,设计人员能以更快的速度开发NT和WDM 驱动程序。
在大多数情况下,DriverWorks函数库的使用,可以大大减少驱动程序的代码长度。
利用这些精心设计的函数,你几乎可以完成所有的工作。
当然,DDK的C语言级的API函数也是可用的。
注意:WindowsNT设备驱动程序能运行在WindowsNT或Windows2000上;而WDM设备驱动程序能在Windows98,WindowsMe,Windows2000,和WindowsXP上运行DriverStudio把那些每个驱动程序都需要的代码都封装成类库。
库代码自动地处理例行的操作,这极大地简小了任务的复杂度。
USB开发步骤之软件篇我这里重点的介绍如何写驱动程序,对于一些应用程序我就不做介绍了,因为我对于那些高层的东西写得很少。
倘若再讲,有班门弄斧之嫌,呵呵!作为WIN98和WIN2K推荐的一项新技术来说,USB的驱动程序和以往的直接跟硬件打交道的WIN95的VXD的方式的驱动程序不同,它应该是WDM类型的。
USB的WDM接口框图如下(这个图可以说是USB软件总体框图)对于HID的设备,就可以采用上图左上边的结构,其它类的话采用右上的结构,其实右边的结构可以又细分成两层,一层是Class Driver,一层是Miniport Driver。
而倒数第三行的UHCD和OpenHCI分别是由INTEL和COMPAQ两位老大定的一个和硬件有关的底层驱动程序标准,各位可以根据所需要的选择。
对于USB的驱动程序,大家还得去了解WDM驱动程序的写法,或者早些时候的NT驱动程序,其实WDM驱动程序可以看做是NT驱动程序的一个upd ate,只是增加了一些新的特性。
“写驱动程序是一个很漫长和繁琐的工作,在此之前,你最好要熟悉硬件,熟悉C/C++,还要用过DDK,会用一些调试程序,如SOFTICE和WINDBG 之类。
如果一切就绪,你就可以开始写驱动程序,工作的进程有时侯会取决于你的运气”。
(这是一位留美的朋友对我说的,我写出来和大家共享)下面是我从一个朋友那里得到的一篇文章的摘要:NT驱动程序的分层结构驱动程序是指管理某个外围设备的一段程序代码。
NT采用更灵活的分层驱动方法,允许杂应用程序和硬件之间存在几个驱动程序层次。
分层机制允许NT更加广泛地定义驱动程序,包括文件系统、逻辑卷管理器和各种网络组件,各种物理设备驱动程序等等。
1、设备驱动程序这些是管理实际数据传输和控制特定类型的物理设备的操作的驱动程序,包括开始和完成I/O操作,处理中断和执行特定的设备要求的任何差错处理。
2、中间驱动程序NT允许在物理设备驱动程序上分层任意数目的中间驱动程序。
这些中间层次提供扩展I/O系统的功能一种方法,而不必修改底层的驱动程序。
这也是微软鼓吹的他们的系统灵活的一面!实际上我觉得这样反而牺牲了一些效率上的东西。
3、文件系统驱动程序(FSD)FSD是一类比较特殊的驱动程序,通常负责维护各种文件系统所需要的磁盘结构。
注意我们并不能使用DDK来开发FSD,而必须使用Microsoft的文件系统开发人员工具包。
一般比较少写中间过滤驱动程序,过滤驱动程序它截获和修改高层发送给类驱动程序的请求。
这样就允许利用现有类驱动程序的功能,而不必从头开始写所有程序。
NT内核模式对象在我们的实际开发过程中的对象是设备,由于端口驱动程序已经隐藏了硬件控制操作,因此我在这里不讲述跟硬件相关的部份。
如果今后的开发对象不同,需要对硬件进行操作的时候,可能会对中断、DMA等有比较详细的了解,这些内容可以参考DDK帮助。
NT使用对象技术管理所有的数据,下面分别对一般驱动程序所涉及的一些对象做一介绍。
不过在介绍这些对象之前,有必要先对驱动程序的结构做一介绍。
驱动程序结构NT驱动程序和一般的DOS/Windows C语言程序不一样,它没有main()或者WinMain()函数入口。
和DLL类似地,它向操作系统显露一个名称为Dri verEntry()的函数,在启动驱动程序的时候,操作系统将调用这个入口。
DriverEntry除了做一些必要的设备初始化工作外,还初始化一些Dispa tch例程入口。
我们知道,NT应用和设备驱动程序打交道主要是通过CreateFile、 ReadFile、WriteFile 和DeviceIoControl等Win32 API来进行的。
这些API其实都对应着驱动程序的一些Dispatch例程。
而驱动程序除了DriverEntry以外,主要就是由这些Dispatch例程组成的。
例如调用Win32 API CreateFile的时候,操作系统最终转化为对驱动程序IRP_MJ_CREATE功能代码所对应的 Dispatch例程的调用,如果驱动程序没有提供该例程, CreateFile调用就会失败。
NT中一些常用的功能代码和Win32 API的对象关系如下所示。
功能代码说明IRP_MJ_CREATE 打开设备CreateFile IRP_MJ_CLEANUP 在关闭设备时,取消挂起的I /O请求CloseHandleIRP_MJ_CLOSE 关闭设备CloseHandleIRP_MJ_READ 从设备获得数据Rea dFileIRP_MJ_WRITE 向设备发送数据WriteFileIRP_MJ_DEVICE_CONTROL 对用户模式或内核模式客户程序可用的控制操作DeviceI oControlIRP_MJ_INTERNAL_DEVICE_CONTROL 只对内核模式客户程序可用的控制操作IRP_MJ_QUERY_INFORMATION 得到文件的长度GetFileLengthIRP_MJ_SET_INFORMATION 设置文件的长度SetFileLengthIRP_MJ_FLUSH_BUFFERS 写输出缓冲区或丢弃输入缓冲区FlushFileBuffersFlushConsoleInputBufferPurgeCommIRP_MJ_SHUTDOWN 系统关闭InitialSystemShutdown和上面的驱动程序支持的功能代码相对应,一般的驱动程序看起来就象下面的样子。
DriverEntry(…) // 驱动程序入口{…DeviceObject->MajorFunction[IRP_MJ_CREATE] = XXDriverCreateClose; //XX对应的是你自己给你的驱动程序的命名DeviceObject->MajorFunction[IRP_MJ_CLOSE] = XXDriverCreateClose;DeviceObject->MajorFunction[IRP_MJ_READ] = XXDriverReadWrite;DeviceObject->MajorFunction[IRP_MJ_WRITE] = XXDriverReadWrite;…}XXDriverCreateClose(…) // 对应IRP_MJ_CREATE和IRP_MJ_CLOSE的例程{//……….}XXDrive rDeviceControl(…)// 对应IRP_MJ_DEVICE_CONTROL的例程{//……….}XXDriverReadWrite(…) // 对应IRP_MJ_READ和IRP_MJ_WRITE的例程{//……….}一个驱动程序并不需要支持所有的功能代码,比如如果一个驱动程序根本就不必要与用户模式客户程序交互,那么就不用支持IRP_MJ_CREATE和I RP_MJ_CLOSE。
又如设备不支持设备读写,就不用支持IRP_MJ_READ和IRP_MJ_WRITE。
驱动程序对象是在操作系统启动驱动程序、在调用驱动程序入口DriverEntry之前就已经创建好了的,并且作为DriverEntry 函数的参数传递给驱动程序。
如果驱动程序启动失败,操作系统将删除该对象。
该对象的数据结构如下。
注意下表并不是完整地列出了ntddk.h中的DEVICE_OBJECT结构体的所有数据项,这里仅列出了一般驱动程序可能使用到的数据项。
在上面提到过驱动程序是管理同类型的所有设备,所以上面的结构中DeviceObject指向的就不是单个的设备对象,而是一个对象链表,这个链表的维护在下面介绍Device对象时可以看到。
Device对象与Device Extension 驱动程序在调用IoCreateDevice函数成功后就创建了一个Device 对象。
下面对Device对象几个比较重要的数据做一介绍。
Device记录着设备的特徵和状态信息,对系统上的每个虚拟的、逻辑的和物理的设备都有一个Device对象。
例如对一个硬盘驱动程序,对一个物理硬盘有一个名称为Partition0的Device对象,对应整个物理磁盘,同时对硬盘的每个分区,也都有一个Device对象,它们的名称分别为Part itionX(X从1开始,每个分区对应一个数字)。
Device Extension是连接到Device对象的一个很重要的数据结构,它的数据结构是由驱动程序设计者自己来确定的,在调用IoCreateDevice的时候应该指定它的大小,Device Extension其实是由操作系统在非份页内存池中为每个Device 对象分配的一块内存。
由于驱动程序必须是完全可重入的,因此使用任何全局变量和静态变量都不是好的办法,一般来说和设备有关的任何需要保持的信息都应该放到Device Extension里去。
设备的缓冲策略也必须提一下,这里的Flag的缓冲策略主要决定设备读写(功能代码IRP_MJ_READ和IRP_MJ_WRITE)时候的缓冲策略,另外功能代码IRP_MJ_DEVICE_CONTROL时候的缓冲策略是由IOCTL控制代码本身来决定的。
两者不能混为一谈。
在下面我将专门用一节来讨论I/O的缓冲策略。
I/O请求包(IRP)在上面的结构里面已经出现了IRP了,在这里对它做一说明。
在NT中,几乎所有的I/O都是包驱动的,可以说驱动程序和操作系统其他部份都是通过I/O请求包来进行交互的。
我们来看看一个I/O请求的执行过程。
(1) 操作系统的I/O管理器从非分页内存分配一个IRP,响应一个I/O请求。
基于由客户指定的I/O函数,I/O管理器将该 IRP传递给合适的驱动程序的Dispatch例程。
(2) Dispatch例程检查请求的参数是否有效,如果有效,驱动程序根据请求的内容进行一系列的操作。
否则设置错误状态信息直接返回。
(3) 操作完成时,将数据(如果有)和状态信息存放到IRP中并返回给I/O管理器。
(4) I/O管理器对返回的IRP进行适当的处理后将最后状态和数据(如果有)返回给用户。
一个IRP的主要数据项如下表所示。
IRP包括一个IRP头和一个IRP stack 的区域。
由于WDM的模式下都是包驱动的,所里IRP可以说是一个非常重要的东东。
还有那个该死的URB(G od damn URB!)[人一辈子真的很过瘾,有些人或有些事你明明不喜欢或做不来,可是有时侯你又不得不硬着头皮去做,就像一大堆球迷围着一堆狗屎般的中国足球,那班傻儿真是要钱不要脸,丢咱中国人的脸]关于AssociatedIrp.SystemBuffer、MdlAddress和UserBuffer将在下面的I/O缓冲区策略里面更详细地讨论。