对于这样一类驱动程序,我们只需要按一种特定的规则实现一个动态库,其中实现对所有的硬件功能的调用,再将这个动态库加入系统中,然后设置相关的注册表项,使得在系统启动时设备管理器能识别并且加载这个设备即可。
1. 实现动态链接库
此动态链接库与应用程序层所用的库并不很大差别,源文件可以是C、C++、甚至汇编,只是它要实现以下函数。
DllEntry(HINSTANCE DllInstance, INT Reason, LPVOID Reserved )
这个函数是动态链接库的入口,每个动态链接库都需要输出这个函数,它只在动态库被加载和卸载时被调用,也就是设备管理器调用LoadLibrary而引起它被装入内存和调用UnloadLibrary将其从内存释放时被调用,因而它是每个动态链接库最早被调用的函数,一般用它做一些全局变量的初始化。
参数:
DllInstance:DLL的句柄,与一个EXE文件的句柄功能类似,一般可以通过它在得到DLL中的一些资源,例如对话框,除此之外一般没什么用处。
Reason:
一般我们只关心两个值:DLL_PROCESS_ATTACH与DLL_PROCESS_DETACH,Reason等于前者是动态库被加载,等于后者是动态库被释放。
所以,我们可以在Reason等于前者是初始化一些资源,等于后者时将其释放。
DWORD XXX_Init( LPCTSTR pContext, LPCVOID lpvBusContext);
它是驱动程序的动态库被成功装载以后第一个被调用的函数。其调用时间仅次与DllEntry,而且,当一个库用来生成多于一个的驱动程序实例时仅调用一次DllEntry,而xxx_Init会被调用多次。驱动程序应当在这个函数中初始化硬件,如果初始化成功,就分配一个自已的内存空间(通常用结构体表示),将自已的状态保存起来,并且将此内存块的地址做为一个DWORD值返回给上层。设备管理器就会用在调用XXX_Open时将此句柄传回,我们就能访问自已的状态。如果初始化失败,则返回0以通知这个驱动程序没有成功加载,先前所分配的系统资源应该全部释放,此程序的生命即告终至。
当这个函数成功返回,设备管理器对这个程序就不做进一步处理,除非它设置了更多的特性。至此一个各为XXX的设备就已经加载成功,当用户程序调用CreateFile来打开这个设备时,设备管理器就会调XXX_Open函数。
参数:
pContext:系统传入的注册表键,通过它可以讲到我们在注册表中设置的配置信息。
lpvBusContext:一般不用。
实际上,很多程序中将这个函数写成了DWORD XXX_Init( DWORD pContext ),我们只需要将pContext转化成LPCTSTR即可。
DWORD XXX_Open(DWORD hDeviceContext,DWORD dwAccess, DWORD dwShareMode);
当用户程序调用CreateFile打开这个设备时,设备管理器就会调用此驱动程序的XXX_Open函数。
参数:
hDeviceContext XXX_Init 返回给上层的值,也就是我们在XXX_Init中分配的用来记录驱动程序信息的那个结构体的指针,我们可以在这个函数中直接将其转化成所定义的结构,从而获取驱动程序的信息。
dwAccess 上层所要求的访问方式,可以是读或者写,或者是0,即不读也不写。
dwShareMode 上层程序所请求的共享模式,可以是共享读、共享写这两个值的逻辑或,或者是0,即独占式访问。
系统层对设备文件的存取权限及共享方法已经做了处理,所以在驱动程序中对这两个参数一般可以不用理会。
这个函数一般不用做太多处理,可以直接返回hDeviceContext表示成功,对于一个不支持多个用户的硬件,在设备已经打开后,应该总是返回0以至失败,则CreateFile调用不成功。
DWORD XXX_Close( DWORD hDeviceContext );
当用户程序调用CloseHandle关闭这个设备句柄时,这个函数就会被设备管理器调用。
参数:
hDeviceContext 为XXX_Open返回给上层的那个值。
这个函数应该做与XXX_Open相反的事情,具体包括:释放XXX_Open分配的内存,将驱动程序被打开的记数减少等。
DWORD XXX_Deinit( DWORD hDeviceContext );
这个函数在设备被卸载时被调用,它应该实现与XXX_Init相反的操作,主要为释放前者占用的所有系统资源。
参数:
hDeviceContext XXX_Init函数返回给上层的那个句柄
void XXX_PowerUp( DWORD hDeviceContext );
void XXX_PowerDown(DWORD hDeviceContext );
正如其名称中体现的那样,这两个函数在系统PowerUp与PowerDown时被调用,这两个函数中不能使用任何可能引起线程切换的函数,否则会引起系统死机。所以,在这两个函数中,实际上几乎是什么做不了,一般在PowerDown时做一个标志,让驱动程序知道自已曾经被Power Down过。在Power Down/On的过程中硬件可能会掉电,所以,尽管Power On以后,原来的IO操作仍然会从接着执行,但可能会失败。这时,当我们发现一次IO操作失败是因为程序曾经进入过Power Down状态,就重新初始化一次硬件,再做同样的IO操作。
BOOL XXX_IOControl(
DWORD hDeviceContext,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut
);
几乎可以说一个驱动程序的所有功能都可以在这个函数中实现。对于一类CE自身已经支持的设备,它们已经被定义了一套IO操作定,我们只需按照各类设备已经定义的内容去实现所有的IO操作。但当我们实现一个自定义的设备时,我们就可以随心所欲定义我们自已的IO操作。
参数:
hDeviceContext XXX_Open返回给上层的那个句柄,即我们自已定义的,用来存放程序所有信息的一个结构。
dwCode IO操作码,如果是CE已经支持的设备类,就用它已经定义好码值,否则就可以自已定义。
pBufIn 传入的Buffer,每个IO操作码都会定义自已的Buffer结构
dwLenIn pBufIn以字节记的大小
pBufOut,dwLenOut分别为传出的Buffer,及其以字节记的大小
pdwActualOut 驱动程序实际在pBufOut中填入的数据以字节记的大小
其中,前两个参数是必须的,其它的任何一个都有可能是NULL或0。所以,当给pdwActualOut赋值时应该先判断它是否为一个有效的地址。
2. 注册表的设置
系统启动时启动设备管理程序,设备管理程序读取HKEY_LOCAL_MACHINE\Drivers\BuiltIn键的内容并加载已列出的流接口驱动程序。因此注册表对于驱动的加载有着关键作用。下面我们以设备名是“STR”来举一个例子:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\STR]
"Prefix"="STR"
"Dll"="MyDev.Dll"
"Order"=dword:1
其中 "Prefix"="STR" 表示流接口的前缀,我们以后可以通过Creatfile 函数来实现对这个流接口的操作,实现如下:HANDLE hStr = CreateFile(TEXT("str1:"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0) 。其中“str1:”中的表示设备好“1”是必需的,不管你的设备当中是不是刚好只有一个,不然的话会出现打开不了这个设备的情况。
"Dll"="MyDev.Dll" 指的是“STR”设备调用的驱动程序 DLL。
HKEY_LOCAL_MACHINE\Drivers\BuiltIn\SampleDev 表示该注册表存在于CE系统注册表的 HKEY_LOCAL_MACHINE\Drivers\BuiltIn\SampleDev 目录下。
3. 创建Makefile和Sources和.def文件
这三个文件主要是来控制编译的,Makefile 和 .def 文件实现比较简单,Sources 文件相对比较复杂。
Makefile 只需要这样一行!INCLUDE $(_MAKEENVROOT)\makefile.def ,具体的实现什么任务还不知道。
.def 文件定义需要输出的函数,这些函数能够被其它代码用动态加载的方法调用。
Sources 这个文件很重要,内容也多,最基本的一个文件该有如下内容。
TARGETNAME=MyDev(指定要生成的动态库的名称)TARGETTYPE=DYNLINK(指定要生成的是一个动态库)
TARGETLIBS=$(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib \
$(_COMMONOAKROOT)\lib\$(_CPUINDPATH)\ceddk.lib
(下面两项指定需要与哪些动态库链接,一般要第一项就足够了)
DLLENTRY=DllEntry(指定动态库的入口函数)
SOURCES= (请在这写上你所有源文件的名字,它们将会被编译)
相关推荐
**WinCe流驱动精灵**是专为在Windows CE操作系统环境下进行程序开发的人员设计的一款工具。Windows CE,作为微软推出的嵌入式操作系统,广泛应用于各种设备,如掌上电脑、工业控制设备等。在开发过程中,驱动程序的...
本文将基于给定的文件信息,详细介绍Wince流驱动的基本构成及其各个组成部分的功能。 #### 二、流驱动框架概述 流驱动是Wince系统中最常见的一种驱动类型,用于处理设备的输入输出操作。在Wince 6.0中,一个典型的...
### WinCE流驱动程序设计概述 #### 一、引言 Windows CE(简称WinCE)是由微软公司开发的一款面向嵌入式领域的操作系统。WinCE因其轻量级、灵活性高而被广泛应用于移动设备如手机、PDA、平板电脑以及工业控制等...
《深入解析WinCE流驱动源代码》 WinCE操作系统,全称为Windows Embedded Compact,是微软公司推出的一种嵌入式操作系统,广泛应用于各种嵌入式设备。在WinCE系统中,驱动程序是硬件与操作系统之间的桥梁,它使得...
3. **流类驱动和功能驱动**:流驱动通常分为两类,流类驱动(Class Driver)和功能驱动(Function Driver)。流类驱动提供了标准的用户接口,而功能驱动则直接与硬件交互,实现具体的设备功能。 4. **注册驱动**:...
本文将深入探讨动态加载WinCE流驱动的原理、步骤及调试助手的使用。 首先,理解WinCE流驱动的概念。流驱动是一种为I/O设备提供服务的软件组件,它们处理设备的数据传输,并通过标准的接口与系统通信。在WinCE中,流...
本文将主要基于"WinCE流驱动程序设计概述"这一主题,结合相关资料,详细阐述WinCE流驱动的基本概念、结构以及设计流程。 首先,我们需要了解什么是流驱动。流驱动是Windows CE中的一种驱动模型,它基于Microsoft的...
本文将深入探讨“wince流驱动举例——点灯”这一主题,主要涉及流驱动的基本概念、AU1200主板的硬件特性以及如何通过编程实现LED灯的控制。 首先,流驱动是操作系统内核与硬件设备之间通信的一种机制,它允许应用...
本文将详细解析Wince流驱动的编写实例,并基于提供的资源进行讲解。 1. **流驱动概念**: Windows CE的流驱动是设备驱动的一种,它为上层应用程序提供了一种标准I/O接口,类似于POSIX的`read()`和`write()`函数。...
"WinCE流接口驱动模板"提供了一种便捷的方式,帮助开发者快速构建自己的驱动程序,无需从零开始设计整个驱动框架。这个模板包含了必要的注册表配置和BIB(Build Information Block)文件,确保驱动程序能够在系统中...
WinCE驱动程序设计有其独特之处,主要围绕两个模型展开:本机驱动程序和流接口驱动程序。 首先,WinCE中的所有驱动程序都是动态链接库(DLL),这意味着它们可以在运行时被加载和卸载。这种设计提供了更大的灵活性,...
本文将深入探讨WINCE流驱动的开发,帮助初学者逐步理解这一领域。 一、流驱动基础概念 1. 流驱动是一种特殊的驱动程序,它遵循微软的通用I/O模型,为应用程序提供类似于标准C库中的文件操作接口,如`read`、`write`...
本篇将深入探讨"WinCE USB Video Camera SRC流驱动"的相关知识点,以及如何在Wince下实现对UVC(USB Video Class)相机的支持。 首先,UVC是一种USB设备类标准,定义了视频设备与主机之间的通信协议。它广泛应用于...
流接口驱动程序设计成动态链接库(DLL)的形式,由设备管理器统一管理,提供固定的入口点函数,使得WinCE的文件系统可以通过这些函数与驱动进行通信,进而实现应用程序对硬件的操作。 1. 工作机制 流接口驱动程序...
在Windows CE(简称WinCE)操作系统中,背光驱动程序是一个关键组件,它负责控制设备的显示屏背光亮度。在嵌入式系统中,尤其是在移动设备如PDA、智能手机或车载信息娱乐系统中,背光驱动是用户体验的重要部分,因为...
Wince 6.0 开发环境搭建及流驱动开发的2种方法 一、Wince 6.0 开发环境搭建 Wince 6.0 开发环境搭建是指在 Windows 操作系统上安装和配置Visual Studio 2005、Windows Embedded CE 6.0、Windows Embedded CE 6.0 ...
设备驱动程序的开发需要了解 WINCE 操作系统的相关技术,如 Windows CE 系统服务、流驱动接口、设备驱动程序架构等。同时,开发者也需要了解硬件设备的相关特性和规格说明,以便正确地编写设备驱动程序。 在 WINCE ...
WinCE USB驱动开发是针对基于ARM架构的嵌入式系统,特别是涉及到USB WiFi(Wlan 802.11b)无线网卡的驱动程序。在Windows CE系统中,驱动开发是确保硬件设备能够正常工作的关键部分。下面将详细讨论WinCE驱动的基本...