分类: 嵌入式
2010-03-29 15:23:43
l 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即可。
l DWORD XXX_Open(DWORD hDeviceContext,DWORD dwAccess, DWORD dwShareMode);
当用户程序调用CreateFile打开这个设备时,设备管理器就会调用此驱动程序的XXX_Open函数。
参数:
hDeviceContext XXX_Init 返回给上层的值,也就是我们在XXX_Init中分配的用来记录驱动程序信息的那个结构体的指针,我们可以在这个函数中直接将其转化成所定义的结构,从而获取驱动程序的信息。
dwAccess上层所要求的访问方式,可以是读或者写,或者是0,即不读也不写
dwShareMode 上层程序所请求的共享模式,可以是共享读、共享写这两个值的逻辑或,或者是0,即独占式访问。
系统层对设备文件的存取权限及共享方法已经做了处理,所以在驱动程序中对这两个参数一般可以不用理会。
这个函数一般不用做太多处理,可以直接返回hDeviceContext表示成功,对于一个不支持多个用户的硬件,在设备已经打开后,应该总是返回0以至失败,则CreateFile调用不成功。
l DWORD XXX_Close( DWORD hDeviceContext );
当用户程序调用CloseHandle关闭这个设备句柄时,这个函数就会被设备管理器调用。
参数:
hDeviceContext 为XXX_Open返回给上层的那个值。
这个函数应该做与XXX_Open相反的事情,具体包括:释放XXX_Open分配的内存,将驱动程序被打开的记数减少等。
l DWORD XXX_Deinit( DWORD hDeviceContext );
这个函数在设备被卸载时被调用,它应该实现与XXX_Init相反的操作,主要为释放前者占用的所有系统资源。
参数:
hDeviceContext XXX_Init函数返回给上层的那个句柄
l void XXX_PowerUp( DWORD hDeviceContext );
l void XXX_PowerDown(DWORD hDeviceContext );
正如其名称中体现的那样,这两个函数在系统PowerUp与PowerDown时被调用,这两个函数中不能使用任何可能引起线程切换的函数,否则会引起系统死机。所以,在这两个函数中,实际上几乎是什么做不了,一般在PowerDown时做一个标志,让驱动程序知道自已曾经被Power Down过。在Power Down/On的过程中硬件可能会掉电,所以,尽管Power On以后,原来的IO操作仍然会从接着执行,但可能会失败。这时,当我们发现一次IO操作失败是因为程序曾经进入过Power Down状态,就重新初始化一次硬件,再做同样的IO操作。
l 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赋值时应该先判断它是否为一个有效的地址