分享

WDM驱动程序的组成

 梦中家园 2013-04-29
在修改C8051F320单片机的驱动程序时,一开始真的有点无从下手,幸好看到了这本书-《USB应用开发技术大全》(人民邮电出版社),使自己对那一大堆的代码,终于理出了思路。在这里就把WDM驱动程序的组成的大概内容摘抄出来,与大家分享。
 
    Windows操作系统下,一般不能直接对硬件接口进行操作,而必须采用驱动程序作为桥梁。主要程序和驱动程序直接通信,交换数据;而驱动程序则和计算机的硬件资源进行通信。 

 

        WDMWindows Driver Model),即Windows驱动程序模型,是Microsoft力推的全新驱动程序模式,旨在通过一种灵活的方式来简化驱动程序的开发,实现对硬件的支持,并减少和降低所有所须开发的驱动程序的数量和复杂性。

 

 
    在WDM驱动程序模型中主要包括两个驱动程序:功能驱动程序和总线驱动程序。由于总线驱动程序已经由操作系统提供,因此,关心的主要是功能驱动程序。一个完整的功能驱动程序包括许多例程:
基本驱动程序例程:DriverEntry和AddDevice。
I/O控制例程:StartIO、AdapterControl、OnInterrupt……
派遣函数:DispatchPnP、DispatchPower、DispatchRead、DispatchWrite……

    当操作系统遇到一个I/O请求包(IRP)时,系统调用驱动程序中的例程来执行相应的操作。在这些例程中,DriverEntry例程和AddDevice例程对每个驱动程序都是必须的,当然还需要其他一些I/O控制例程和派遣函数。其中StartIO例程用于对IRP进行排队,AdapterControl例程用于执行DMA操作的驱动程序中,OnInterrupt例程为中断服务例程。 

       I/O请求包(IRP)主要由MajorFunctionMinorFunction字段构成,当然还可以包括Struct ReadStruct Write等控制参数。MajorFunction字段是IRP的主要功能代码,MinorFunction字段是IRP的次要功能代码,它们指明了驱动程序应该执行的具体操作。

常用的IRP主功能代码:

IRP_MJ_CREATE 打开文件句柄

IRP_MJ_CLOSE 关闭文件句柄

IRP_MJ_READ 读取数据

IRP_MJ_WRITE 写数据

IRP_MJ_CLEANUP 清除挂起的IRP

IRP_MJ_DEVICE_CONTROL 设备I/O控制

IRP_MJ_INTERNAL_DEVICE_CONTROL 底层的设备I/O控制

IRP_MJ_SYSTEM_CONTROL 系统管理与测试

IRP_MJ_POWER 电源管理

IRP_MJ_PNP 即插即用管理 

 

 

        WDM驱动程序的功能实现主要由特定的例程决定。在不同的情况下,操作系统或主机程序触发相应的例程,实现不同的操作。一个典型的WDM驱动程序由以下部分构成:

入口例程DriverEntry:主要用于WDM驱动程序的初始化,是所有驱动程序必须的。

即插即用例程:用户处理即插即用设备的添加、停止和删除等。

分发例程:用于处理主机程序的各种I/O请求。

电源管理例程:用于处理系统和设备的电源管理请求。

卸载例程:处理WDM驱动程序的卸载等操作。

 

    驱动程序入口例程,即DruverEntry例程,是所有驱动程序的入口。DriverEntry例程由操作系统的I/O管理器在设备驱动功能加载的时候进行调用,主要负责WDM驱动程序的初始化。

 

    即插即用例程,当设备连接到计算机上的时候,操作系统自动识别,自动选择并加载合适的驱动程序。当设备从系统中移除的时候,自动处理相应的清除工作。在设备连接和断开的时候,整个过程不需要用户的干预。
其例程主要有两个:一个AddDevice例程和一个IRP_MJ_PNP例程。
AddDevice 例程主要使用IoCreateDevice函数来创建和初始化一个设备对象,然后初始化设备扩展,并使用IoAttachDeviceToDeviceStack函数将设备连接到设备栈。

IRP_MJ_PNP例程主要负责处理系统即插即用管理器发出的PnP信息,包括启动设备(IRP_MN_START_DEVICE)、停止设备(IRP_MN_STOP_DEVICE)、删除设备(IRP_MN_REMOVE_DEVICE)等。

 

    分发例程,用于处理各种I/O请求,这是主机程序控制硬件的接口。每个分发例程对应一个Win32函数,主机程序便是通过Win32函数来和相应的分发例程通信的。常用的分发例程如下所示。

IRP_MJ_CREATE例程,对应的Win32函数为CreateFile

IRP_MJ_CLOSE例程,对应的Win32函数为CloseHandle

IRP_MJ_READ例程,对应的Win32函数为ReadFile

IRP_MJ_WRITE例程,对应的Win32函数为WriteFile

IRP_MJ_DEVICE_CONTROL例程,对应的Win32函数为DeviceIoControl

一般来说,并不是所有的分发例程都是必须的,但是所有的驱动程序都要包含IRP_MJ_CREATE例程和IRP_MJ_CLOSE例程。如果没有这两个例程,主机程序便不能获得设备句柄,也就不能控制设备。

 

    电源管理例程,用于管理设备或系统的电源状态,其有四个次功能代码:

IRP_MN_SET_POWER设置系统或设备电源状态。

IRP_MN_QUERY_POWER查询是否允许改变系统或设备的电源状态。

IRP_MN_WAIT_WAKE响应外部事件以唤醒设备。

IRP_MN_POWER_SEQUENCE确认设备是否进入指定的电源状态。

 

    卸载例程,只在需要卸载驱动程序的时候调用,一般来说,驱动程序的卸载例程需要完成如下几个方面的工作:保存设备的状态,以便于设备恢复到最近保存的设备状态。释放该驱动程序所占用的内存空间。删除设备对象及其符号链接名或GUID描述符。通常情况下,卸载例程可以什么也不做,因为其主要的工作都在处理例程IRP_MN_REMOVE_DEVICE中完成。

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多