第11章Windows环境下输入输出程序设计课件_第1页
第11章Windows环境下输入输出程序设计课件_第2页
第11章Windows环境下输入输出程序设计课件_第3页
第11章Windows环境下输入输出程序设计课件_第4页
第11章Windows环境下输入输出程序设计课件_第5页
已阅读5页,还剩101页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第11章Windows环境下输入输出程序设计2022/12/17第11章Windows环境下输入输出程序设计第11章Windows环境下输入输出程序设计2022/12/1Windows是一个多任务操作系统,在保护模式下工作。Windows操作系统不支持用户程序对计算机底层硬件进行直接控制。用户程序需要输入/输出时,可以通过通过API(ApplicationProgramInterface,应用程序接口)来调用设备驱动程序,对设备实现间接控制,进行输入/输出。Windows9x使用VxDs(VirtualDeviceDriver’s,虚拟设备驱动)设备驱动程序。Windows2000/XP使用WDM(WindowsDriverModel,Windows驱动程序模型)设备驱动程序。第11章Windows环境下输入输出程序设计Windows是一个多任务操作系统,在保护模式下工作。第11211.1Windows设备驱动程序

11.1.1虚拟设备 在多任务运行环境下,计算机内的硬件、软件资源为多个任务共享。任何一个用户程序都不能独占系统的硬件、软件资源。虚拟设备实质上是真实物理设备的部分资源和相关软件的组合,用来完成用户程序需要的功能。虚拟设备不但可以代表实际存在的硬件设备,还可以模拟实际上不存在的“设备”,供用户使用。计算机上的“虚拟光驱”就是一个典型的虚拟设备。与这个设备同名的物理设备是不存在的,用户使用的是硬盘的部分存储空间以及相应的服务程序。第11章Windows环境下输入输出程序设计11.1Windows设备驱动程序11.1.13使用虚拟设备好处:实现多任务对系统资源的共享,方便用户的使用;实现任务与任务、任务与系统之间的隔离和保护;规范外部设备输入、输出方法,使不同工作方式的设备用相同的方式进行输入输出。对Windows应用程序来讲,虚拟设备就是真实设备,应用程序分不清那个设备是由真实硬件支持的真实设备,那个设备是由虚拟设备驱动程序模拟的虚拟设备。第11章Windows环境下输入输出程序设计使用虚拟设备好处:第11章Windows环境下输入输出程序设411.1.2

Windows9X设备驱动程序Windows9x是一个分层结构的操作系统,由工作在两个不同层面的组件构成:顶层组件,工作在Ring3层;底层组件,工作在Ring0层。第11章Windows环境下输入输出程序设计11.1.2Windows9X设备驱动程序5顶层:Windows9x操作系统的顶层组件工作在特权级3,称为ring3层。它给应用程序的运行提供Win32API服务。Windows9x应用程序和Win32API服务一起构成操作系统的顶层,称为系统虚拟机(VM,VirtualMachine)。对于一个任务来说,这些服务程序以及他们所掌控的硬件资源就是一台“实实在在”的计算机。但是,对于整个系统来说,他们只是由操作系统向用户提供的一个运行用户程序的平台,包括为这个应用程序服务的操作系统组件和部分的硬件资源。每一个DOS应用程序都在一个独立的虚拟机中运行,操作系统允许多个虚拟机同时处于运行状态。第11章Windows环境下输入输出程序设计顶层:第11章Windows环境下输入输出程序设计6底层:Windows9x操作系统的底层组件工作在0特权级,称为ring0层,它就是虚拟机管理器(VMM,VirtualMachineManager)。Windows9x虚拟机管理器由一个内核服务集和许多虚拟设备驱动程序(VxDs,VirtualDeviceDriver’s)组成。许多VxDs是由Microsoft公司随操作系统提供的,如键盘和显示器等的VxDs,有的VxD则由设备制造商提供,或者由用户自行编写。VxD用来支持特定的硬件或软件,完成需要的功能。VxDs中的程序运行在ring0层,可以执行所有的指令,完成所需的任何软硬件的操作。第11章Windows环境下输入输出程序设计底层:第11章Windows环境下输入输出程序设计7 对于应用程序而言,虚拟机管理器是透明的,应用程序感觉不到管理器的存在。 微软已经宣布,从2006年6月起不再提供对Windows9x的技术支持。因此,Windows9x和VxDs的使用将逐渐减少。随着Windows2000/XP的广泛使用,WDM驱动程序的开发和使用已成为主流。第11章Windows环境下输入输出程序设计 对于应用程序而言,虚拟机管理器是透明的,应用程序感觉不到811.1.3

Windows2000/XP设备驱动程序Windows2000操作系统组件的层次结构 Windows2000操作系统的功能模块划分为用户模式和内核模式两大类。用户模式的操作系统功能模块工作在ring3层,他们不能使用CPU中的特权指令,连同IN、OUT这样的非特权指令也被禁止。所有的用户程序都在这一层上运行。内核模式的操作系统模块工作在ring0层,可以使用CPU的任何指令。第11章Windows环境下输入输出程序设计11.1.3Windows2000/XP设备驱动程序Wi9Windows2000操作系统的层次结构第11章Windows环境下输入输出程序设计Windows2000操作系统的层次结构第11章Windo102.Windows2000的设备驱动程序Windows2000的驱动程序也有两种不同的类型。

用户模式驱动程序工作在用户模式,通过调用内核模式驱动程序实现指定的功能。用户模式驱动程序不能直接对硬件设备进行访问,仅仅用于构建一个硬件或软件的运行环境。

Windows内核驱动程序工作在内核模式,可以直接访问硬件设备。每个设备驱动程序都有一组完成各种功能的函数,通过调用这些函数可以对某一设备完成特定的操作。第11章Windows环境下输入输出程序设计2.Windows2000的设备驱动程序第11章Wi11内核模式驱动程序的类型文件系统驱动程序可以在本地硬盘、网络、移动存储设备或各种有存储能力的硬件设备实现标准的文件系统,如FAT32、NTFS系统等。PnP驱动程序是一种遵循Windows2000即插即用协议的内核模式驱动程序。WDM驱动程序是一种PnP驱动程序。它同时还遵守电源管理协议。显示驱动程序是一种特殊的内核驱动程序。此类的驱动程序还有打印驱动程序、多媒体驱动程序、网络驱动程序等。遗留设备驱动程序主要用在WindowsNT系统中,它也可以运行在Windows2000系统中。第11章Windows环境下输入输出程序设计内核模式驱动程序的类型第11章Windows环境下输入输出程12Windows2000内核模式驱动程序的类型第11章Windows环境下输入输出程序设计Windows2000内核模式驱动程序的类型第11章Win1311.2WDM驱动程序

WDM是Microsoft力推的新型驱动程序模型,首先出现在WindowsNT中,现在的Windows98/Me/2000/XP都支持WDM。微软宣称,在后续的操作系统中将继续支持WDM。第11章Windows环境下输入输出程序设计11.2WDM驱动程序WDM是Mi14WDM是一个分层的驱动程序。它至少有功能驱动程序(Functiondriver)和总线驱动程序(Busdriver)两个层面。功能驱动程序提供一个设备的使用功能,或者可以认为它就是一个设备的驱动程序。用户程序需要使用该设备时,需要调用功能驱动程序中的功能函数。总线驱动程序负责系统启动时设备的安装、检测,并确定设备的资源使用情况。设备的启动、停止,设备的初始化,设备的电源管理等功能也都由总线驱动程序提供。11.2.1WDM驱动程序模型和层次结构第11章Windows环境下输入输出程序设计WDM是一个分层的驱动程序。它15 WDM引入了

功能设备对象FDO(FunctionalDeviceObject)

物理设备对象PDO(PhysicalDeviceObject)

两个新概念来描述硬件。一个PDO对应一个真实硬件。一个硬件只允许有一个PDO,却可以拥有多个FDO,在驱动程序中直接操作的不是硬件而是相应的PDO与FDO。根据具体的需要还可以选择过滤驱动程序(filterdriver)。第11章Windows环境下输入输出程序设计 WDM引入了

功能设备对象FDO(FunctionalDe16Windows20000的输入输出是包驱动的应用程序调用WDM驱动程序时,系统为每一个用户的请求打包,形成一个I/O请求包(I/ORequestPackage,IRP),然后将其发送至驱动程序。IRP中的PDO字段用来区别是发送给哪一个设备的。某个层次的驱动程序得到IRP后,分析其中的请求,完成本层应该完成的任务。如果IRP要求的任务已经完成,该层次的驱动程序就向上一层传送结果并逐层返回。如果IRP中的请求尚未完成,那么就继续向下层驱动程序传递这个IRP。内核组件就是这样通过发送IRP来运行驱动程序中的代码第11章Windows环境下输入输出程序设计Windows20000的输入输出是包驱动的第11章Wind17WDM驱动程序层次与I/O请求过程第11章Windows环境下输入输出程序设计WDM驱动程序层次与I/O请求过程第11章Windows环1811.2.2

WDM驱动程序开发工具 目前有两个主要的工具来开发设备驱动程序,一个是Microsoft公司提供的WindowsDDK。它有Windows98DDK、Windows2000DDK、WindowsXPDDK和Windows2003DDK四个版本,分别用来支持相应的四个操作系统中VxD和WDM驱动程序的开发。 用WindowsDDK开发驱动程序难度较大。第11章Windows环境下输入输出程序设计11.2.2WDM驱动程序开发工具 19另一个驱动程序开发工具是NuMega公司提供的DriverStudio,其中包含VtoolsD、DriversWorks、DriversNetWorks和SoftICE。VtoolsD用来开发Windows98的VxD驱动程序。DriversWorks和DriversNetWorks分别用来开发一般设备和网络设备的WDM驱动程序。SoftICE是一个功能强大的调试工具。第11章Windows环境下输入输出程序设计另一个驱动程序开发工具是NuMega公司提供的Dr20DriverStudio的开发是建立在WindowsDDK的基础上的,安装DriverStudio时,先要安装WindowsDDK。DriverStudio将WindowsDDK的内容封装在一些基本的类中,使用VC++编程。使用DriverStudio来开发Windows的驱动程序,相对WindowsDDK来讲要容易得多。DriverStudio使用开发向导,帮助你建立编写驱动程序所需要的工程文件和程序框架文件,这些文件已经组成了一个完整的设备驱动程序。接下来的工作就是将这些文件导入到VC++的开发环境中,添加具体的操作代码,进行进一步的开发。第11章Windows环境下输入输出程序设计DriverStudio的开发是建立在WindowsDDK2111.2.3

DriverStudio中的WDM驱动程序结构

从基本WDM启动程序的两个头文件中可以大致看清WDM驱动程序的基本框架结构。KDriver是WDM驱动程序的基类,任何驱动程序都要从继承该类开始。SimpleWdmDriver驱动程序从派生KDriver类开始。SimpleWdmDevice是KPnpDevice类的派生类。重载其某些成员函数便可处理相应事件的发生。第11章Windows环境下输入输出程序设计11.2.3DriverStudio中的WDM驱动程序结22最重要的方法是virtualNTSTATUSDeviceControl(KIrpI),应用程序中原本需要对硬件设备的I/O访问指令被移到了DeviceControl中。应用程序需要访问硬件设备时,可以使用DeviceIoControl函数,最后DeviceIoControl会调用DeviceControl,从而完成对设备的I/O访问。可以说DeviceControl就是功能驱动程序。第11章Windows环境下输入输出程序设计最重要的方法是virtualNTSTATUSDevice23//HelloWdm.h-includefileforbasicWDMdriverclassSimpleWdmDriver:publicKDriver{public:

//DriverEntry负责驱动程序的初始化,必须重载 virtualNTSTATUS

DriverEntry(PUNICODE_STRINGRegistryPath);

//AddDevice初始化驱动程序所控制的设备,必须重载virtualNTSTATUSAddDevice(PDEVICE_OBJECTPdo);

//Unload删除由DriverEntry所分配的资源 virtualVOIDUnload(void);};第11章Windows环境下输入输出程序设计//HelloWdm.h-includefilef24//hellodev.h-includefilefordeviceclassofbasicdriverclassSimpleWdmDevice:publicKPnpDevice{public: SimpleWdmDevice(PDEVICE_OBJECTPdo,ULONGUnit);

//PlugandPlayhandlers NTSTATUSOnStartDevice(KIrpI); //设备启动时调用。 NTSTATUSOnStopDevice(KIrpI); //设备停止时调用。 NTSTATUSOnRemoveDevice(KIrpI);

//设备删除时调用。

//UserControlhandlers

//设备打开时调用,应用程序使用Create函数时调用。第11章Windows环境下输入输出程序设计//hellodev.h-includefilef25virtualNTSTATUSCreate(KIrpI); //设备关闭时调用,即应用程序使用Create函数时调用。virtualNTSTATUSClose(KIrpI); //设备功能调用,应用程序使用DeviceIoControl函数时被调用 virtualNTSTATUSDeviceControl(KIrpI); //PowerManagementhandlers NTSTATUSOnDevicePowerUp(KIrpI); // NTSTATUSOnDeviceSleep(KIrpI); //设备睡眠时调用 NTSTATUSOnSetPower(KIrpI); // NTSTATUSDefaultPnp(KIrpI); // NTSTATUSDefaultPower(KIrpI); };第11章Windows环境下输入输出程序设计virtualNTSTATUSCreate(KIrp2611.3Windows2000/XP下输入

输出的实现Windows是一个基于“消息传递”机制的多任务操作系统。用户程序需要访问硬件设备时,通过调用API函数调用该设备的驱动程序。WIN32将用户的请求组合成为一个IRP包,向内核发送“消息”。 内核组件根据IRP中的PDO字段,将该“消息”传送给对应的WDM驱动程序。 驱动程序完成硬件设备的访问后,向用户程序返回结果。 调用驱动程序的过程,就是用户程序和驱动程序之间传递消息,交换数据,进行通信的过程。第11章Windows环境下输入输出程序设计11.3Windows2000/XP下输入

27 用户程序完成对设备的访问有两种方式等待方式下,用户程序调用驱动程序,等待驱动程序完成对硬件设备的访问。这种方式编程简单。异步方式下,应用程序调用驱动程序,启动了硬件设备后,直接返回进行其它处理,并不等待输入/输出完成。硬件设备完成了数据输入输出后,由驱动程序通知应用程序进行进一步的处理。这时,需要由驱动程序发起和应用程序的通信。这种方式下,要用到反调函数、Win32事件通知等方法。第11章Windows环境下输入输出程序设计 用户程序完成对设备的访问有两种方式第11章Windows环28CreateFile()函数用来打开设备,获取设备句柄;设备输入输出控制函数DeviceIoControl(),用来调用WDM驱动程序执行相应的操作(包括设备的控制和数据的输入,输出);CloseHandle()函数用来关闭设备。也可以使用ReadFile()和WriteFile()函数进行“标准”的输入/输出。11.3.1用于输入/输出的WIN32API函数第11章Windows环境下输入输出程序设计CreateFile()函数用来打开设备,获取设备句柄;1291.打开设备

CreateFile()函数用来打开设备,获取设备句柄,格式如下:HANDLECreateFile(“\\\\.\\SimpleWDMDevice”, //设备的符号链接名GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, //同步打开设备NULL );使用上述函数时,除了设备名之外,不需要改变其它参数。这里假设设备的名字为SimpleWDMDevice。进行打开操作时首先搜索当前目录,然后搜索Windows系统目录。第11章Windows环境下输入输出程序设计1.打开设备第11章Windows环境下输入输出程302.DeviceIoControl函数调用DeviceIoControl( HANDLE hDevice, //设备句柄 DWORD dwIoControlCode, //控制代码 LPVOID lpInBuffer, //输入数据块指针 DWORD nInBufferSize,//输入数据块大小 LPVOID lpOutBuffer, //输出数据块指针 DWORD nOutBufferSize,//输出数据块大小 LPDWORD lpBytesReturned, //返回字节长度指针 NULL //同步时为NULL )第11章Windows环境下输入输出程序设计2.DeviceIoControl函数调用第11章Wind31DeviceIoControl函数调用参数hDevice是由CreateFile函数获取的设备句柄。dwIOControlCode是应用程序向WDM驱动程序发出的控制代码。lpInBuffer和nInBufferSize是应用程序向WDM驱动程序传送的I/O数据块的地址及大小。lpOutBuffer、nOutBufferSize和lpBytesReturned是WDM驱动程序返回给应用程序的数据块的地址、大小以及实际返回的字节数。输入/输出缓冲区的格式由驱动程序自行规定。第11章Windows环境下输入输出程序设计DeviceIoControl函数调用参数第11章W323.关闭设备 完成对设备的输入、输出控制后, 应用程序调用CloseHandle(hDevice)关闭设备。第11章Windows环境下输入输出程序设计3.关闭设备第11章Windows环境下输入输出程序设计334.ReadFile和WriteFile函数ReadFile( HANDLE hFile, //设备句柄 LPVOID lpBuffer, //输入数据块指针 DWORDnNumberOfBytesToRead,//输入数据块大小 LPDWORD lpNumberOfBytesRead, //返回的字节数长度指针 NULL ) //同步时为NULLWriteFile( HANDLE hFile, //设备句柄 LPVOID lpBuffer, //输出数据块指针 DWORDnNumberOfBytesToWrite,//输出数据块大小 LPDWORD lpNumberOfBytesWritten,

//实际输出的字节数长度指针 NULL ) //同步时为NULL第11章Windows环境下输入输出程序设计4.ReadFile和WriteFile函数第11章Wi34 本节以Aedk-LabPCI计算机接口实验仪为例,介绍WDM驱动程序的使用。 该实验设备由一块PCI接口卡和一台接口实验仪组成,将PCI接口卡插入PC机的PCI总线插槽,用连接线把PCI卡和实验机相连接,整个实验仪就成为PC机的一台“外部设备”。在监控软件的控制下,进行PC机与实验仪的通讯,实现对实验过程的全程控制。 PCI卡采用了PLX公司的PCI9052芯片作为接口芯片。11.3.2Windows2000/XP下输入输出举例第11章Windows环境下输入输出程序设计 本节以Aedk-LabPCI计算机接口实验仪为例35 进行硬件连接之后,需要安装驱动程序,在Win2000中也就是安装WDM驱动程序。 在实验设备所附带的软件中,驱动程序文件有两个:INF文件,称为设备信息文件,供驱动程序安装时使用。INF文件指明了硬件驱动该如何安装到系统中,源文件在哪里、安装到哪一个文件夹中、怎样在注册表中加入与设备有关的信息等;后缀为sys的文件,是整个实验仪的驱动程序。一般情况下,INF文件会被复制到Windows2000系统目录中的INF子目录中,Sys文件被复制到System32/drivers子目录中。第11章Windows环境下输入输出程序设计 进行硬件连接之后,需要安装驱动程序,在Win2036安装驱动程序后,在设备管理器中可以看到相应的设备第11章Windows环境下输入输出程序设计安装驱动程序后,在设备管理器中可以看到相应的设备第11章Wi37//设备的头文件//8255Demo.h//控制码#defineIOCTL_PCI_CON //读配置信息 CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)#defineIOCTL_IO_READ //IO读 CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ANY_ACCESS)#defineIOCTL_IO_WRITE //IO写 CTL_CODE(FILE_DEVICE_UNKNOWN,0x802,METHOD_BUFFERED,FILE_ANY_ACCESS)第11章Windows环境下输入输出程序设计//设备的头文件第11章Windows环境下输入输出程序设计38//设备的头文件//PCI卡配置信息structpci_cfg{ ULONG MemBase[2]; //内存基地址 ULONG MemLength[2]; //内存大小 ULONG IOBase[2]; //IO基地址 ULONG IOPortLength[2]; //IO基长度 ULONG IRQ; //中断号}; //数据缓冲区structBuffers{ ULONG Address; UCHAR Data;};第11章Windows环境下输入输出程序设计//设备的头文件第11章Windows环境下输入输出程序设计39三个控制码800H、801H和802H分别对应于读配置信息、IO读和IO写。pci_cfg是PCI配置信息的格式,下面的示例程序只用到了IOBase[2]数组,其中可以存放该PCI设备申请获得的三处IO空间的首地址。Buffers是应用程序和驱动程序交换数据的缓冲区格式。Buffers有两个域,地址域名为Address,由用户程序向驱动程序传递需要读写的IO端口地址,另一个是数据域Data,读操作时由驱动程序将读到的数据通过它传递给用户程序,写操作时由用户程序将需要输出的数据通过它传递给驱动程序。需要注意的是,控制码以及输入、输出缓冲区的具体格式由驱动程序自行规定,操作系统对此不予干涉。第11章Windows环境下输入输出程序设计三个控制码800H、801H和802H分别对应于读配置信息40 8255A的PA口接8路开关的输入,PB口输出,接8个发光二极管。 程序的功能是将PA输入的开关量,向PB口输出,用8个开关分别控制8个发光二极管。 输入全零时,程序结束运行。使用实验仪8255A芯片进行开关量输入输出第11章Windows环境下输入输出程序设计 8255A的PA口接8路开关的输入,PB口输出,接8个发41 下面的示例程序中,"\\\\.\\PCI9052Device0"是设备名,只要安装了设备驱动程序,系统就可认出该设备名。 除了主函数,示例程序还包含了四个子函数。

OpenDevice函数打开设备,如果成功则返回设备句柄,失败则程序结束。

GetPCIConfig函数读取设备的配置信息,如果不成功,程序也要结束。

ReadIO和WriteIO是对IO端口的读、写函数。

上面三个子函数都通过调用API函数DeviceIoControl()实现他们各自的功能,区别主要在于使用了不同的控制代码。使用实验仪8255A芯片进行开关量输入输出第11章Windows环境下输入输出程序设计 下面的示例程序中,"\\\\.\\PCI9052Devi42示例程序函数关系第11章Windows环境下输入输出程序设计示例程序函数关系第11章Windows环境下输入输出程序设计43 主函数首先打开设备,读取PCI卡的配置信息。实验设备中8255的片选端连接在译码器的最低端,因此,PCI卡的IO基地址就是8255的PA口地址,依次是PB口的地址、PC口的地址和控制口的地址。 用户编写的ReadIO函数调用DeviceIoControl函数时,输入和输出缓冲区使用同一个缓冲区buf。端口地址是输入参数,调用之前预先置入输入缓冲区buf的Address字段。读操作获得的数据是输出参数,调用完成后从buf的Data字段中取得。 主函数从PA口读入数据,然后向PB口输出,这样就可以用8个开关来分别控制8个发光二极管。读入数据data为零时,程序结束。第11章Windows环境下输入输出程序设计 主函数首先打开设备,读取PCI卡的配置信息。实验设备中844//8255IO读写演示程序,Demo.c#include"8255Demo.h"char*sLinkName="\\\\.\\PCI9052Device0";structpci_cfgpci;structBuffersbuf;HANDLEOpenDevice(){ HANDLEhDevice; hDevice=CreateFile( sLinkName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);第11章Windows环境下输入输出程序设计//8255IO读写演示程序,Demo.c第11章Windo45 if(hDevice==INVALID_HANDLE_VALUE) { printf("请检查PCI卡和驱动程序\n"); exit; } returnhDevice;}第11章Windows环境下输入输出程序设计 if(hDevice==INVALID_HAND46voidGetPCIConfig(HANDLEhDevice){ BOOLstatus; DWORDrc; status=DeviceIoControl(hDevice,IOCTL_PCI_CON, NULL,0,&pci,sizeof(pci_cfg),&rc,NULL); //调用DeviceIoControl函数; //获取PCI设备配置 if(!status){ printf("无法获取pci配置信息\n"); exit; } return;}第11章Windows环境下输入输出程序设计voidGetPCIConfig(HANDLEh47 if(hDevice==INVALID_HANDLE_VALUE) { printf("请检查PCI卡和驱动程序\n"); exit; } returnhDevice;}第11章Windows环境下输入输出程序设计 if(hDevice==INVALID_HAND48 voidWriteIO(WORDport,BYTEdata){ BOOLstatus; DWORDrc; buf->Address=port; //端口地址写入IO缓冲区 buf->Data=data; //输出数据写入IO缓冲区 status=DeviceIoControl(hDevice, IOCTL_IO_WRITE,&buf, sizeof(Buffers),NULL,0,&rc,NULL); //调用DeviceIoControl函数 //向设备进行输出 if(!status)printf("无法写入\n");}第11章Windows环境下输入输出程序设计 voidWriteIO(WORDport,BYTE49 UCHARReadIO(WORDport){ DWORDrc; BOOLstatus buf->Address=port;//将端口地址写入IO缓冲区 status=DeviceIoControl(hDevice,IOCTL_IO_READ,

&buf,sizeof(Buffers),&buf,sizeof(Buffers), &rc,NULL); //调用DeviceIoControl函数 //从设备输入 if(!status)printf("无法读出\n"); returnbuf->Data;}第11章Windows环境下输入输出程序设计 UCHARReadIO(WORDport)第11章W50 voidmain(){ HANDLE hDevice; WORD 8255PAaddr,8255PBaddr,8255ConAddr; UCHAR data; hDevice=OpenDevice(); //打开设备 GetPCIConfig(hDevice); //读取配置信息 8255PAaddr=pci.IOBase[1] //取得PA口地址 8255PBaddr=pci.IOBase[1]+1; //取得PB口地址 8255ConAddr=pci.IOBase[1]+3; //取得控制口地址 WriteIO(8255ConAddr,0x90); //写控制字90h,方式0,PA口读,PB口写第11章Windows环境下输入输出程序设计 voidmain()第11章Windows环境下输入输出51

do{ data=ReadIO(8255PAaddr); //从PA口读取数据 WriteIO(8255PBaddr,data); //将数据写入PB口 }while(data); //数据不为0继续

CloseHandle(hDevice); //关闭设备 return;} 第11章Windows环境下输入输出程序设计 第11章Windows环境下输入输出程序设计52演讲完毕,谢谢听讲!再见,seeyouagain3rew2022/12/17第11章Windows环境下输入输出程序设计演讲完毕,谢谢听讲!再见,seeyouagain3rew53第11章Windows环境下输入输出程序设计2022/12/17第11章Windows环境下输入输出程序设计第11章Windows环境下输入输出程序设计2022/12/54Windows是一个多任务操作系统,在保护模式下工作。Windows操作系统不支持用户程序对计算机底层硬件进行直接控制。用户程序需要输入/输出时,可以通过通过API(ApplicationProgramInterface,应用程序接口)来调用设备驱动程序,对设备实现间接控制,进行输入/输出。Windows9x使用VxDs(VirtualDeviceDriver’s,虚拟设备驱动)设备驱动程序。Windows2000/XP使用WDM(WindowsDriverModel,Windows驱动程序模型)设备驱动程序。第11章Windows环境下输入输出程序设计Windows是一个多任务操作系统,在保护模式下工作。第115511.1Windows设备驱动程序

11.1.1虚拟设备 在多任务运行环境下,计算机内的硬件、软件资源为多个任务共享。任何一个用户程序都不能独占系统的硬件、软件资源。虚拟设备实质上是真实物理设备的部分资源和相关软件的组合,用来完成用户程序需要的功能。虚拟设备不但可以代表实际存在的硬件设备,还可以模拟实际上不存在的“设备”,供用户使用。计算机上的“虚拟光驱”就是一个典型的虚拟设备。与这个设备同名的物理设备是不存在的,用户使用的是硬盘的部分存储空间以及相应的服务程序。第11章Windows环境下输入输出程序设计11.1Windows设备驱动程序11.1.156使用虚拟设备好处:实现多任务对系统资源的共享,方便用户的使用;实现任务与任务、任务与系统之间的隔离和保护;规范外部设备输入、输出方法,使不同工作方式的设备用相同的方式进行输入输出。对Windows应用程序来讲,虚拟设备就是真实设备,应用程序分不清那个设备是由真实硬件支持的真实设备,那个设备是由虚拟设备驱动程序模拟的虚拟设备。第11章Windows环境下输入输出程序设计使用虚拟设备好处:第11章Windows环境下输入输出程序设5711.1.2

Windows9X设备驱动程序Windows9x是一个分层结构的操作系统,由工作在两个不同层面的组件构成:顶层组件,工作在Ring3层;底层组件,工作在Ring0层。第11章Windows环境下输入输出程序设计11.1.2Windows9X设备驱动程序58顶层:Windows9x操作系统的顶层组件工作在特权级3,称为ring3层。它给应用程序的运行提供Win32API服务。Windows9x应用程序和Win32API服务一起构成操作系统的顶层,称为系统虚拟机(VM,VirtualMachine)。对于一个任务来说,这些服务程序以及他们所掌控的硬件资源就是一台“实实在在”的计算机。但是,对于整个系统来说,他们只是由操作系统向用户提供的一个运行用户程序的平台,包括为这个应用程序服务的操作系统组件和部分的硬件资源。每一个DOS应用程序都在一个独立的虚拟机中运行,操作系统允许多个虚拟机同时处于运行状态。第11章Windows环境下输入输出程序设计顶层:第11章Windows环境下输入输出程序设计59底层:Windows9x操作系统的底层组件工作在0特权级,称为ring0层,它就是虚拟机管理器(VMM,VirtualMachineManager)。Windows9x虚拟机管理器由一个内核服务集和许多虚拟设备驱动程序(VxDs,VirtualDeviceDriver’s)组成。许多VxDs是由Microsoft公司随操作系统提供的,如键盘和显示器等的VxDs,有的VxD则由设备制造商提供,或者由用户自行编写。VxD用来支持特定的硬件或软件,完成需要的功能。VxDs中的程序运行在ring0层,可以执行所有的指令,完成所需的任何软硬件的操作。第11章Windows环境下输入输出程序设计底层:第11章Windows环境下输入输出程序设计60 对于应用程序而言,虚拟机管理器是透明的,应用程序感觉不到管理器的存在。 微软已经宣布,从2006年6月起不再提供对Windows9x的技术支持。因此,Windows9x和VxDs的使用将逐渐减少。随着Windows2000/XP的广泛使用,WDM驱动程序的开发和使用已成为主流。第11章Windows环境下输入输出程序设计 对于应用程序而言,虚拟机管理器是透明的,应用程序感觉不到6111.1.3

Windows2000/XP设备驱动程序Windows2000操作系统组件的层次结构 Windows2000操作系统的功能模块划分为用户模式和内核模式两大类。用户模式的操作系统功能模块工作在ring3层,他们不能使用CPU中的特权指令,连同IN、OUT这样的非特权指令也被禁止。所有的用户程序都在这一层上运行。内核模式的操作系统模块工作在ring0层,可以使用CPU的任何指令。第11章Windows环境下输入输出程序设计11.1.3Windows2000/XP设备驱动程序Wi62Windows2000操作系统的层次结构第11章Windows环境下输入输出程序设计Windows2000操作系统的层次结构第11章Windo632.Windows2000的设备驱动程序Windows2000的驱动程序也有两种不同的类型。

用户模式驱动程序工作在用户模式,通过调用内核模式驱动程序实现指定的功能。用户模式驱动程序不能直接对硬件设备进行访问,仅仅用于构建一个硬件或软件的运行环境。

Windows内核驱动程序工作在内核模式,可以直接访问硬件设备。每个设备驱动程序都有一组完成各种功能的函数,通过调用这些函数可以对某一设备完成特定的操作。第11章Windows环境下输入输出程序设计2.Windows2000的设备驱动程序第11章Wi64内核模式驱动程序的类型文件系统驱动程序可以在本地硬盘、网络、移动存储设备或各种有存储能力的硬件设备实现标准的文件系统,如FAT32、NTFS系统等。PnP驱动程序是一种遵循Windows2000即插即用协议的内核模式驱动程序。WDM驱动程序是一种PnP驱动程序。它同时还遵守电源管理协议。显示驱动程序是一种特殊的内核驱动程序。此类的驱动程序还有打印驱动程序、多媒体驱动程序、网络驱动程序等。遗留设备驱动程序主要用在WindowsNT系统中,它也可以运行在Windows2000系统中。第11章Windows环境下输入输出程序设计内核模式驱动程序的类型第11章Windows环境下输入输出程65Windows2000内核模式驱动程序的类型第11章Windows环境下输入输出程序设计Windows2000内核模式驱动程序的类型第11章Win6611.2WDM驱动程序

WDM是Microsoft力推的新型驱动程序模型,首先出现在WindowsNT中,现在的Windows98/Me/2000/XP都支持WDM。微软宣称,在后续的操作系统中将继续支持WDM。第11章Windows环境下输入输出程序设计11.2WDM驱动程序WDM是Mi67WDM是一个分层的驱动程序。它至少有功能驱动程序(Functiondriver)和总线驱动程序(Busdriver)两个层面。功能驱动程序提供一个设备的使用功能,或者可以认为它就是一个设备的驱动程序。用户程序需要使用该设备时,需要调用功能驱动程序中的功能函数。总线驱动程序负责系统启动时设备的安装、检测,并确定设备的资源使用情况。设备的启动、停止,设备的初始化,设备的电源管理等功能也都由总线驱动程序提供。11.2.1WDM驱动程序模型和层次结构第11章Windows环境下输入输出程序设计WDM是一个分层的驱动程序。它68 WDM引入了

功能设备对象FDO(FunctionalDeviceObject)

物理设备对象PDO(PhysicalDeviceObject)

两个新概念来描述硬件。一个PDO对应一个真实硬件。一个硬件只允许有一个PDO,却可以拥有多个FDO,在驱动程序中直接操作的不是硬件而是相应的PDO与FDO。根据具体的需要还可以选择过滤驱动程序(filterdriver)。第11章Windows环境下输入输出程序设计 WDM引入了

功能设备对象FDO(FunctionalDe69Windows20000的输入输出是包驱动的应用程序调用WDM驱动程序时,系统为每一个用户的请求打包,形成一个I/O请求包(I/ORequestPackage,IRP),然后将其发送至驱动程序。IRP中的PDO字段用来区别是发送给哪一个设备的。某个层次的驱动程序得到IRP后,分析其中的请求,完成本层应该完成的任务。如果IRP要求的任务已经完成,该层次的驱动程序就向上一层传送结果并逐层返回。如果IRP中的请求尚未完成,那么就继续向下层驱动程序传递这个IRP。内核组件就是这样通过发送IRP来运行驱动程序中的代码第11章Windows环境下输入输出程序设计Windows20000的输入输出是包驱动的第11章Wind70WDM驱动程序层次与I/O请求过程第11章Windows环境下输入输出程序设计WDM驱动程序层次与I/O请求过程第11章Windows环7111.2.2

WDM驱动程序开发工具 目前有两个主要的工具来开发设备驱动程序,一个是Microsoft公司提供的WindowsDDK。它有Windows98DDK、Windows2000DDK、WindowsXPDDK和Windows2003DDK四个版本,分别用来支持相应的四个操作系统中VxD和WDM驱动程序的开发。 用WindowsDDK开发驱动程序难度较大。第11章Windows环境下输入输出程序设计11.2.2WDM驱动程序开发工具 72另一个驱动程序开发工具是NuMega公司提供的DriverStudio,其中包含VtoolsD、DriversWorks、DriversNetWorks和SoftICE。VtoolsD用来开发Windows98的VxD驱动程序。DriversWorks和DriversNetWorks分别用来开发一般设备和网络设备的WDM驱动程序。SoftICE是一个功能强大的调试工具。第11章Windows环境下输入输出程序设计另一个驱动程序开发工具是NuMega公司提供的Dr73DriverStudio的开发是建立在WindowsDDK的基础上的,安装DriverStudio时,先要安装WindowsDDK。DriverStudio将WindowsDDK的内容封装在一些基本的类中,使用VC++编程。使用DriverStudio来开发Windows的驱动程序,相对WindowsDDK来讲要容易得多。DriverStudio使用开发向导,帮助你建立编写驱动程序所需要的工程文件和程序框架文件,这些文件已经组成了一个完整的设备驱动程序。接下来的工作就是将这些文件导入到VC++的开发环境中,添加具体的操作代码,进行进一步的开发。第11章Windows环境下输入输出程序设计DriverStudio的开发是建立在WindowsDDK7411.2.3

DriverStudio中的WDM驱动程序结构

从基本WDM启动程序的两个头文件中可以大致看清WDM驱动程序的基本框架结构。KDriver是WDM驱动程序的基类,任何驱动程序都要从继承该类开始。SimpleWdmDriver驱动程序从派生KDriver类开始。SimpleWdmDevice是KPnpDevice类的派生类。重载其某些成员函数便可处理相应事件的发生。第11章Windows环境下输入输出程序设计11.2.3DriverStudio中的WDM驱动程序结75最重要的方法是virtualNTSTATUSDeviceControl(KIrpI),应用程序中原本需要对硬件设备的I/O访问指令被移到了DeviceControl中。应用程序需要访问硬件设备时,可以使用DeviceIoControl函数,最后DeviceIoControl会调用DeviceControl,从而完成对设备的I/O访问。可以说DeviceControl就是功能驱动程序。第11章Windows环境下输入输出程序设计最重要的方法是virtualNTSTATUSDevice76//HelloWdm.h-includefileforbasicWDMdriverclassSimpleWdmDriver:publicKDriver{public:

//DriverEntry负责驱动程序的初始化,必须重载 virtualNTSTATUS

DriverEntry(PUNICODE_STRINGRegistryPath);

//AddDevice初始化驱动程序所控制的设备,必须重载virtualNTSTATUSAddDevice(PDEVICE_OBJECTPdo);

//Unload删除由DriverEntry所分配的资源 virtualVOIDUnload(void);};第11章Windows环境下输入输出程序设计//HelloWdm.h-includefilef77//hellodev.h-includefilefordeviceclassofbasicdriverclassSimpleWdmDevice:publicKPnpDevice{public: SimpleWdmDevice(PDEVICE_OBJECTPdo,ULONGUnit);

//PlugandPlayhandlers NTSTATUSOnStartDevice(KIrpI); //设备启动时调用。 NTSTATUSOnStopDevice(KIrpI); //设备停止时调用。 NTSTATUSOnRemoveDevice(KIrpI);

//设备删除时调用。

//UserControlhandlers

//设备打开时调用,应用程序使用Create函数时调用。第11章Windows环境下输入输出程序设计//hellodev.h-includefilef78virtualNTSTATUSCreate(KIrpI); //设备关闭时调用,即应用程序使用Create函数时调用。virtualNTSTATUSClose(KIrpI); //设备功能调用,应用程序使用DeviceIoControl函数时被调用 virtualNTSTATUSDeviceControl(KIrpI); //PowerManagementhandlers NTSTATUSOnDevicePowerUp(KIrpI); // NTSTATUSOnDeviceSleep(KIrpI); //设备睡眠时调用 NTSTATUSOnSetPower(KIrpI); // NTSTATUSDefaultPnp(KIrpI); // NTSTATUSDefaultPower(KIrpI); };第11章Windows环境下输入输出程序设计virtualNTSTATUSCreate(KIrp7911.3Windows2000/XP下输入

输出的实现Windows是一个基于“消息传递”机制的多任务操作系统。用户程序需要访问硬件设备时,通过调用API函数调用该设备的驱动程序。WIN32将用户的请求组合成为一个IRP包,向内核发送“消息”。 内核组件根据IRP中的PDO字段,将该“消息”传送给对应的WDM驱动程序。 驱动程序完成硬件设备的访问后,向用户程序返回结果。 调用驱动程序的过程,就是用户程序和驱动程序之间传递消息,交换数据,进行通信的过程。第11章Windows环境下输入输出程序设计11.3Windows2000/XP下输入

80 用户程序完成对设备的访问有两种方式等待方式下,用户程序调用驱动程序,等待驱动程序完成对硬件设备的访问。这种方式编程简单。异步方式下,应用程序调用驱动程序,启动了硬件设备后,直接返回进行其它处理,并不等待输入/输出完成。硬件设备完成了数据输入输出后,由驱动程序通知应用程序进行进一步的处理。这时,需要由驱动程序发起和应用程序的通信。这种方式下,要用到反调函数、Win32事件通知等方法。第11章Windows环境下输入输出程序设计 用户程序完成对设备的访问有两种方式第11章Windows环81CreateFile()函数用来打开设备,获取设备句柄;设备输入输出控制函数DeviceIoControl(),用来调用WDM驱动程序执行相应的操作(包括设备的控制和数据的输入,输出);CloseHandle()函数用来关闭设备。也可以使用ReadFile()和WriteFile()函数进行“标准”的输入/输出。11.3.1用于输入/输出的WIN32API函数第11章Windows环境下输入输出程序设计CreateFile()函数用来打开设备,获取设备句柄;1821.打开设备

CreateFile()函数用来打开设备,获取设备句柄,格式如下:HANDLECreateFile(“\\\\.\\SimpleWDMDevice”, //设备的符号链接名GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, //同步打开设备NULL );使用上述函数时,除了设备名之外,不需要改变其它参数。这里假设设备的名字为SimpleWDMDevice。进行打开操作时首先搜索当前目录,然后搜索Windows系统目录。第11章Windows环境下输入输出程序设计1.打开设备第11章Windows环境下输入输出程832.DeviceIoControl函数调用DeviceIoControl( HANDLE hDevice, //设备句柄 DWORD dwIoControlCode, //控制代码 LPVOID lpInBuffer, //输入数据块指针 DWORD nInBufferSize,//输入数据块大小 LPVOID lpOutBuffer, //输出数据块指针 DWORD nOutBufferSize,//输出数据块大小 LPDWORD lpBytesReturned, //返回字节长度指针 NULL //同步时为NULL )第11章Windows环境下输入输出程序设计2.DeviceIoControl函数调用第11章Wind84DeviceIoControl函数调用参数hDevice是由CreateFile函数获取的设备句柄。dwIOControlCode是应用程序向WDM驱动程序发出的控制代码。lpInBuffer和nInBufferSize是应用程序向WDM驱动程序传送的I/O数据块的地址及大小。lpOutBuffer、nOutBufferSize和lpBytesReturned是WDM驱动程序返回给应用程序的数据块的地址、大小以及实际返回的字节数。输入/输出缓冲区的格式由驱动程序自行规定。第11章Windows环境下输入输出程序设计DeviceIoControl函数调用参数第11章W853.关闭设备 完成对设备的输入、输出控制后, 应用程序调用CloseHandle(hDevice)关闭设备。第11章Windows环境下输入输出程序设计3.关闭设备第11章Windows环境下输入输出程序设计864.ReadFile和WriteFile函数ReadFile( HANDLE hFile, //设备句柄 LPVOID lpBuffer, //输入数据块指针 DWORDnNumberOfBytesToRead,//输入数据块大小 LPDWORD lpNumberOfBytesRead, //返回的字节数长度指针 NULL ) //同步时为NULLWriteFile( HANDLE hFile, //设备句柄 LPVOID lpBuffer, //输出数据块指针 DWORDnNumberOfBytesToWrite,//输出数据块大小 LPDWORD lpNumberOfBytesWritten,

//实际输出的字节数长度指针 NULL ) //同步时为NULL第11章Windows环境下输入输出程序设计4.ReadFile和WriteFile函数第11章Wi87 本节以Aedk-LabPCI计算机接口实验仪为例,介绍WDM驱动程序的使用。 该实验设备由一块PCI接口卡和一台接口实验仪组成,将PCI接口卡插入PC机的PCI总线插槽,用连接线把PCI卡和实验机相连接,整个实验仪就成为PC机的一台“外部设备”。在监控软件的控制下,进行PC机与实验仪的通讯,实现对实验过程的全程控制。 PCI卡采用了PLX公司的PCI9052芯片作为接口芯片。11.3.2Windows2000/XP下输入输出举例第11章Windows环境下输入输出程序设计 本节以Aedk-LabPCI计算机接口实验仪为例88 进行硬件连接之后,需要安装驱动程序,在Win2000中也就是安装WDM驱动程序。 在实验设备所附带的软件中,驱动程序文件有两个:INF文件,称为设备信息文件,供驱动程序安装时使用。INF文件指明了硬件驱动该如何安装到系统中,源文件在哪里、安装到哪一个文件夹中、怎样在注册表中加入与设备有关的信息等;后缀为sys的文件,是整个实验仪的驱动程序。一般情况下,INF文件会被复制到Windows2000系统目录中的INF子目录中,Sys文件被复制到System32/drivers子目录中。第11章Windows环境下输入输出程序设计 进行硬件连接之后,需要安装驱动程序,在Win2089安装驱动程序后,在设备管理器中可以看到相应的设备第11章Windows环境下输入输出程序设计安装驱动程序后,在设备管理器中可以看到相应的设备第11章Wi90//设备的头文件//8255Demo.h//控制码#defineIOCTL_PCI_CON //读配置信息 CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)#defineIOCTL_IO_READ //IO读 CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ANY_ACCESS)#defineIOCTL_IO_WRITE //IO写 CTL_CODE(FILE_DEVICE_UNKNOWN,0x802,METHOD_BUFFERED,FILE_ANY_ACCESS)第11章Windows环境下输入输出程序设计//设备的头文件第11章Windows环境下输入输出程序设计91//设备的头文件//PCI卡配置信息structpci_cfg{ ULONG MemBase[2]; //内存基地址 ULONG MemLength[2]; //内存大小 ULONG IOBase[2]; //IO基地址 ULONG IOPortLength[2]; //IO基长度 ULONG IRQ; //中断号}; //数据缓冲区structBuffers{ ULONG Address; UCHAR Data;};第11章Windows环境下输入输出程序设计//设备的头文件第11章Windows环境下输入输出程序设计92三个控制码800H、801H和802H分别对应于读配置信息、IO读和IO写。pci_cfg是PCI配置信息的格式,下面的示例程序只用到了IOBase[2]数组,其中可以存放该PCI设备申请获得的三处IO空间的首地址。Buffers是应用程序和驱动程序交换数据的缓冲区格式。Buffers有两个域,地址域名为Address,由用户程序向驱动程序传递需要读写的IO端口地址,另一个是数据域Data,读操作时由驱动程序将读到的数据通过它传递给用户程序,写操作时由用户程序将需要输出的数据通过它传递给驱动程序。需要注意的是,控制码以及输入、输出缓冲区的具体格式由驱动程序自行规定,操作系统对此不予干涉。第11章Windows环境下输入输出程序设计三个控制码800H、801H和802H分别对应于读配置信息93 8255A的PA口接8路开关的输入,PB口输出,接8个发光二极管。 程序的功能是将PA输入的开关量,向PB口输出,用8个开关分别控制8个发光二极管。 输入全零时,程序结束运行。使用实验仪8255A芯片进行开关量输入输出第11章Windows环境下输入输出程序设计 8255A的PA口接8路开关的输入,PB口输出,接8个发94 下面的示例程序中,"\\\\.\\PCI9052Device0"是设备名,只要安装了设备驱动程序,系统就可认出该设备名。 除了主函数,示例程序还包含了四个子函数。

OpenDevice函数打开设备,如果成功则返回设备句柄,失败则程序结束。

GetPCIConfig函数读取设备的配置信息,如果不成功,程序也要结束。

ReadIO和WriteIO是对IO端口的读、写函数。

上面三个子函数都通过调用API函数DeviceIoControl()实现他们各自的功能,区别主要在于使用了不同的控制代码。使用实验仪8255A芯片进行开关量输入输出第11章Windows环境下输入输出程序设计 下面的示例程序中,"\\\\.\\PCI9052Devi95示例程序函数关系第11章Windows环境下输入输出程序设计示例程序

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论