zoukankan      html  css  js  c++  java
  • WinCE流设备驱动简介及GPIO驱动的实现(转载)

                                                       WinCE流设备驱动简介及GPIO驱动的实现(转载 ARM-WINCE)

    流设备驱动实际上就是导出标准的流接口函数的驱动,这是文档上面的定义。在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 SH

                ENDIF

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

    本文来自CSDN博客,转载出处:http://blog.csdn.net/nanjianhui/archive/2008/07/18/2674753.aspx

  • 相关阅读:
    单例模式
    HashSet、LinkedHashSet、SortedSet、TreeSet
    ArrayList、LinkedList、CopyOnWriteArrayList
    HashMap、Hashtable、LinkedHashMap
    andrew ng machine learning week8 非监督学习
    andrew ng machine learning week7 支持向量机
    andrew ng machine learning week6 机器学习算法理论
    andrew ng machine learning week5 神经网络
    andrew ng machine learning week4 神经网络
    vue组件监听属性变化watch方法报[Vue warn]: Method "watch" has type "object" in the component definition. Did you reference the function correctly?
  • 原文地址:https://www.cnblogs.com/sql4me/p/1716978.html
Copyright © 2011-2022 走看看