【流接口驱动】流接口设备驱动的架构
WinCE提供了四种设备模型,其中两种是专门用于WinCE的模型,另外两种外部模型来自其他的操作系统。基于WinCE的两种模型是 本机的设备驱动程序和流接口的驱动程序。两种外部模型用于通用串行总线(USB)和网络驱动器接口标准(NDIS)驱动程序。其中流接口驱动程序是为连接到基于WjnCE平台的外围设备而设计的,这些外围设备包括SD卡、摄像头、打印机等。
在WinCE中,最简单的一个驱动程序莫过于一个内置(Built-in)设备的流接口驱动。对于一个不支持热拔插的设备,最快捷的方法就是为其实现一个内置的流接口的驱动。
对于这样一类驱动程序,我们只需要按一种特定的规则实现一个动态库,其中实现对所有的硬件功能的调用,再将这个动态库加入系统中,然后设置相关的注册表项,使得在系统启动时设备管理器能识别并且加载这个设备即可.
1 流接口驱动体系结构
流驱动将设备抽象为文件进行操作,它体系结构如图1所示。应用程序使用文件API对设备进行访问,文件API被操作系统转发到FileSys.exe进程中;然后FileSys.exe发现是对设备进行操作,就会把执行交给设备管理器;接着设备管理器根据具体的请求,调用不同的流接口驱动程序中暴露的接口;最终驱动程序负责与硬件交互。
1 流接口驱动体系结构
流驱动将设备抽象为文件进行操作,它体系结构如图1所示。应用程序使用文件API对设备进行访问,文件API被操作系统转发到FileSys.exe进程中;然后FileSys.exe发现是对设备进行操作,就会把执行交给设备管理器;接着设备管理器根据具体的请求,调用不同的流接口驱动程序中暴露的接口;最终驱动程序负责与硬件交互。
流式驱动程序的工作过程(1)。
答:第一步:加载驱动程序,主要有两种加载方式:(1)当系统启动时,设备管理器搜寻注册表的HKEY_LOCAL_MACHINE\Drivers\BuiltIn键下面的子键,并逐一加载该子键下的每一个驱动,此过程称为BusEnum;(2)应用程序可调用ActivateDeviceEx()函数动态地加载驱动程序。
第二步:设备管理器从注册表的dll键值中获取驱动程序所在的DLL文件名。
第三步:设备管理器调用LoadDriver()函数把该DLL加载到自己的虚拟地址空间中。
第四步:设备管理器在注册表的HKEY_LOCAL_MACHINE\Drivers\Active下,记录所有已经加载的驱动程序。
第五步:设备管理器调用驱动程序中的COM_Init函数,并把上一步中添加的注册表项的完整路径作为COM_Init函数的第1个参数传入驱动程序内。
第六步:在COM_Init中,通常须对硬件进行一些最基本的初始化操作。
通过以上的操作完成流式驱动程序的加载任务。
对驱动程序的操作:
第一步:应用程序使用该设备。首先,应用程序调用CreateFile(TEXT(“COM1”)….)打开设备。然后,文件系统判断打开的是文件还是设备。最后,如果打开的是设备,就将控制权交回设备管理器。
第二步:设备管理器调用驱动程序的COM_Open()函数打开设备。
第三步:COM_Open()函数把打开设备的结果返回给设备管理器。
第四步:设备管理器把SMP_open()的返回结果,返回给应用程序的CreateFile()函数调用。
通过第七步到第十步,设备已被成功打开,接下来可对设备进行读/写和控制操作。下面将以从设备中读取数据为例。
第一步:应用程序使用CreateFile()调用返回的句柄,调用函数ReadFile(),向设备发送读请求。
第二步:设备管理器调用驱动程序的COM_Read()函数,读取设备的数据信息。在此过程中,COM_Read()函数可与硬件交互,从硬件中读取必要的信息。然后返回给设备管理器,再返回给应用程序。
最后,当应用程序不再使用该设备时,它可调用CloseHandle()将设备关闭。
工作过程及打开驱动程序示例:http://wenku.baidu.com/view/0f08030790c69ec3d5bb75bd.html
流驱动的工作顺序如下(2):
1)加载驱动。在当系统启动时,设备管理器搜寻注册表的HKEY_LOCAL_MACHINE\Driver\BuiltIn键下面的子键,并逐一加载子键下的每个驱动,此过程叫BusEnum。
2)设备管理器从注册表的dll键值中获取驱动程序所在的DLL文件名。
3)设备管理器调用LoadDriver()函数把DLL加载到自己的虚拟地址空间内。
4)设备管理器在注册表的HKEY_LOCAL_MACHINE\Driver\Active下面,记录所有已经加载的驱动程序[2]。
5)设备管理器调用驱动中的XXX_Init()函数。
6)在XXX_Init()中,通常对硬件进行一些基本的初始化操作。通过以上6步,流接口驱动被成功加载。
7)应用程序使用该设备。首先它调用CreateFile()打开设备。CreateFile()是在FileSys.exe中实现的。但是FileSys.exe只作简单判断,如果发现打开的设备驱动程序而不是一个文件,那么就重新把主动权交还给设备管理器。
8)设备管理器调用驱动程序中的XXX_Open()函数打开设备。在XXX_Open()中,驱动程序可能会对硬件进行一些额外的初始化工作,使硬件进入工作状态。
9)XXX_Open()函数把打开设备的结果返回给设备管理器。
10)设备管理器把XXX_Open()返回的结果,再返回给应用程序的CreateFile()函数调用。通过7-10步,设备已被成功打开,至此就可以对设备进行读写和控制操作。
11)应用程序使用第7步CreateFile()函数返回的句柄作为 ReadFile() / WriteFile()的第一个参数,向设备发送读请求。同样ReadFile() / WriteFile()要经过FileSys.exe转发给设备管理器。
12)设备管理器调用驱动程序中的XXX_Read() / XXX_Write() 函数,读取设备的数据信息或向设备写信息。
13)在流驱动程序中,XXX_Read() / XXX_Write() 函数可与硬件交互,从硬件中读取必要的信息或向硬件写必要的信息。然后返回给设备管理器,再返回给应用程序。
当应用程序不再使用该设备时,它可调用CloseHandle()将设备关闭。当系统不再使用设备时,应用程序可调用DeactivateDevice()函数把该驱动程序卸载。
原文更多:http://space.itpub.net/13771794/viewspace-515899
2.流接口驱动的实现
(1)流接口驱动的入口点
流接口驱动的入口点主要包括XXX_Init、XXX_Deinit、XXX_Open、XXX_Close、XXX_Read、XXX_Write、XXX_Seek、XXX_PowerUp、XXX_PowerDown和XXX_IOControl,其中XXX是在驱动程序注册表里定义的设备前缀。
(2)单访问和多访问
生成一个流接口驱动程序的时候,由于外围设备是以特殊文件形式供应用程序使用的,因此很容易出现多个应用程序同时访问同一个设备的情况。这时要考虑用户驱动程序对它的服务设备是否有多次打开文件处理的功能。
在WinCE中一个流接口驱动程序可以通过使用hOpenContext参数来实现单访问和多访问。如果是实现单访问,则第一次对XXX_Open的调用返回一个合法值,保持该值的合法性,后来的调用都返回空值;若是实现多访问,对于XXX_Open的调用每次都返回不同的值。
3.流接口函数
流接口函数也称作流接口驱动的入口点,下表对流接口函数进行了总结:http://www.cnblogs.com/Logen1010/archive/2011/03/23/1992661.html
套接口有三种类型:流式套接口,数据报套接口及原始套接口.
流式套接口定义了一种可靠的面向连接的服务,实现了无差错无重复的顺序数据传输.数据报套接口定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证可靠,无差错.原始套接口允许对低层协议如IP或ICMP直接访问,主要用于新的网络协议实现的测试等.
无连接服务器一般都是面向事务处理的,一个请求一个应答就完成了客户程序与服务程序之间的相互作用。若使用无连接的套接口编程。
套接口工作过程如下:服务器首先启动,通过调用socket()建立一个套接口,然后调用bind()将该套接口和本地网络地址联系在一起,再调用listen()使套接口做好侦听的准备,并规定它的请求队列的长度,之后就调用accept()来接收连接.客户在建立套接口后就可调用connect()和服务器建立连接.连接一旦建立,客户机和服务器之间就可以通过调用read()和write()来发送和接收数据.最后,待数据传送结束后,双方调用close()关闭套接口.