精华内容
下载资源
问答
  • Windows设备驱动程序WDF开发
  • 我将带领大家学习WDM驱动开发,包括重要的理论与实践。 我们逐步深入,在系列一的基础上慢慢推进,开始学习WDM驱动模型,包括重要的IRP及派遣函数,具体章节包括: 1)PNP即插即用管理 2)电源管理 3)IO端口管理 4...
  • Windows设备驱动程序WDF开发及源码,需要的同志请拿走
  • windows设备驱动程序WDF开发武安河源码,学习wdf的可以参考。
  • WDF体系结构windows驱动开发。。
  • windows设备驱动程序wdf开发 光盘 去掉bin 7z 自解压
  • 讨论了嵌入式操作系统Windows CE与桌面Windows系统设备驱动开发的区别,主要包括驱动结构模型、驱动组成部分和开发环境。
  • Windows设备驱动程序WDF开发(书籍)

    热门讨论 2013-02-17 18:22:57
    Windows设备驱动程序WDF开发,作者:武安河
  • Windows设备驱动程序WDF开发源码

    千次下载 热门讨论 2009-05-26 15:21:24
    Windows设备驱动程序WDF开发》既适合具有一定计算机硬件及C/C++语言基础的计算机应用开发人员阅读,也适合作为计算机应用开发人员和高等院校学生的实用参考书。Windows最新的WDF驱动程序框架,包括KMDF和UMDF,...
  • Windows设备驱动程序WDF开发 武安河 资源为我的联系方式 支持支付宝交易
  • 武安河的《Windows设备驱动程序WDF开发》,是一本wdf驱动开发入门好书,里面包含书本所有源码。
  • 学习windows驱动(WDF USB设备驱动开发)

    千次阅读 2015-10-29 18:01:04
    根据《竹林蹊径 深入浅出Windows驱动开发》第4章 WDF USB设备驱动开发里介绍的目录可以初见端倪,需要了解USB设备硬件结构,USB软件结构,内核开发, 数据I/O操作,设备控制,用户程序。USB设备硬件结构。 USB是...

    学习WDF USB驱动开发,
    那么怎么进行WDF USB设备驱动开发呢?
    我们需要懂什么?
    需要做什么呢?
    根据《竹林蹊径 深入浅出Windows驱动开发》第4章 WDF USB设备驱动开发里介绍的目录可以初见端倪,需要了解USB设备硬件结构,USB软件结构,内核开发,
    数据I/O操作,设备控制,用户程序。

    USB设备硬件结构。
    USB是Universal Serial Bus(通用串行总线),它的硬件特征是串行数据传输和热插拔。
    USB连接分主从结构。
    USB主机要具备USB主控制器和USB根集线器。主控制器用来处理跟集线器上的数据,交给系统处理;根集线器用来连接多个外部设备,及提供USB埠。
    USB中断是伪中断,usb在自己内存保存中断数据,等主机来查询,然后给主机数据。
    USB软件结构包含总线驱动、功能驱动、过滤驱动,它体现了多模块之间的分工和统筹。
    总线驱动位于驱动栈的最下层,它负责资源分配、子设备管理等,处理上层驱动请求。USB设备总线驱动有控制器驱动、Hub驱动,还有端口驱动。
    控制器驱动Usbohci.sys、Usbuhci.sys、Usbehci.sys。
    HCI代表主机控制接口(Host Control Interface)。
    Hub驱动:Usbhub.sys
    Hub驱动是所有设备的父驱动。
    端口驱动:Usbport.sys
    系统类驱动。
    USB设备包含USB集线器设备、USB HID设备、USB音频设备、USB MIDI设备、USB存储设备。为了使开发简单,Windows操作系统为它们提供了系统驱动程序。
    功能驱动。
    父驱动和混合设备。
    过滤驱动。
    你想过滤谁,得先了解谁;否则,死机、蓝屏会与你不期而遇。就像你想追求一个人,要先熟悉这个人一样。

    USB驱动栈、设备栈。
    驱动栈、设备栈本质上是并行的概念。驱动之间的联系是通过设备对象进行间接联系的,驱动栈只是概念上的,它表示一个设备能够在系统里被识别、运行,从上到下需要哪些驱动程序支持。
    系统里每个DevNode表现为一个设备栈。
    可以这样理解:驱动栈里包含了若干独立的设备栈,每个驱动可同时存在于若干不同的设备栈里。

    内核开发
    要讲述的内容包括:WDF USB框架介绍、设备配置、数据传输、设备控制等。其中USB的数据传输方式包含了控制方式、中断方式、批量方式3种。
    设备驱动

    设备驱动和过滤驱动、内核服务不同。后者的存在,可能是为了实现一个内核API的Hook,或者挂载到某个设备以截取数据,目的比较复杂、散。
    设备驱动目的专一,为了让某个物理设备能正常工作,和系统结为紧密的一体。
    专一性往往等同于特殊性。从初始化到设备操作由设备协议本身决定:不同总线、不同数据格式、不同传输方式。

    设备配置就是设备初始化。
    数据操作分输入输出。用正确的方法把正确的数据输入或输出设备,是设备驱动的终极目标。
    设备控制包含很多操作。USB设备控制包含设备Reset、管道Reset\设置特性等。

    入口函数
    编程首先想到的是入口函数。
    驱动程序加载由System进程完成,System进程首先在驱动文件的PE架构中寻找入口函数地址,默认都指向DriverEntry。

    USB描述符
    USB协议里的描述符包括: 设备描述符、配置描述符、字符串描述符、报告(Report)描述符等。

    描述符介绍
    USB描述符定义有一个共同特点,前两个字节意义相同,第一字节表示结构体长度,第二个字节表示描述符类型。
    设备描述符
    配置描述符
    字符串描述符

    读取描述符

    展开全文
  • Windows WDM设备驱动程序开发
  • Windows设备驱动程序(VxD与WDM)开发讲述windows环境下设备驱动程序开发的过程
  • Windows WDM设备驱动程序开发指南.rar Windows WDM设备驱动程序开发指南.rar
  • Windows WDM设备驱动程序开发指南(PDF).rar
  •  本书介绍了编写Windows7设备驱动程序所需的知识,涵盖了用户模式驱动程序开发、内核模式驱动程序开发、WDF架构、驱动程序调试等主题。作者展示了如何利用微软提供的强大工具和模型,高效地开发稳定、健壮的驱动...
  • Windows usb驱动开发.zip

    2020-01-08 14:30:47
    该例子详细介绍了windows usb驱动开发。关于usb如何编写驱动程序和windows设备编程如何实现。
  • Windows CE设备驱动开发之电源管理

    千次阅读 2012-06-02 16:28:33
    它所有设备的电源使用,同时能与不支持电源管理的应用程序及驱动程序共存。 使用电源管理可以有效的减少目标设备的电源消耗,同时,能在运行、空闲、复位及挂起电源状态时维持并保护RAM中的文件系统。 电源管理...

    4.7电源管理

    电源管理模块管理设备电源,从而全面改进操作系统的电源使用效率;它所有设备的电源使用,同时能与不支持电源管理的应用程序及驱动程序共存。

    使用电源管理可以有效的减少目标设备的电源消耗,同时,能在运行、空闲、复位及挂起电源状态时维持并保护RAM中的文件系统。

    电源管理具有以下特性:

    使设备具有自行电源管理功能的框架;

    建立一种在系统中使设备电源在挂起和恢复状态间切换的机制;

    一个对系统环境、电源状态、设备电源状态有统一认识的模块。你可以定制电源管理模块,使全系统的电源分配适合您的设备;

    当系统挂起或恢复时,使系统跳过所有代码调用PowerOffSystem函数。

    对于支持电源管理的驱动程序,在设备枚举时应尽量准确的向电源管理模块报告其性能,然后将收到来自电源管理模块的获取或更改其电源状态的请求。对于自行管理电源的设备,必须通过DevicePowerNotify向电源管理模块发送请求来更改电源状态。

    电源管理模块与设备在一个正常的线程执行环境中通过调用DeviceIoControl进行通讯。

     

    4.7.1、            电源管理架构

    在不依赖Windows CE电源管理模型的情况下,只能对设备进行简单的管理。电源管理器为OEM厂商提供了较大的灵活性,同时驱动开发人员也不用为了兼容电源管理模型而牺牲驱动程序性能。在基本的Windows CE电源模型中,在操作系统挂起或恢复时,设备会收到标识信息(notification)。这一标识信息在中断处理时产生,所以设备在挂起状态时可以做什么工作,有多长时间做这一工作被严格限制。下图描述了Windows CE电源管理的结构。

    使用电源管理器时,设备会从I/O控制代(IOCTLs)收到电源状态改变通知。因为IOCTLs在线程中执行,在线程中驱动开发者可以更为灵活的处理电源状态改变。使用IOCTLs还能够区分设备电源状态与系统电源状态。这样,在系统运行时可以将部分设备关闭,而某些设备也可以在系统挂起时一直开启。

    除了管理设备电源,电源管理器还向应用程序通知其它与电源相关事件的发生。例如:当系统从挂起状态恢复运行时,电源管理器会向相关应用程序发出通知。

    电源管理器是一个名为pm.dll的动态链接库,系统运行时被Device.exe进程直接调用。当电源管理API被调用时,Device.exe调用pm.dll的入口函数。在Platform Builder 4.0及其后续版本中提供了Pm.dll的源代码OEM厂商可以根据其设备修改Pm.dll

    电源管理器担任设备、应用程序及预定义的操作系统电源状态的仲裁者。电源管理器定义了下列规则,使上述三部分以这些规则进行通讯:

    l         系统电源状态限定了所有设备的最大功耗;

    l         应用程序以最小功耗来获取指定设备的最低性能等级。

    l         当设备功耗在其最大功耗与最小功耗范围内时,电源管理器允许设备自行管理其电源。

    l         如果最小功耗高于最大功耗,那么,在应用程序请求设备运行期间,设备电源将持续提升。

    l         设备可以在一个或多个电源状态下运行。电源状态以有限的数字表示。详见设备电源状态章节。

    l         系统转为挂起状态后,对应用程序有用的最小功耗将被取消。

    l         系统电源状态是描述所有设备中最大的设备电源状态。系统电源状态由OEM厂商定义,并在注册表中描述,同时,在电源管理器中可以加入部分支持代码。OEM厂商可以定义任意数量的系统电源状态。详见系统电源状态章节。

    在电源管理器框架内部,OEM厂商可以定义系统电源状态来设定最大设备电源状态。设备调用DevicePowerNotify来控制其电源等级,应用程序调用SetPowerRequirement来确认它们需要使用的设备是否正在合适的性能等级运行。

     

    4.7.1.1              电源管理器和ACPI/APM

    电源管理器并不涉及高级配置与电源接口(ACPI)或高级电源管理(APM)ACPI规范将系统电源状态定义为一个从高功率/高性能到低功率/低性能的线性集。Windows CE电源管理器允许OEM厂商定义任意数目的系统电源状态,但并不要求定义的系统电源状态是线性的。

    我们鼓励开发者根据情况定义操作系统电源状态,并根据设备定位或环境控制设备电源。例如:开发者可以定义系统电源状态,据此可以做到在装置不在支架(cradle)中时可以关闭某些设备,或者当系统使用外接交流电源时允许设备运行在高功耗电源等级。同样的,开发者可以根据系统环境定义不同的空闲、挂起状态。开发者需要定制电源管理器并保证在适当或必须的时候在各种电源状态间切换。

    系统电源状态与ACPI模式有显著的区别。然而,设备电源状态表面上看起来与ACPI规范中的设备电源状态类似,但实际上,他们仍有细微的区别。例如:在Windows CED3电源状态被设定为在操作系统挂起时可使指定设备担任唤醒源的功能。

    4.7.1.2              电源挂起、恢复回调函数

    挂起和恢复电源事件的回调函数与电源管理器无关。当CPU被停止,操作系统将进入挂起状态,这时回调函数会被系统调用。并在OEMPowerOff被调用前立即执行。在电源管理器请求关闭系统电源并进入挂起状态之前,电源管理器会时常对设备驱动进行IOCTL调用。当然,情况并不总是这样。电源管理器框架允许设备在系统运行时被关闭,也允许设备在系统挂起时处于开启状态。

    当设备电源状态为D0D1D2,如果掉电事件发生时,开发者可以自行决定进行何种处理。此时,通常关闭设备电源,并在加电事件发生时恢复供电。如果设备可以不依赖CPU即可运行,在挂起状态时或许可以使此设备运行。如果设备在挂起期间一直处于供电状态,那可能是电源管理器配置错误,或者是应用程序使用POWER_FORCE标记对此设备进行了SetPowerRequirement调用。

     

    4.7.1.3              其他电源管理API

    电源管理器创建于标准的Windows CE电源体系结构的上层。所以,不管电源管理器如何运行,流接口设备驱动程序在系统挂起或恢复时总是通过XXX_PowerUpXXX_PowerDown获取通知。下表列出了与电源管理相关的API

    函数名

    功能描述

    GetSystemPowerStatusEx2

    获取电池状态信息。

    PowerPolicyNotify

    以事件的形式通知电源管理器,以便执行必要的处理,从而实现OEM创建的电源策略。

    OEMIdle

    被系统内核调用。在没有线程需要运行时将处理器置为空闲状态。

    OEMPowerOff

    当关机按钮被按下,或图形、窗体、事件子系统(GWES)超时时被调用。使处理器进入挂起状态。

    XXX_PowerDown (Device Manager)

    挂起设备电源。仅用于能被软件控制关闭的设备。

    XXX_PowerUp (Device Manager)

    恢复设备电源。

     

    Windows CE设备驱动开发之电源管理      第二部分

    4.7.2、电源状态

    电源管理器期望所有被管理的设备能支持一个或多个设备电源状态。设备电源状态的数量是有限的。设备必须通知电源管理器其功耗特性。设备常以功耗换取性能。

    电源管理器在OEM定义的系统电源状态下管理设备电源状态。系统电源状态在注册表中定义,可以用任意数字定义。系统电源状态会给设备电源状态设置一个上限。

    某些应用程序可能需要特定设备保持运行在指定的设备功率等级上。例如:当一个音频播放程序在播放音乐时,可能需要网卡及音频解码器保持运行在高功率等级。视频播放程序可能需要网络、音频,同时可能要使显示设备在进入屏幕保护模式后一直显示,并保持背光常亮。应用程序可以请求电源管理器设置最小设备电源状态,电源管理器会调用SetPowerRequirementReleasePowerRequirement系统API来进行设置。

    4.7.2.1              设备电源状态

    设备电源状态是预定义的静态值。电源管理器将设备状态传给驱动程序,驱动程序负责将其映射为自身的设备性能,然后在物理设备上进行状态转换。

    下表是对各种设备电源状态的描述。

    设备电源状态

    注册表键值

    描述

    Full on

    D0

    此状态表示设备已开启或正在运行。设备将以系统允许的最大功耗及最高性能运行。

    Low on

    D1

    此状态表示设备已开启或正在运行,但以低于D0状态的功耗及性能运行。D1状态适用于设备已经被使用,但以较低的性能运行即可,没有必要以最大性能运行,会产生额外的功率消耗。

    Standby

    D2

    此状态表示设备被部分供电,保证设备在需要时能自动唤醒。

    Sleep

    D3

    睡眠状态。保证唤醒的最小供电,在需要时能自动唤醒并初始化。

    Off

    D4

    关闭状态,不供电。

    一种物理设备并不能支持上述所有的设备电源状态。但是,所有的设备都必须支持D0设备电源状态。如果驱动程序收到请求,要求其将设备进入它不支持的电源状态,驱动程序应使设备进入下一个支持的电源状态。例如:电源管理器请求设备进入D2电源状态,但设备并不支持D2状态,这时如果设备支持D3D4状态,驱动程序应使设备进入D3D4状态。如果某一设备需要进入D3状态,但是此设备却不能唤醒系统,那么应使此设备进入D4状态。上述这些规则可以使驱动程序的执行简单化。

    电源管理器有选择的将系统电源状态映射为对应的设备电源状态。例如:如果设备仅支持D0D4电源状态,那么,电源管理器不会直接请求设备进入D4电源状态。如果D3D4被设为此设备的最小电源状态,电源管理器会一直等待直到系统进入D3D4状态时,再将设备设为D4状态。如果此设备的最小电源状态被设为D0D1D2,电源管理器将使设备一直运行于D0状态。

    当设备驱动程序被加载时,应将设备设为D0状态。在驱动程序被卸载时,应将设备设为D4状态。如果在启动时设备进入了D0外的其他设备电源状态,那么可以在处理IOCTL_POWER_CAPABILITIES时发出一个DevicePowerNotify请求。

     

    4.7.2.2              系统电源状态

    系统电源状态由OEM定义,并由OEM引用。OEM可以将其命名为像OnSystemIdleOnBatteryInCradleOutOfCradle等名称。这些名称并没有被系统预定义,也不要求将其定义为线性序列。系统电源状态在系统配置注册表键中定义。Windows CE并没有限制可以定义多少种系统电源状态。

    当然,也可以创建系统电源状态与预定义的设备电源状态的显式映射。显式映射需要在注册表中定义。系统电源状态明确的制定系统中所有设备的最大设备电源状态。

    电源管理器示例定义了OnUserIdleSystemIdleSuspend四种系统电源状态。当用户使用系统时,电源状态设为On。如果用户停止使用,电源状态被设为UserIdle。当用户在一定的周期内(如30s)不使用系统,则进入SystemIdle状态;只要设备驱动程序处于活动状态,系统将一直保持在SystemIdle状态。如果设备驱动程序停止活动,系统进入Suspend状态。

    UserIdle状态用于用户正在使用设备,但却没有操作设备。例如,用户一直观看屏幕显示,但没有手动操作。SystemIdle状态被用于用户没有直接使用设备,但处理器仍在继续运行。例如,在传输文件期间,用户可能人为设备已处于空闲状态,但实际上处理器依旧在持续运行,直到文件传输完成。

    电源管理器示例实现了根据UserActivitySystemActivity定时器对用户及系统活动进行判断。在定时器超时后,根据当前系统供电状况(使用外接电源或电池)进行不同的系统电源状态切换。

    Platform Builder提供的Windows CE运行时image示例均使用外接电源供电模式。你可以选择实现一套在使用电池供电时的电源状态。复制电源管理器示例代码的PDD目录,并对其做适当的修改即可。

    4.7.2.2.1   将系统电源状态映射为设备电源状态

    在注册表系统配置中明确定义系统电源状态名称。系统电源状态到设备电源状态的映射在注册表的每一个电源状态名称键值下被枚举。如下示例代码:

    [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power/State/Example]
        Default=dword:0; D0
        Flags=dword:10000; POWER_STATE_ON
        COM1:=dword1; D1

    上面的注册表片段定义了名为Example的系统电源状态,并设置了除COM1:被限制为最高运行于D1设备电源状态外,其他的所有设备最高均可运行于D0设备电源状态。其中Flags列是一个标识码,用于表示Pm.h头文件中定义的POWER_STATE_ON标记。如果需要,OEM可以定义自己的电源状态标记。

    下表列出了键值名称及其描述。

    键名

    描述

    Name

    系统电源状态名称

    Flags

    标识码。用于表示在Pm.h头文件中预定义的类似于POWER_STATE_ON的标记。

    Default

    表示在此系统电源状态下时,所有设备的默认设备电源状态。此键值用数字表示,0代表D01代表D1,以此类推。

    DeviceName

    设置在此系统电源状态下指定设备的最大设备电源状态。可以对任意数目的设备进行定义。

     

    电源管理器支持多种设备类型的映射。例如:NDIS迷你接口及块设备驱动器设备类型在Pm.h中会被指定为其自身的GUID类型。其他类型被管理设备的默认值也可以在注册表中指定。例如:

    [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power/State/Example/{98C5250D-C29A-4985-AE5F-AFE5367E5006}]
        Default=dword:1; D1
        "CISCO1"=dword:0; D0

    上面注册表片段设置电源管理器限值所有NDIS迷你接口设备在Example系统电源状态下时均运行于D1设备电源状态,只有名为CISCO1的设备最高可运行于D0状态。

     

    4.7.2.2.2   系统电源状态切换

    电源管理器在下列情况下进行系统电源状态切换:

    l         OEM定义的状态切换事件发生。

    l         应用程序调用SetSystemPowerState

    OEM定义的事件可能包含设备供电从外接电源切换为使用电池供电,延长系统空闲周期,将设备插入底座(Cradle),电池电量低等。OEM需要根据情况修改电源管理器,以便判断两种系统电源状态间的切换是否合理,并在必要时切换系统电源状态。Platform Builder提供的电源管理器源代码仅支持在设备从外接电源切换为使用电池供电时进行系统电源状态切换。

    应用程序可以使用系统电源状态名或表示系统电源状态的数值为参数调用SetSystemPowerState函数。如果应用程序了解OEM定义的系统电源状态,那么可以选择使用电源状态名进行显式调用。对于独立于平台的应用程序,则设置数值进行调用,并允许电源管理器决定如何进行电源状态映射。电源管理器可对应用程序能请求的状态进行限制。

     

    4.7.2.2.3   系统电源状态示例

    下面的注册表片段是表示系统电源状态到设备电源状态映射的示例。

    [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power/State/On]
        "Default"=dword:0           ; D0
        "Flags"=dword:10000         ; POWER_STATE_ON
    [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power/State/UserIdle]
        "Default"=dword:1           ; D1
        "Flags"=dword:0
    [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power/State/SystemIdle]
        "Default"=dword:2           ; D2
        "Flags"=dword:0
    [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power/State/Suspend]
        "Default"=dword:3           ; D3
        "Flags"=dword:200000        ; POWER_STATE_SUSPEND
    ; @CESYSGEN IF CE_MODULES_NDIS
    [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power/State/Suspend/{98C5250D-C29A-4985-AE5F-AFE5367E5006}]
        "Default"=dword:4           ; D4
    ; @CESYSGEN ENDIF CE_MODULES_NDIS

    下表描述了上面注册表片段的映射方式。

    系统电源状态

    设备电源状态

    On

    D0

    UserIdle

    D1

    SystemIdle

    D2

    Suspend

    D3NDIS迷你接口单独被映射为D4

    当系统使用上面的注册表配置,并进入Suspend状态,除了NDIS迷你接口会被关闭外,其他可唤醒源都将处于可激活状态。如果有设备不支持D3状态,它将自动进入D4状态。

    应用程序可以使用SetPowerRequirement创建设备电源要求。也可以使用电源管理器控制面板程序创建附加的设备电源要求。

     

    4.7.2.3              设备及系统电源状态名称

    电源管理器要求使用小写字母命名设备及系统电源状态名称。一些类似于wsprintf(buf, "%u", n)或不区分大小写的比较这样的操作,会涉及区位表(Locale table)查询。区位表(Locale table)Wince.nls内存映射文件中被实现。在挂起期间,电源管理器不能使用FileSystemPowerFunction访问文件系统。从挂起的线程中访问文件系统可能造成操作系统死锁。如果Wince.nls中必须的页面无法在内存中找到,就会产生死锁。

    在处理API调用时,电源管理器将名称转换为小写字母。然而,在挂起及恢复状态时,电源管理器在文件系统操作被禁止后访问注册表。这时不能将注册表设置项转换为小写。所以必须将系统电源状态注册表设置改为小写字母。例如:WAV1:应被描述为wav1:。其他类似于注册表HKLM/Drivers/Builtin下的用于控制设备驱动加载的设置项不用修改。

    Windows CE设备驱动开发之电源管理 第三部分 

    4.7.3、电源管理器接口

    电源管理器有三种不同的使用者。

    l         电源管理器能识别的设备的驱动程序。

    l         可能需要更改系统电源状态或设备性能的应用程序。

    l         需要电源事件通知的应用程序。

    电源管理器使用不同的编程接口与这些使用者进行通讯。

    4.7.3.1              设备驱动接口

    电源管理器使用两种不同的机制与支持电源管理的设备驱动进行通讯。电源管理器向下调用设备驱动确定其设备性能,并更新其设备电源状态。设备向上调用电源管理器请求进行设备电源状态更改。向下调用在系统中以IOCTL方式实现。设备通过DevicePowerNotify API函数向上调用电源管理器。

    由于电源管理器使用DeviceIoControl与支持电源管理的设备进行通讯,所以设备需要实现一个外部(expose)流接口。在某些情况下,可以用电源管理代理来实现外部流接口。网络驱动接口规约(NDIS)中实现了一个外部流接口,从而能使用RegisterPowerRelationship API函数进行对NDIS迷你接口的代理管理。电源管理器同时提供了一种与非流接口设备的通讯机制。这一方法由具有打开设备句柄、发送请求等功能的抽象层组成。例如:位于Public/Common/Oak/Drivers/Pm/Mdd/Pmdisplay.cpp的驱动程序实现了一个基于ExtEscape函数的通讯接口。

    打开名称格式为COM1:、并实现了外部流接口的标准设备,可以对其进行读写。但是,电源管理器并不要求支持电源管理的设备必须使用这种命名格式;设备名称可以是任意唯一的字符串。例如:NDIS迷你接口可以被命名为VMINI1

    尽管Platform Builder提供的电源管理器仅支持流接口驱动,但OEM可以自由的实现其他的设备接口。可以为设备定义一个新的唯一类型全局标识符(GUID)来实现新的接口。不过,驱动程序在使用新接口时必须遵循标准电源管理设备驱动准则。

    默认情况下,电源管理器可以发现下列GUID表示的设备类型:

    l         {A32942B7-920C-486b-B0E6-92A702A99B35} GUID类型为普通被管理设备。

    l         {8DD679CE-8AB4-43c8-A14A-EA4963FAA715} GUID类型为块设备。

    l         {98C5250D-C29A-4985-AE5F-AFE5367E5006} GUID类型为NDIS设备。

    应用程序可以从HKEY_LOCAL_MACHINE/System/CurrentControlSet/Control/Power /Interfaces注册表键中获取可被管理的设备类型的列表。

    当应用程序调用一个引用了指定设备的电源管理器API时,应用程序必须指定设备的GUID类型名。如果没有指定设备的GUID类型名,电源管理器会假定此设备为普通被管理设备类型。

    有效的设备类型名需要有GUID前缀及反斜杠符号。例如:GUID {8DD679CE-8AB4-43c8-A14A-EA4963FAA715}/DSK1:表示引用一个名为DSK1的块设备。

    电源管理器从注册表读取设备类型列表,使用RequestPowerNotifications决定此类型的设备在什么时候被载入。下面时设备类型列表的示例。

    [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power/Interfaces]
        "{A3292B7-920C-486b-B0E6-92A702A99B35}"="Generic power-manageable devices"
        "{8DD679CE-8AB4-43c8-A14A-EA4963FAA715}"="Power-manageable block devices"
        "{98C5250D-C29A-4985-AE5F-AFE5367E5006}"="Power-manageable NDIS miniports"

    Platform Builder附带的电源管理器以上述设置执行。如果不定义新的设备注册表键,在注册表中可以不包含上述设置。下面步骤说明了实现一个表示使用ExtEscape直接管理的显示驱动类型的过程。

    1.     使用Guidgen.exe创建一个新的GUID类型,并将其添加到注册表中。

    2.     为了识别GUID,需要修改电源管理器,并使用ExtEscape与设备通讯。

    3.       调用AdvertiseInterface,使用新的GUID修改显示驱动。

     

    4.7.3.1.1     IOCTL设备控制符

    电源管理器使用下列IOCTL码与设备通讯:

    IOCTL

    功能

    IOCTL_POWER_CAPABILITIES

    要求设备通知电源管理器它所支持的电源状态及其特性。

    IOCTL_POWER_SET

    要求设备更新其设备电源状态。

    IOCTL_POWER_QUERY

    询问设备是否准备好可以进入另外一个设备电源状态。

    IOCTL_POWER_GET

    要求设备通知电源管理器它现在的设备电源状态。

    IOCTL_REGISTER_POWER_RELATIONSHIP

    通知父设备登记它所控制的所有设备。

     

    4.7.3.1.2     驱动到电源管理器的API函数

    电源管理器为被管理设备提供下列函数,设备可以通过调用下列函数相电源管理器请求服务。

    函数名

    功能

    DevicePowerNotify

    设备驱动调用此函数请求电源管理器更新其设备电源状态。

    RegisterPowerRelationship

    总线驱动及其他代理电源管理器在需要拦截所有设备的电源IOCTL时调用此函数。

    ReleasePowerRelationship

    结束由RegisterPowerRelationship调用创建的代理关系。

     

    4.7.3.2              应用程序接口

    电源管理器提供了一些函数,使应用程序可以使用这些函数进行设备电源管理。下表中的API函数中,只有GetSystemPowerStateSetPowerRequirementReleasePowerRequirement是普通应用程序可以直接执行的。例如:应用程序可以调用SetSystemPowerState来挂起系统,但是电源管理器可以限制应用程序可以请求进入的系统电源状态。其他的API函数是为像控制面板这样的OEM应用程序准备的。下表是这些函数的说明。

    函数名

    功能

    GetSystemPowerState

    返回当前系统电源状态的名称。

    SetSystemPowerState

    请求电源管理器更改当前系统电源状态。

    SetPowerRequirement

    请求电源管理器将指定设备的电源状态维持在最小等级。

    ReleasePowerRequirement

    释放SetPowerRequirement设置的电源状态.将设备电源状态恢复到调用SetPowerRequirement之前的状态。

    GetDevicePower

    返回指定设备的当前电源状态。

    SetDevicePower

    请求电源管理器更改指定设备的当前电源状态。

     

    4.7.3.2.1   系统电源状态设置

    某些情况下,应用程序需要更改系统电源状态。在特定的Windows CE设备上,应用程序并不知道哪些电源状态可用,也不期望知道这些电源状态的特性。对应用程序而言,最好使用描述电源状态的掩码来调用SetSystemPowerState进行电源状态切换,而不要使用明确的状态名调用。电源管理器会将此掩码转换为对应的电源状态。例如:应用程序可以使用POWER_STATE_SUSPEND位元请求进行系统电源状态切换。根据在请求时系统是否在支架(cradle)中,电源管理器随后会切换到SuspendSuspendCradle状态。如果设备被从支架中取下,电源管理器会将设备切换到Suspend状态。

    电源管理器可以限定应用程序可以设置进入哪些系统电源状态。例如:如果电源管理器使用外部输入控制系统电源状态,那么,当系统使用电池供电时,将不会允许进入ACRun状态。Platform Builder附带的电源管理器仅允许应用程序设置系统进入Suspend状态。

    下表描述了预定义的电源状态位元及其含义。

    位元

    描述

    POWER_STATE_ON

    高性能高功耗。

    POWER_STATE_OFF

    所有设备都被关闭。

    POWER_STATE_CRITICAL

    电池低电量。

    POWER_STATE_BOOT

    系统正在启动。

    POWER_STATE_IDLE

    空闲状态。

    POWER_STATE_RESET

    清除文件,关闭设备并调用KernelIoControl.

    POWER_STATE_SUSPEND

    挂起操作系统并最终调用OEMPowerOff.

    Platform Builder附带的电源管理器并没有使用上表中全部状态。OEM可以根据其设备自行定义状态标记。

    如果应用程序使用SetSystemPowerState请求进入一个新的电源状态,电源管理器将进行以下处理:

    l         广播PBT_TRANSITION通知。

    l         如果需要更新所有设备的电源状态。如果设备已处于一个可被新的电源状态接受的电源状态下,电源管理器就不会进行IOCTL_POWER_SET请求。

    l         如果设备从挂起状态恢复,电源管理器广播PBT_RESUME通知。

     

    4.7.3.2.2   设备电源需求

    在某些情况下应用程序需要改变电源管理器对系统电源状态的管理。例如:某页面调度程序需要使COM3:保持运行在D3或更高的状态,即使在挂起时也以此电源状态运行,从而在COM3:收到一个输入页时能唤醒系统。或者,例如一个流音频程序可能需要网卡及音频系统即便在系统使用电池供电,并以及空闲了一段时间的情况下也能保持在全功耗(Full Power)运行。电源管理器提供SetPowerRequirement API函数为有特定电源管理需求的应用程序提供支持。

    SetPowerRequirement API函数允许应用程序请求电源管理器在设备电源状态上设置一个较低的下限。如果电源要求有效,电源管理器则不允许设备将自己的电源状态设为低于要求的下限值。当电源管理器更改系统电源状态时,如果设备需要维持在高于系统电源状态所允许的设备电源状态,电源管理器通常会使设备保持此电源状态。

    当系统挂起时设备的电源需求通常会被取消。当系统处于挂起状态时,CPU将停止运行,中断服务也将停止。如果应用程序需要设备在挂起状态时能继续运行,可以在调用SetPowerRequirement时设置POWER_FORCE标记。进行此操作需要对应的设备驱动程序支持在系统挂起时自行停用。

    电源管理器可能取消其他环境下的设备电源需求。例如,OEM厂商可能会重新解释系统电源状态POWER_STATE_CRITICAL标记,以便指示系统在使用电池供电,且电池处于低电量临界时,应关闭所有设备。

     

    4.7.3.3              通知接口

    电源管理器提供了一组API函数,从而允许应用程序获取电源相关事件的通知,并参与决策系统电源状态的切换。下表列出了相关的API函数。

    函数

    描述

    RequestPowerNotifications

    请求电源管理器发送电源事件通知。

    StopPowerNotifications

    取消由RequestPowerNotifications发出的通知请求。

    通知信息通过消息队列传递。为了使用通知,应用程序需要创建一个消息队列,并通过RequestPowerNotifications API函数将消息队列句柄传递给电源管理器。通常将创建一个线程来监控消息队列,等待消息产生。

    电源管理器定义了以下几种通知类型。

    通知

    描述

    PBT_RESUME

    当系统从挂起状态恢复时产生。

    PBT_POWERSTATUSCHANGE

    当系统在AC供电及其他供电方式(如电池)间切换时产生。

    PBT_TRANSITION

    当电源管理器进行系统电源状态变更时产生。

     

    Windows CE设备驱动开发之电源管理 第四部分

    4.7.4、设备电源管理指南

    电源管理器对设备功耗、性能及响应时间并没有进行严格的限制。只是在用户角度而言D0D1状态下是可操作的,而更高编号的电源状态比D0D1消耗更少的电源。

    本指南的目的是为了使OEM厂商能更容易的定义有意义的系统电源状态,而不用了解特定设备的详细功耗要求。

    4.7.4.1              设备电源自管理(Device Power Self-Management

    一些设备自行管理其电源的过程可能比较复杂。当设备处于休止状态时,驱动程序开发人员希望能降低它们的功耗。降低功耗一般会同时降低设备性能,所以当这些设备被使用时,也需要提升其性能等级。提升性能的同时也会增大设备功耗。

    这些设备往往根据其被使用频繁程度来动态的提升或降低其设备电源状态。但电压自管理的实际算法根据设备特性的不同而不同。

    电源管理器的DevicePowerNotify API函数允许驱动开发人员请求电源管理器调整设备的电源状态。如果所请求的设备电源状态在允许的范围内(即最大及最小值之间),电源管理器将允许对设备电源状态的调整。最大值为系统电源状态要求的值,最小值由应用程序调用SetPowerRequirement API设定。

    如果电源管理器设备请求的电源状态调整,电源管理器将调用对应的设备API更新设备电源状态,如:使用设备的IOCTL_POWER_SET函数。在调用DevicePowerNotify函数时,需要遵循以下要求:

    l         DevicePowerNotify调用成功后设备不能立即更新其电源状态,直到IOCTL_POWER_SET被引发时才能更新。

    l         驱动开发人员不能认为DevicePowerNotify调用成功就意味着电源管理器一定会引发IOCTL_POWER_SET

    l         驱动开发人员不能认为IOCTL_POWER_SET会被作为DevicePowerNotify调用的结果而被立即引发。

    l         当能够唤醒系统的设备进入D3状态后,不应再使用DevicePowerNotify来请求D3状态。

    一些设备能够支持D0D4设备电源状态以外的其他电源等级。如果需要,驱动开发人员可以将此类设备的多个电源等级映射到电源管理器所能识别的某一设备电源状态。设备可以不依赖电源管理器在每个设备电源状态的允许范围内自由的进行电源自管理。但是,设备仍然需要使用DevicePowerNotify进行设备电源状态切换。

    自管理示例

    对于一个实现了所有五种电源状态的设备,如果在一定的时间周期内无活动,需要动态的从D0降到D1状态,或从D1降到D2状态。这是因为D2状态的耗电量更少,而且设备很少需要响应。如果设备发觉需要活动,但其不在D0状态,设备将尝试进入D0状态。

    这样一个设备的中断服务线程可能与下面的示例代码类似。

    while(!fDone) {

        dwStatus = WaitForSingleObject(hInterruptEvent, dwTimeout);

        switch(dwStatus) {

        case WAIT_OBJECT_0: // device activity

            // service device

            ...

            if(deviceDx != D0 && !fBoostRequested) {

                fBoostRequested = TRUE;

                DevicePowerNotify(pszDeviceName, D0, POWER_DRIVER | POWER_NAME);

     

            }

            dwTimeout = INACTIVITY_TIMEOUT;

            break;

        case WAIT_TIMEOUT:  // device inactive

            if(deviceDx < D2 && !fReductionRequested) {

                fReductionRequested = TRUE;

                DevicePowerNotify(pszDeviceName, deviceDx + 1, POWER_DRIVER | POWER_NAME);

     

            }

            if(deviceDx >= D2) {

                dwTimeout = INFINITE;

            }

        default:            // error handling

            break;

        }

    }

    设备的DeviceIoControl处理程序可能包含下列示例代码。

    case IOCTL_POWER_SET:

        // update device registers

        ...

        deviceDx = *(PCEDEVICE_POWER_STATE) pOutBuf;

        fBoostRequested = FALSE;

        fReductionRequested = FALSE;

        break;

    上面驱动程序代码仅表明了是否请求了状态切换,而不是是否已经切换。这一点非常重要,因为设备可能在D2状态时请求进入D0状态,但是由于当前的电源情况,电源管理器可能仅将其设为D1状态。在下一次设备活动时,设备会再次请求进入D0状态,而电源管理器可能只允许其运行在D1状态。明白了状态切换请求的过程,能够避免在设备进入活动状态前进行额外的电源管理API调用。同样的处理逻辑也用于当设备非活动超时时电源状态降低的过程。

    设备的中断服务程序在调用DevicePowerNotify函数前设置fBoostRequestedfReductionRequested标记。这是因为DevicePowerNotify调用可能导致调用IOCTL_POWER_SET而在同一线程中再次进入驱动程序。DeviceIoControl调用会清除标记,从而使驱动程序在之后能进一步调整设备电源状态。

    4.7.4.2              如何为驱动程序添加电源管理(How to Add Power Management to a Device Driver

    开发者可以为驱动程序添加电源管理支持,以便能够降低目标设备的功耗。为此,驱动程序必须导出流接口。如果已经实现了流接口,那么可以开始添加电源管理支持。

    硬件及软件假定

    你掌握了如何从命令行创建WinCE运行时镜像。详见Build Tool

    步骤

    相关主题

    1. 创建一个流接口驱动。

    How to Create a Device Driver

    2. 为流接口驱动添加IOCTLs。关于电源管理IOCTLs的更多信息,见Power Management IOCTLs.

    Power-Manageable Device Drivers

    3. 通知电源管理器,驱动程序支持电源管理。见Power Management Functions.

    4. 在驱动程序中实现设备电源状态。关于设备电源状态的更多信息,见Device Power States.

    Power Management Implementation in Drivers

    5. 编译驱动程序。如果编译无错,那么你已成功为流接口驱动添加了电源管理。详见Troubleshooting: Building a Driver.

    Building a Device Driver from the Command Line

    6. 调试驱动程序.

    How to Debug a Device Driver

    4.7.4.3              电源可管理设备驱动(Power-Manageable Device Drivers

    为了创建一个支持电源管理的设备驱动程序,必须先定义一个non-COM-related设备接口。non-COM-related设备接口表示设备支持电源管理。可以使用以下方式定义这一设备接口:

    l         可以在用于激活设备的注册表键的IClass值中定义接口。

    l         可以使用驱动程序的Init函数在活动注册表中定义IClass值。

    l         可以调用ActivateDeviceEx函数并使用REGINI参数来定义IClass值。

    l         可以在驱动程序中显式的调用AdvertiseInterface

    关于为电源管理定义non-COM-related接口的更多信息,参见设备接口通知。可以通过调用RequestPowerNotifications函数为电源管理通知注册设备驱动程序,同时将句柄传递给电源管理通知专用的消息队列。如果驱动程序需要响应电源通知并进行相关处理,就必须这么做。通常情况下,一旦驱动程序实现了电源管理支持,那么此驱动只需要处理电源管理器的DeviceIoControl调用。

    电源管理器通过IOCTL码与设备通讯。下表列出了电源管理器与设备通讯时使用的IOCTL码:

    Function

    Description

    IOCTL_POWER_CAPABILITIES

    请求设备驱动返回设备支持的电源状态及相关特征

    IOCTL_POWER_SET

    请求驱动更新设备的电源状态

    IOCTL_POWER_QUERY

    电源管理器询问设备是否准备好进行状态切换

    IOCTL_POWER_GET

    请求驱动返回当前设备的电源状态

    IOCTL_REGISTER_POWER_RELATIONSHIP

    通知父设备注册所有它所控制的设备

     

    你可以实现并使用可选的IOCTL_POWER_QUERY控制码,以便在驱动程序还没有准备好改变电源状态时,延迟电源切换。你可以通过修改MDD层来支持IOCTL_POWER_QUERY,虽然这样修改可能会导致MDD层与电源管理器的未来版本不兼容。

    4.7.4.4              在驱动程序中实现电源管理(Power Management Implementation in Drivers

    在配置驱动程序支持电源管理时,要确定驱动程序每个入口点的电源状态。如果确定电源状态正确无误,那么驱动程序会根据目标设备的当前电源状态以适当的方式运行。

    确保在XXX_PowerUp被调用时驱动程序不会给目标设备加电。而应该恢复电源管理器设置的电源状态,很可能是D3D4这样的状态值。同样,在XXX_PowerDown被调用时不会关闭目标设备电源。

    注意:如果在挂起前目标设备一直没有加电,电源管理器也没有向其发送请求。这种情况下,驱动程序没有正确配置,所以要在驱动程序中重新配置。

    4.7.4.5              在流接口驱动中实现电源管理(Power Management Implementation in Stream Interface Drivers

    在驱动程序能够支持电源管理之前,必须先导出一个流接口。导出的流接口会提供一组入口点以便实现标准文件I/O函数,这些函数会被kernel使用。

    关于导出流接口的更多信息,见流接口驱动实现(Stream Interface Driver Implementation)。

    除流接口函数外,驱动程序还必须支持IOCTL_POWER_CAPABILITIESIOCTL_POWER_SET这两个IOCTL

    关于IOCTL_POWER_SET的更多信息,见IOCTL_POWER_SET请求处理(IOCTL_POWER_SET Request Processing)。

    关于IOCTL_POWER_CAPABILITIE的更多信息,见设备电源特性(Device Power Capabilities)。

    一旦配置了流接口,就可以进一步配置驱动程序来支持电源管理。更多信息参见 4.4在驱动程序中实现电源管理。

    4.7.4.6              设备类型名(Class-Qualified Device Names

    Windows CE .NET 4.10起,支持电源管理的设备可分属于不同的设备类型。这些设备类型由预定义类型和自定义类型组成。电源管理器API函数可以接受设备名称,也可以接受有效地设备类型名称(class-qualified device names)。例如,下面列出的每一名称都是有效的设备名称:

    l         COM1:

    l         {A32942B7-920C-486b-B0E6-92A702A99B35}/COM1:

    l         {98C5250D-C29A-4985-AE5F-AFE5367E5006}/CISCO1

    l         {8DD679CE-8AB4-43c8-A14A-EA4963FAA715}/DSK1:

    如果某个设备的类型无效,那么此设备将被假定属于默认设备类型。例如,上面COM1:{A32942B7-920C-486b-B0E6-92A702A99B35}/COM1:是等效的。

    4.7.4.7              设备初始化(Device Initialization Responsibilities

    在初始化期间,设备驱动程序应将设备置为D0状态,同时在电源管理器通过IOCTL_POWER_CAPABILITIES询问时应尽可能准确的汇报设备特性。

    4.7.4.8              IOCTL_POWER_SET请求处理(IOCTL_POWER_SET Request Processing

    电源管理器使用IOCTL_POWER_SET(设备的IOCTL码)来调整设备的电源状态。在实现此IOCTL码时,驱动程序开发人员应了解下列内容:

    l         设备并不一定需要支持所有五种设备电源状态,但至少必须支持D0状态;如果设备仅支持D0状态,那么它也不需要处理IOCTL_POWER_SET

    l         电源管理器可能会要求设备进入任何设备电源状态,并不仅仅是设备声明支持的几个。

    l         如果一个设备被要求进入一个它并不支持的电源状态,它就会进入另一个它支持的更高功耗的状态。例如,一个设备并不支持D2,它会被要求进入D1

    l         电源管理器可能会通过发出IOCTL_POWER_SET,使设备再次进入它已经处于的当前状态。在这种情况下,设备驱动程序简单的返回成功即可。

    l         设备的电源状态不一定与系统的电源状态同步,因为它可能受到应用程序需求的限制。

     

    4.7.4.9              挂起及恢复处理(Suspend and Resume Handling

     

    支持电源管理的流设备驱动程序通过XXX_PowerDownXXX_PowerUp不断接收系统挂起/恢复状态通知。这些通知在内核调用OEMPowerOff之前的中断处理中发出。PowerDown/PowerUp回调机制与电源管理器无关,----

    Power managed stream device drivers will continue to receive notifications of system suspend and resume states through their XXX_PowerDown (Device Manager) and XXX_PowerUp (Device Manager). These notifications are sent in an interrupt context just before the kernel calls OEMPowerOff. The PowerDown/PowerUp callback mechanism is independent of the Power Manager and allows legacy device drivers to function under Microsoft? Windows? CE .NET 4.0 and later.

    驱动开发人员应该知道,当系统进入挂起状态,处理器将不再运行。理论上,电源管理器会根据电源状态映射,使设备进入对应的设备电源状态。然而,挂起系统电源状态或应用程序的设备电源需求可能不适合某些设备。例如,多媒体应用程序可能要求音频设备保持运行在D0状态。如果音频芯片需要频繁使用处理器设置DMA缓存,驱动开发人员可判定此设备在系统挂起状态不适合运行于D0状态,并关闭设备电源。

    驱动开发者必须知道在系统处于挂起状态时设备适合使用哪些电源状态,从而依此实现其驱动程序。这一方法适合保守的驱动开发人员在系统挂起期间进行电源管理决策。但是,在系统挂起时并不是所有的设备都必须被关闭。例如,如果音频设备可以不依赖处理器播放音乐,那么它可以在系统挂起期间保持供电。

    如果驱动开发人员在挂起期间改变了设备的电源状态,就必须在系统恢复的同时恢复设备的电源状态。在系统挂起期间,这些设备应尽量保证其实际行为对电源管理器而言是透明的。

    当支持电源管理的流设备通过ActivateDeviceEx被加载时,可以自动通知电源管理器。在注册表HKEY_LOCAL_MACHINE/CurrentControlSet/Control/Power/Interfaces键值下的所有设备在加载时都需要通知电源管理器。如果这些设备的注册表IClass键值(REG_MULTI_SZ类型)中包含类似"{A32942B7-920C-486b-B0E6-92A702A99B35}"GUID,那么在其被加载时电源管理器会收到通知。

    设备在收到IOCTL_POWER_CAPABILITIES控制码后,可以通过调用DevicePowerNotify函数管理其自身电源。在设备处理IOCTL期间,电源管理器允许设备自行管理电源。

    如果OEM厂商选择实现非流接口的设备API,就需要定制电源管理器,使其使用新的机制与设备通讯。

     

    4.7.4.10          D3设备状态和系统唤醒(Device State D3 and System Wakeup

    D3设备电源状态需要特殊考虑,因为它并不是仅仅用于限定设备的功耗等级。设备可以运行与D3状态,从而在挂起状态时唤醒系统,但者并不是必须的。

    下列指南说明了如何在驱动程序中添加D3状态支持:

    l         可以从挂起状态唤醒系统的设备不应通过DevicePowerNotify请求进入D3状态。这是因为在系统进入挂起状态前,不应存在唤醒源。----

    Devices that can wake the system from a suspend state should not request the D3 state through DevicePowerNotify. This is because enabling a device as a wake source is not always appropriate, unless the system is going to enter a suspend state. The driver cannot distinguish IOCTL_POWER_SET requests for D3 that it has initiated itself from those initiated by the Power Manager as part of a system power state transition.

    l         可以将支持唤醒的设备的D2D3状态定义为相同的电压等级,当然D2状态不支持唤醒功能。

    l         不能从挂起状态唤醒系统,但是具有一个能保持设备运行最低功耗模式的设备,在电源自管理过程中可以使用D3状态。

    l         如果一个非唤醒源设备运行在D3状态,并且系统挂起,那么它应在XXX_PowerDown处理过程切换到D4状态;同时在XXX_PowerUp处理中恢复到D3状态。如果做不到,就不能支持D3状态,而应在请求进入D3状态时直接切换到D4状态。

    l         上述指南隐含说明了支持D3状态的设备不一定能在挂起状态唤醒系统。

    总之,OEM厂商设计系统电源状态时,应用程序开发者调用SetPowerRequirement时都需要考虑系统挂起期间D3状态的特殊性。上述指南同时描述了OEM厂商和应用程序开发者可以在挂起期间要求设备进入D3状态,而不用考虑设备是否支持唤醒功能。

     

    4.7.4.11          设备电源特性(Device Power Capabilities

    IOCTL_POWER_CAPABILITIES在即插即用设备枚举时从驱动程序中查询设备的具体特性,包括潜伏周期(latency)、功耗、系统唤醒及启动功率(Inrush)。在驱动程序响应此IOCTL时也同时汇报他所支持的设备电源状态。电源管理器一般不会要求设备进入它所不支持的电源状态。但是,驱动开发人员不能认为这种情况不会产生。因为设备制造商可以定制电源管理器,设备制造商可能会忽略POWER_CAPABILITIES结构的DeviceDx字段。

     

    Windows CE设备驱动开发之电源管理 第五部分

    4.7.1、活动定时器(Activity Timers

    在初始化时,电源管理器从注册表中读取活动定时器名称列表。对于每个定时器,电源管理器都会检查其超时时间(以秒为单位)以及可选的唤醒源列表。然后创建下列事件:

    l         定时器重置事件

    l         活动状态手动重置事件

    l         手动重置事件

    如果超时与不产生重置事件的定时器到期关联,电源管理器将重置活动事件并设置非活动事件。如果重置事件产生,电源管理器重置非活动事件并设置活动事件。

    下列示例代码是配置一个活动计时器的注册表设置: [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power/ActivityTimers/SystemActivity]

        "Timeout"=dword:A

    "WakeSources"=multi_sz:"0x20"

    上面注册表设置会引发电源管理器创建三个事件,分别名为:PowerManager/ActivityTimer/SystemActivityPowerManager/SystemActivity_Active PowerManager/SystemActivity_Inactive。第一个事件是一个自动重置事件,任何驱动程序都可能通过发送信号表明系统处于活动状态。支持重置活动定时器的驱动程序应从注册表中读取定时器的重置事件名称。其他两个是手动重置事件,这两个事件在同一时刻只会产生一个,而不会同时发生。驱动程序、应用程序或电源管理器自身都可能打开这些事件的句柄,以便确定定时器是否到期。这些事件表明了活动定时器的状态。重置事件是活动定时器的输入,状态事件是其对应的输出。

    除了创建事件,这一注册表设置项还将一个唤醒源与此活动定时器关联。如果系统恢复,并且电源管理器确定系统是由此活动定时器对应的唤醒源所唤醒,那么此活动定时器将被置为活动。电源管理器使用IOCTL_HAL_GET_WAKE_SOURCE内核IOCTL来确定是什么设备唤醒了系统。----

    In addition to creating events, this set of registry entries associates a wake source identifier with the activity timer. If the OS resumes and the Power Manager determines that the wake source corresponding to this ID caused the system to resume, it will set the associated activity timer to active. The Power Manager uses the IOCTL_HAL_GET_WAKE_SOURCE kernel IOCTL to determine what woke the system. The active timer allows the development workstation that is in finite state to manage OS power state transitions to use the activity timer as input. It then uses that input to make a decision as to which system power state is the most appropriate to enter during the resume process. For example, the Power Manager might enter an OS power state in which the display and backlight are off. The Power Manager enters this state so that network synchronization can occur without disturbing the user.

    驱动程序可以在适当的时候重置活动定时器,而在同一时刻可能有多个驱动打开句柄来重置活动定时器事件。驱动在重置活动定时器时需要从注册表读取事件名称。OEM厂商可以对注册表进行定制,通过定制注册表,OEM厂商可以决定电源管理器如何理解驱动程序的活动。潜在的活动源包含打开句柄重置活动定时器事件的所有驱动。

    会有多个线程打开句柄手动重置活动/非活动事件并等待其确定系统状态。例如,屏幕背光驱动可以使用为活动定时器创建的一对事件来判断如何控制背光的电源及亮度。

    当系统挂起时,电源管理器重置正在活动的与活动定时器关联的手动重置事件。在系统恢复时,电源管理器会检测所有活动定时器,来判断是否是由与活动定时器关联的唤醒源引发了系统恢复。如果找到匹配项,就表明系统恢复是由其对应的唤醒源产生的活动事件引发的。

     

    4.7.5.1              活动定时器行为(Activity Timer Behavior

    各种驱动程序都可以重置活动定时器,但是重置活动定时器会导致电源管理器产生一个定时器管理线程。这会给目标设备CPU造成额外负担。为了解决这个问题,当活动事件从非活动状态变位活动状态时,电源管理器在定时器超时前不会再检测重置事件。如果在此期间产生了活动事件,电源管理器不会处理而会持续等待。如果直到定时器超时都没有重置事件,那么活动定时器会到期,同时手动重置事件的状态会改变。

     

    4.7.5.2              活动定时器超时及控制面板的电源选项(Activity Timer Time-outs and the Power Control Panel Utility

     

    活动定时器超时表示电源管理器在等待多长时间后可以判定某一活动源是非活动的。这会引发一个非活动事件。控制面板中的设置工具可以确定在保持非活动状态多长时间后,电源管理器会进行系统电源状态切换。

    活动定时器超时时间应小于系统电源状态超时时间,但应大于预期的活动时间间隔。例如,系统状态超时可能是几分钟,而用户活动定时器可能是10秒。这样可以预防在正常操作时频繁的进行活动定时器状态切换。

    控制面板的电源选项工具中列出的超时时间是累加的。也就是说,如果每个超时时间都设置为1分钟,系统会在3分钟后挂起。因为每个超时时间表示一次系统电源状态切换,而系统直到挂起会进行3次状态切换。

     

    4.7.5.3              活动定时器事件(Activity Timer Events

     

    开发者可以设置在驱动程序中活动定时器事件。电源管理器在等待定时器到期期间不会等待定时器重置事件。在活动定时器超时后,电源管理器会检测在此期间是否有重置事件被设置。如果没有设置重置事件,定时器会被认为已经到期。如果有重置事件被设置,电源管理器将在此等待定时器。电源管理器仅在定时器到期且在此期间没有产生重置事件,或在非活动期间第一次产生重置事件时更新手动重置定时器事件。

    如果驱动程序线程运行在较高优先级时,电源管理器的活动定时器线程不会运行,即使电源管理器正在等待定时器重置事件。默认情况下,活动定时器线程运行在THREAD_PRIORITY_ABOVE_NORMAL优先级,而大多数驱动程序运行在THREAD_PRIORITY_HIGHEST或更高优先级。这将导致活动定时器线程不能抢占驱动程序线程。

     

    4.7.5.4              活动定时器重置(Activity Timer Resets

    可以设置电源管理器来监测哪些应用程序正在使用socket,这比仅监测socket是否连接要好。网络协议栈并没有直接支持此功能。当然,你可以创建一个线程,周期性的循环调用GetTcpStatisticsGetUdpStatistics函数来确定是否有TCPUDP报文收发操作。如果收到或发送了报文,线程可以重置活动定时器。此线程可以实现为作为电源管理器一部分的可安装设备驱动程序;或作为某应用程序的一部分来实现。

    注意:如果本地应用程序使用socket进行进程间通讯(IPC)时,GetTcpStatisticsGetUdpStatistics函数可能会返回环回通讯数据。

     

    4.7.2、            挂起超时支持(Suspend Time-out Support

    你可能需要使WindowsCE设备处于非活动状态一段时间后进入挂起状态。可以使用以下方式进入挂起状态:

    l         GWES会维持一个依据用户输入的空闲定时器(Idle timer),并在其处于非活动状态一段时间后挂起系统。这种方法用于Windows CE .NET 4.1 之前版本。

    l         电源管理器可以根据活动定时器、输入电源及其他输入来管理系统电源状态。开发者可以定制电源管理器,使其能在你选择挂起(如开始菜单的挂起按钮)时挂起系统。

    l         可以编写一个独立的应用程序来决定什么时候挂起系统。这种情况下,GWES和电源管理器都必须配置为不对挂起状态进行管理。

    上述三种情况下,都是通过调用PowerOffSystem从而使电源管理器来挂起系统。三种情况的不同之处在于如何使系统进入挂起状态。开发者应只使用其中一种方法,以便避免GWES、电源管理器及应用程序间的冲突。

    如果电源管理器正在管理系统超时,SystemIdleTimerReset函数会通知GWES不应出现屏幕保护程序。

    4.7.6.1              GWES挂起超时(GWES Suspend Time-outs

    下表列出控制系统进入挂起状态的注册表键值。这些值以DWORD类型保存在注册表HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power键下。如果值为0,表示禁用此功能。

    注册表值名称

    默认值

    描述

    BattPowerOff

    300 (5分钟)

    表示当系统使用电池供电时,在多少秒无用户输入后会挂起系统。

    ExtPowerOff

    0 (禁用)

    表示当系统使用外接电源供电时,在多少秒无用户输入后会挂起系统。

    WakeupPowerOff

    60 (1分钟)

    表示当系统被非用户输入事件唤醒后(例如闹钟),在多少秒无活动时会挂起系统。

    ScreenPowerOff

    0 (禁用)

    GWES发送APM_POWERBROADCAST, PBT_APMUSERIDLE消息给任务栏前,多少秒无用户输入。

    为了使GWES控制挂起超时,必须使用这些注册表设置。同时必须防止电源管理器控制系统挂起状态。在示例电源管理器实现中,可以通过从注册表中移除电源管理器超时定义来实现此功能。当GWES管理系统挂起超时时,它通过调用SetSystemPowerState函数使电源管理器将系统切换到挂起状态。

     

    4.7.6.2              电源管理器挂起超时(Power Manager Suspend Time-outs

     

    示例电源管理器的实现依据系统电源、用户活动及系统活动进行挂起超时管理。示例电源管理器实现了超时可配置。由于电源管理器可以被OEM厂商定制,所以下列描述并不适用于所有Windows CE设备。OEM控制电源管理器如何、在什么时候改变系统电源状态。

    下面列出了控制电源管理器进行系统电源状态切换的注册表值:

    ACUserIdle

    ACSystemIdle

    ACSuspend

    BattUserIdle

    BattSystemIdle

    BattSuspend

    BatteryPoll

    这些DWORD值保存在HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power/Timeouts注册表键下。0值表示不会产生超时。示例电源管理器并没有提供忽略系统电源状态的方法,OEM可以选择实现此类方法。

    为了使电源管理器能更好的管理系统电源状态,这些设置必须在注册表中出现。示例电源管理器是根据ACUserIdle进行电源管理的。

    注意:为了防止GWES与电源管理器间的冲突,应禁用GWES电源管理。在电源管理器管理系统电源时,可能会限制应用程序不能进入某些系统电源状态。

    Note   To prevent conflicts between GWES and the Power Manager, you need to disable GWES power management as described previously. When the Power Manager is actively managing system power, it may restrict applications from entering arbitrary system power states.

    如果要刷新系统状态切换定时器,应创建一个名为PowerManager/ReloadActivityTimeouts的自动重置事件,并在此事件的处理过程中调用SetEvent。这样可以使电源管理器再次从注册表中读取状态切换定时器设置。

    注册表设置:

    [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power/Timeouts]

        "ACUserIdle"=dword:3c; 以秒为单位

        "ACSystemIdle"=dword:12c; 以秒为单位

        "ACSuspend"=dword:0; 以秒为单位

        "BattUserIdle"=dword:3c; 以秒为单位

        "BattSystemIdle"=dword:b4; 以秒为单位

        "BattSuspend"=dword:12c; 以秒为单位

        "BatteryPoll"=dword:1f4; 电池轮询间隔时间,以毫秒为单位

     

     

    4.7.6.3              应用程序挂起超时(Application Suspend Time-outs

    OEM厂商有可能会编写应用程序直接对系统电源状态进行管理,而这样就不需要定制电源管理器。为此,应用程序必须禁用GWES及电源管理器的电源管理功能,并自行处理电源状态切换。禁用电源管理器及GWES电源管理功能的更多信息,参见6.2 电源管理器挂起超时。

    电源管理器可能不能确定从挂起状态恢复时,应恢复到哪个电源状态。如果OEM厂商允许系统在挂起后完全恢复,那么可以不考虑这个问题。但是,如果OEM厂商需要部分唤醒系统,就可能需要修改电源管理器。

    展开全文
  • 第8章 KMDF过滤器驱动程序 1. 管理设备的主功能为功能驱动FDO, 过滤器驱动位于FDO的上层或下层 WdfFdoInitSetFilter // 声明...第9章 USB设备开发 1. USB2.0 最快480Mb/s, UBS3.0速度 5.0Gbps(500MB/s) 2. US...

    第8章 KMDF过滤器驱动程序

    1. 管理设备的主功能为功能驱动FDO, 过滤器驱动位于FDO的上层或下层

        WdfFdoInitSetFilter // 声明这个一个过滤驱动

    2. 安装要修改FDO的inf文件

    FilterSample实例

     

    第9章 USB设备开发

    1. USB2.0 最快480Mb/s, UBS3.0速度 5.0Gbps (500MB/s)

    2. USB设备有一到多个配置

        每个配置有一到多个接口

        每个接口有一到多个端点,端点是通信管道的终点, 有四种:批量(bulk), 控制,中断(interrupt),同步(Isochronous)

        1)端点0默认是可以访问的,输入和输出

        2)FDO的作用是把IRP引导到正确端点的管道上,把需求提给总线驱动,总线驱动分解成事务(transaction),送往总线

            事务有一到多个阶段(phase),phase分令牌(token),数据和握手(ack)

     

    3. USB数据传输方式

        1)控制传输:最高优先级,最大数据64B,每个控制事务包括一个SETUP令牌,带可选的数据阶段和握手阶段,设备必须响应控制传输

        2)

     (usb驱动部分待续)

     

    第10章 PCI设备驱动程序开发

    1. 微机扩展插槽有:ISA(已淘汰), PCI(即插即用,不是热插拔)

       PCI: 32位数据总线,速率132~264MB/s, 

       通用PCI总线接口:AMCC的S5933,PLX的9054。也可以用FPGA实现PCI接口

    2. 开发驱动主要有3方面问题:硬件访问,中断处理,DMA传输

        X86有两种地址空间:I/O地址(只有64KB),内存地址(4GB以上)

        I/O映射:一个芯片的地址在I/O地址空间的范围,只能通过I/O指令来访问。

        内存映射:内存指令访问

    3. I/O访问

        WRITE_PORT_UCHAR ,   WRITE_PORT_USHORT, WRITE_PORT_ULONG

        WRITE_PORT_BUFFER_UCHAR ...

    4. 存储器访问

        WRITE_REGISTER_UCHAR ...

        WRITE_REGISTER_BUFFER_UCHAR

    5. 硬件访问编程

       1) 根据配置定义地址指针,用于修改PCI9054的寄存器, MemBaseAddress0 和 IoBaseAddress0

       2)EvtDevicePrepareHardware 中初始化 MemBaseAddress0

         CmResourceTypePort IO端口 资源

         CmResourceTypeMemory

         CmResourceTypeInterrupt  

    6. 中断处理

       WDFINTERRUPT, 运行在DIRQL级别,处理时间尽可能短

       中断服务例程是异步调用的,必须考虑其他例程和中断服务例程的共享数据的保护性访问(硬件中断自旋锁,运行在DIRQL)

       WDF_INTERRUPT_CONFIG_INIT, WdfInterruptCreate

    7. DMA编程对象

       1) WDFDMAENABLER,用于建立一个DMA适配器,说明DMA通道的特性,  WdfDmaEnablerCreate

       2) WDFDMATRANSACTION, 用于传输控制, WdfDmaTransactionCreate

           启动一个DMA传输,获取传输缓冲区的物理地址和字节数,DMA传输结束后的数据处理

           函数:

           WdfDmaTransactionInitialize(EvtProgramDmaFunction): WdfDmaTransactionExecute后会调用EvtProgramDmaFunction

           WdfDmaTransactionExecute 执行DMA传输

           WdfDmaTransactionRelease 终止传输

         WdfDmaTransactionDmaCompleted 测试传输是否完成

           WdfDmaTransactionDmaCompletedFinal 强行完成DMA传输

           WdfDmaTransactionGetBytesTransferred 传输的总字节数

           WdfDmaTransactionSetMaximumLength 设置传输的最大字节数,应小于65536

       3) WDFCOMMONBUFFER,申请系统的公用缓冲区, WdfCommonBufferCreate

     

           对于DMA操作,系统提供一个特殊的内存,物理上连续的内存,称为公用缓冲区(比较稀有,避免浪费)。

           对于支持分散/聚集DMA的设备,可以不用公用缓冲区

      

    8. DMA传输编程

        DPC中,测试DMA传输完成没有,若没有,则WdfDmaTransactionExecute 继续传输

    PCI9056:

    #define INTCSR 0x68
    #define CNTRL 0x6C
    #define DMAMODE0 0x80
    #define DMAPADR0 0x84
    #define DMALADR0 0x88
    #define DMASIZ0 0x8C
    #define DMADPR0 0x90//descriptor
    #define DMACSR0 0xA8//DMA通道0 命令状态寄存器
    #define HPIC 0x00
    #define HPIA 0x04
    #define HPID 0x08

     

    第11章 UMDF驱动程序编程入门

    UMDFSample实例

    是dll程序

     

    第12章 WinDbg使用介绍

    1. windbg调试:双机调试,也可以用虚拟机代替

        目标机:启动时选择“启用调试程序”

        主控机:winDbg中kernel debugging

        windbg:debug-》break, 使主控机和目标机连接

        .reload 加载符号文件

        ld projectName  加载PDB文件

        lm l 显示已经加载符号文件列表

     

    2. 调试

        F9 在源文件中设置断点

        G  使目标机运行

        F10 执行

     

    转载于:https://www.cnblogs.com/yuanming/p/6775341.html

    展开全文
  • 本文件夹是Windows设备驱动程序WDF开发一书附带的光盘源码。可用来参考编程,亦可用于帮助调试。譬如可利用现成的驱动程序调试你编写的应用程序,以确保你编写的应用程序没问题。再用没问题的应用程序调试你编写的...
  • 博文链接:https://lijinyan3000.iteye.com/blog/187404
  • WinDriver是Jungo公司出版的一个设备驱动程序开发组件,它可以大大加速PCI设备驱动程序的开发。作者在实际的项目中采用了WinDriver来开发设备驱动程序,取得了相当好的运行效果。从目前国内的资料上来看,大多数...

    摘要

           WinDriver是Jungo公司出版的一个设备驱动程序开发组件,它可以大大加速PCI设备驱动程序的开发。作者在实际的项目中采用了WinDriver来开发设备驱动程序,取得了相当好的运行效果。从目前国内的资料上来看,大多数设计人员还是在用DDK、Wtools开发设备驱动程序,因而作者觉得有必要向大家介绍与推荐这个软件。
           WinDriver是一套设备驱动程序开发组件,它的目的就是方便Windows程序员快速开发出PCI/ISA设备的Windows驱动程序(目前最新的版本V4.32还支持PCMCIA、USB设备的驱动程序的开发,并且除了支持Windows9X/NT系统外,还有支持Unix、Windows CE的版本推出)。利用WinDriver开发设备驱动程序,不需要熟悉操作系统的内核,整个驱动程序中的所有函数都是工作在用户态下的,通过与WinDriver的.Vxd或者.Sys文件交互来达到驱动硬件的目的。由于是一个用户态程序,效率的高低也就成了人们选择WinDriver时关心的一个问题。大量实践数据表明,WinDriver并没有通过牺牲系统性能来换取驱动程序的快速开发,的确是一个“像开发用户态程序那样简单,像核心态程序那样高效的开发工具。
     


    1 WinDriver主要特征

    • 提供了从用户层访问硬件的简单方法;
    • 能够方便地将性能要求特别苛刻的部分通过Windriver提供的API插入到核心态模式运行,提高执行效率;
    • 对主流PCI接口芯片(AMCC、PLX、V3系列)提供了很好的支持;
    • 可以利用常见的软件开发平台(Visual C++、Borland C++、VB4、Java、Delphi);
    • 支持I/O、DMA、中断处理,支持PCI、ISA、EISA设备的开发;
    • 无需DDK以及核心态程序开发的经验。

    2 开发步骤

    (1)根据WinDriver的文档,建议开发步骤如下:

    • 修改代码,加入定制功能;
    • 在用户态执行与调试代码;
    • 将性能苛刻部分插入到核心态;

    (2)我们在实际编写驱动程序的过程中发现,完全用WinDriver提供API来写驱动程序比在Wizard生成的框架代码上修改更为灵活。一般来说,PCI驱动程序分成3个部分:初始化部分,对硬件资源的访问函数库、具体调用部分。其中,后面两个部分对于不同的硬件都是基本一致的。比如说,我们先后开发的基于AMCC5933与PLX9052的PCI接口卡,对于他们的硬件资源访问,用的都是WinDriver下面相同的API;两者开发的不同只在于初始化时对于硬件资源的锁定。所以只要开发出了针对一种接口芯片的系统的驱动代码后,以后一般只要修改接口芯片的ID值及一些寄存器的偏移值,就能够移植了,比每次生成不同的框架代码再改动也许要更简便。

    3 实例分析

        整个驱动程序的结构大致如下:

    • 打开WinDriver设备;
    • 查找我们要访问的PCI设备;
    • 枚举该设备的资源(内存、I/O、中断);
    • 锁定该设备的资源只能为我们所用,不能被其他程序访问;
    • 访问板上的资源;
    • 解锁资源;
    • 关闭WinDriver设备。

    以下为一段使用WinDriver开发的AMCC5933DMA的驱动代码,利用这个程序来演示WinDriver的程序结构。这个程序只要稍加修改,就可以用来作为其他PCI卡的驱动程序的一部分,例如PLX9050、9054。为了节省篇幅,省略了变量说明部分。程序中出现的变量大都由其名称可以反映含义,具体可以参见WinDriver的设计文档中的说明。

    hWD=WD_Open(); //打开WinDriver设备,每次使用前必须调用;
    pciScan.searched.dwVendorId=0x10e8; //AMCC公司供货号
    pciScan.searched.dwDeviceId=0x4750; //AMCC5933的设备号
    WD_PciScanCards (hWD,&pciSxcan); //枚举PCI槽上的设备
    pciSlot =pciScan.cardSilt[0]; //假设只有我们一个设备得到设备槽的号码
    pciCardInfo.pciSlot=pciSlot;
    WD_PciGetCardInfo(hWD,&pciCardInfo); //得到该设备槽上的设备信息
    Card=pciCardInfo.Card; //Card为一个反映PCI卡上资源的结构
    cardReg.Card=Card;
    WD_CardRegister(hWD,&cardReg); //向核心态登记,锁定卡上资源
    Item=Card.Item[2]; //将卡上的号为2的资源赋给Item
    if(Item.item==ITEM_MEMORY)
    {
    regAddr=Item.I.Mem.dwUserDirectAddr; //得到PCI卡上的内存映射到用户态的地址
    }
    Dma1.dwBytes=4*dwDWord;
    Dma1.pUserAddr=pBuffer1;
    Dma1.dwOptions=0;
    WD_DMALock(hWD,&Dma1); //锁定用于DMA的内存资源


    至此与PCI卡上的内存进行DMA传输的准备已经完成,下面只要写相应的控制字就可以启动DMA操作了。

    4 常见问题的解答

    (1)评估版本的功能限制及其解决
            评估版本除了30天的限制外,与正式版本相比还有3个限制。其中影响最大的是所有的关闭函数(DMA锁定内存的解锁,资源的关闭…)都加了延时。这样我们在做数据采集卡的驱动程序时就要注意,最好只分配一次资源。比如说做DMA操作,不要反复地锁定内存,这样会在解锁时损失效率。一个折衷的方法是锁定DMA内存后,一旦这块内存写满后,就将其中数据拷到用户态程序分配的大内存中去。
    (2)用WinDriver开的程序效率
            在使用WinDriver或者VxdTools这类工具时,大家最关心的一个问题可能就是效率问题。从实践与分析来看,WinDriver生成的驱动代码的效率相当地高。比如PCI卡的高速数据采集涉及到DMA的应用,WinDriver提供相应的API来将卡上的内存映射到用户态程序所能直接访问的地址空间中,然后直接对这个映射后得到的地址进行DMA操作。也就是说,与用DDK来直接编写驱动程序的区别就在于地址映射的操作上,在这部分工作上面,用WinDriver的API肯定没有直接用DDK写的专门面向特定硬件优化的代码来得高效。但是这部分代码实际上属于初始化工作,这部分的效率高低事实上并不会影响总体上的效率。
    实际中,用WinDriver编写的PCI驱动程序在赛扬466、64M内存的机器上,在8位模式下可以稳定地采集4~8Mbytes/s的数据。而且随着硬件设计的改变,肯定还有提高余地。
            经过实际应用,发现WinDriver这个软件使用快速,无论是开发效率还是实际达到的性能指标都相当令人满意。特别对于硬件开发人员来说,可以不必了解繁琐的操作系统的内核知识,就可以快速地开发出驱动程序,对于调试硬件是一个很好的帮助工具。

    展开全文
  • Windows 2000XP WDM设备驱动程序开发 第二版 含大部分源代码。 本资源为搜集网上的内容整理而成。一步到位。
  • Windows驱动开发

    千次阅读 2012-11-24 15:57:31
    Windows驱动开发过程中,环境搭建是最重要的一部。而标准的驱动开发环境搭建相对模糊,不具有可行性。故而本人记录下自己搭建开发环境的过程。 2、驱动开发分类  1)、Windows驱动开发分成两类。一类是设备驱动...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,527
精华内容 610
关键字:

windows设备驱动开发