WinCE流设备驱动简介及GPIO驱动的实现

流设备驱动实际上就是导出标准的流接口函数的驱动,这是文档上面的定义。在 WinCE 中,所有的流设备都导出流设备接口,这样 WinCE 中的 Device Manager 可以加载和管理这些流设备驱动。

首先我声明一下,这个图是我抄的,呵呵。在 WinCE 启动的时候, OAL(OAL.exe) 首先加载 kernel.dll ,然后 kernel.dll 加载 device.dll device.dll 会加载 devmgr.dll devmgr.dll 实际上就是 Device Manager 模块,他会负责流设备的加载,卸载和交互操作。这个从图中可以看出的。

再来说说应用程序,一般应用程序要通过文件系统接口来访问设备。首先调用 CreateFile 打开设备并获得相应的句柄,然后通过文件系统接口调用 ReadFile 或者 WriteFile 来访问相应的流设备驱动,或者通过 DeviceIoControl 直接访问。无论哪种方式,都是要通过 Device Manager 才能访问到相应的设备驱动,如上图。

 

 

不知道上面的架构解释清楚了没有,下面介绍一下流设备驱动的接口函数:

 

1.    DWORD XXX_Init(LPCTSTR pContext, DWORD dwBusContext)

该函数用于初始化一个流设备驱动,在设备被加载的时候调用,调用成功后会返回一个句柄。






               


pContext


:在





Active


注册表键路径下的一个字符串






               


dwBusContext


:不常用,这里可以设为





0


 


2. BOOL XXX_Deinit(DWORD hDeviceContext)












    





卸载一个设备驱动。






              hDeviceContext :设备驱动的句柄,在 XXX_Init 调用时返回的

 

3.


 


DWORD XXX_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode)












       打开一个设备。

              hDeviceContext :设备驱动的句柄,在 XXX_Init 调用时返回的

              AccessCode :访问权限代码,一般是只读或者只写或者读写

              ShareMode :共享模式,是否支持共享或者独享

 

4. BOOL XXX_Close(DWORD hOpenContext)

       关闭一个设备。

              hDeviceContext :设备驱动的句柄,在 XXX_Open 调用时返回的

 

5. DWORD XXX_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)

       从设备上面读取数据。

              hDeviceContext :设备驱动的句柄,在 XXX_Open 调用时返回的

              pBuffer :存放数据的 Buffer

              Count :读取数据的字节数

 

6. DWORD XXX_Write(DWORD hOpenContext, LPCVOID pBuffer, DWORD Count)

       写数据到设备上面。

              hDeviceContext :设备驱动的句柄,在 XXX_Open 调用时返回的

              pBuffer :存放数据的 Buffer

              Count :写入数据的字节数

 

7. DWORD XXX_Seek(DWORD hOpenContext, long Amount, WORD Type)

       移动设备中的数据指针。

              hDeviceContext :设备驱动的句柄,在 XXX_Open 调用时返回的

              Amount :移动的字节数

              Type FILE_BEGIN 表示从头移动

                       FILE_CURRENT 表示从当前位置移动

                       FILE_END 表示从末尾往前移动

 

8. void XXX_PowerUp(DWORD hOpenContext)

       打开设备电源。

              hDeviceContext :设备驱动的句柄,在 XXX_Open 调用时返回的

 

9. void XXX_PowerDown(DWORD hOpenContext)

       关闭设备电源。

              hDeviceContext :设备驱动的句柄,在 XXX_Open 调用时返回的

 

10. BOOL XXX_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut)

       设备 IO 控制操作函数。

              hDeviceContext :设备驱动的句柄,在 XXX_Open 调用时返回的

              dwCode :操作码

              pBufIn :输入 Buffer

              dwLenIn :输入 Buffer size

              pBufOut :输出 Buffer

              dwLenOut :输出 Buffer size

              pdwActualOut :实际输出的字节数

 

11. BOOL XXX_PreClose(DWORD hOpenContext)

       标记一个正要关闭的句柄为无效,并唤醒所有正在休眠的线程

              hDeviceContext :设备驱动的句柄,在 XXX_Init 调用时返回的

 

12. BOOL XXX_PreDeinit(DWORD hDeviceContext)

       标记一个设备实例为无效,并唤醒所有休眠的线程

              hDeviceContext :设备驱动的句柄,在 XXX_Init 调用时返回的

 

 

       上面这些函数就是流设备驱动的所有接口函数,理解起来应该不难。下面介绍一个实际的流设备驱动的例子,是基于 WinCE6.0 ( WinCE5.0 比一些配置文件稍有不同 ) 。这里介绍的是一个操作 GPIO 的流设备驱动并介绍具体添加流设备驱动的步骤:

 

(1) 更改 BSP 工程文件,添加 GPIO 驱动的选项:

       BSP 目录下面的 ”CATALOG” 文件夹下面找到 ”BspName.pbcxml” 并用记事本打开,然后添加 GPIO 驱动的选项,首先找到 <BSP>…</BSP> 并在里面添加下面一行:

           <BspItemId>Item:Cirrus Logic:bsp_ep94xx_gpio_ep9407_EP94xx</BspItemId>

       然后在 < CatalogFile >…</CatalogFile> 中添加下面的驱动描述:

      <Item Id="Item:Cirrus Logic:bsp_ep94xx_gpio_ep9407_EP94xx">

           <Title>GPIO</Title>

           <Description>GPIO Driver</Description>

           <Type>BspSpecific</Type>

           <Variable>BSP_EP94XX_GPIO</Variable>

           <Location>Device Drivers</Location>

           <SourceCode>

                 <Title>$(_WINCEROOT)/PLATFORM/EP94XX/SRC/DRIVERS/gpio</Title>

                 <Path>$(_WINCEROOT)/PLATFORM/EP94XX/SRC/DRIVERS/gpio</Path>

           </SourceCode>

      </Item>

       上面实际上添加了 GPIO 驱动,环境变量为 BSP_EP94XX_GPIO ,源代码位于路径 ”/Platform/EP94XX/SRC/DRIVERS/gpio” 下面。

 

(2) 创建 GPIO 驱动文件夹并更改 dir 文件:

       进入 ”/Platform/EP94XX/SRC/DRIVERS/” 目录,创建一个名为 ”gpio” 的文件夹,这个文件夹包含 GPIO 驱动。然后打开 dirs 文件,在末尾添加 ”gpio”

 

(3) 开发 GPIO 驱动:

       进入 ”/Platform/EP94XX/SRC/Drivers/gpio” 并创建 gpio.c 文件,在文件中封装相应的流设备接口函数,如下:

                                   GPI_Init(..)

                                   GPI_DeInit(..)

                                   GPI_Read(..)

                                   GPI_Write(..)

                                   …

       可以在 GPI_Read 函数中读取 GPIO 的状态,在 GPI_Write 函数中设置 GPIO 的状态,当然也可以通过 GPI_IoControl 函数来实现。

       然后在该路径下面创建 makefile 文件,并在里面包含下面一行就可以了:

              !INCLUDE $(_MAKEENVROOT)/makefile.def

       接下来创建模块导出文件 gpio.def ,具体内容如下:

              LIBRARY     GPIO_LIB

EXPORTS

                  DllEntry

                  GPI_Init

                  GPI_Deinit

                  GPI_Open

                  GPI_Close

                  GPI_Read

                  GPI_Write

                  GPI_Seek

                  GPI_IOControl

                  GPI_PowerDown

                  GPI_PowerUp

       最后创建用于编译的 sources 文件,具体内容如下:

       !ifndef BSP_EP94XX_GPIO

SKIPBUILD=1

!endif

 

TARGETNAME=gpio

RELEASETYPE=PLATFORM

TARGETTYPE=DYNLINK

TARGETLIBS= /

               $(_SYSGENSDKROOT)/lib/$(_CPUINDPATH)/coredll.lib

 

DLLENTRY=DllEntry

SOURCES= gpio.c

 

(4) 添加 GPIO 驱动的注册表配置:

       打开 ”/PLATFORM/EP94XX/files/” 目录下的 platform.reg 文件,添加下面的配置:

       IF BSP_EP94XX_GPIO

            ; Add these entries to your registry to enable the gpio device

            [HKEY_LOCAL_MACHINE/Drivers/BuiltIn/GPIO]

            prefix"="GPI"

            "Dll"="gpio.dll"

            "Order"=dword:1

            ENDIF

 

(5) 添加驱动模块到 NK

       打开 ”/PLATFORM/EP94XX/files/” 目录下的 platform.bib 文件,添加如下内容:

            IF BSP_EP94XX_GPIO

                gpio.dll  $(_FLATRELEASEDIR)/gpio.dll                  NK SHK

            ENDIF

 

 

       应该就这些了。上面的例子是我在项目中实际做过的,当时有个客户想通过应用程序直接操作 GPIO ,所以我就给他们写了这个驱动。只要具备一些 WinCE BSP 的基础知识,看懂上面的内容应该很简单。由于是我做过的项目,所以上面的一些路径,名称等设置都是基于我所使用的 BSP 的,仅供大家参考。

 

 原文地址 http://blog.csdn.net/nanjianhui/archive/2008/07/18/2674753.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值