设备管理器和流式接口设备驱动程序
一 串口驱动程序是典型的流式接口设备驱动程序
串口是典型的流式设备。在使用串口时,二进制数据像流水一样,从一台设备经过串口流到另外一台设备,这样的设备在windows CE中称为流式设备。
在windows CE中使用流式接口驱动程序管理流式设备。流式接口设备驱动程序,就是向设备管理器暴露流式接口函数的驱动程序。在流式接口驱动程序中,驱动程序把外设抽象成一个文件,而应用程序则使用普通的文件API函数来对流式设备进行访问。
二 设备管理器以总线枚举方式加载流式接口的设备驱动程序
在windwos CE6.0版本起,设备管理器不再是单独的用户态进程device.exe,而只是操作系统内核进程中的一个动态链接库device.dll。
设备管理器具有以下几项职能:
(1)设备管理器负责将动态链接库形式的设备驱动程序加载到自己所在的进程的地址空间中。Device.dll本身运行在内核进程nk.exe中,所以加载的设备驱动程序也运行内核进程中。这是windows CE 6.0和windows CE 5.0以前版本的重大区别。
(2)在系统启动和即插即用设备连接上来时负责加载和初始化驱动程序,在外设不再使用时卸载驱动程序。
(3)管理外设的状态,当有特定的事件发生时根据用户的设定对应用程序发出通知。
(4)统一管理可分配给外设使用的内存和I/O端口地址空间资源。
(5)提供对外设的电源管理的接口。
设备管理器加载设备驱动程序是按照这样的方式进行的:首先设备管理器执行自身的初始化,然后初始化资源管理器和电源管理器,最后设备管理器根据注册表的设置,加载总线枚举器busenum.dll,有总线枚举器负责加载和初始化设备驱动程序。在windows CE注册表的[HKEY_LOCAL_MACHINE/Drivers/BuiltIn]注册表键下存放有总线枚举器的相关内容。,而这个注册表键值下的各个子键就用于存放要被加载的各设备驱动程序的配置数据,用总线枚举器负责一一加载并初始化各个子键下的设备驱动程序。因而可以将总线枚举器看成一个特殊的总线的设备驱动程序。
可以设想,在基于windows CE的嵌入式硬件上,存在一个大的虚拟总线,嵌入式系统中的所有外设都连接在这个虚拟总线上。这里的总线枚举器busenum.dll就是这个虚拟总线的设备驱动程序。
三 总线枚举器加载一个设备驱动程序的具体步骤
总线枚举器加载一个设备驱动程序按照以下几个步骤进行:
(1) 总线枚举器被设备管理器加载并且完成自身的初始化后,开始枚举自己对应的注册表键的各个子键,从中寻找合法的设备驱动程序。
(2) 总线枚举器从[HKEY_LOCAL_MACHINE/Drivers/BuiltIn]注册表键的各个子键中寻找名为dll的键值,合法的键值是设备驱动程序的动态链接库文件名字符串,也是总线枚举器要加载的可执行文件。
(3) 总线枚举器调用ActivateDevcieEx函数,执行加载第二步中获取的设备驱动的动态链接库到自己所在的进程地址空间,也就是nk.exe系统内核进程。
(4) 总线枚举器要在注册键[HKEY_LOCAL_MACHINE/Drivers/Active]下为刚加载的驱动程序生成一个子键。后文称这个注册表子键为设备驱动程序的Active注册表键。由总线枚举器加载的设备驱动程序的Active注册表键中的各表项主要是被夹在过程中即期产生的动态数据。
(5) 总线枚举器调用设备驱动程序的初始化函数Init,这个函数必定有一个参数是上一步产生的设备驱动的Active注册表键的字符串指针。
(6) 由设备驱动程序的Init函数执行最基本的硬件初始化工作,包括:为设备设定一个初始工作状态,将设备的内存缓冲区和I/O端口映射到系统的虚拟地址等。