Windows CE下驱动开发基础

这是我从1月6日开始主持天极网论坛嵌入式开发版以来第一次发表文章,加上以前琐碎的文章共计30篇。研究的越多就越感觉自己懂的太少,其实在驱动开发方面我还是个菜鸟,我是想再次抛砖引玉,让做驱动有N年经验的人奉献一点出来,让大家减少一些研究驱动源码而又缺少注释所带来的痛苦。

我想即使读者看过微软的关于驱动开发的培训教材和CE帮助文档中的驱动部分,头脑中仍然一片茫然。要想真正了解驱动程序必须结合一些驱动程序源码,在此我以串口驱动程序(COM16550)中初始化过程为线索简单讲一讲驱动开发的基础知识。

Windows CE下的串口驱动程序能够处理所有I/O行为类似串口的设备,包括基于16450、16550 UART(通用异步收发芯片)的设备和一些采用DMA的设备,常见的有9针串口、红外I/O口、Modem等。在%_WINCEROOT%\Public\Common\OAK\Drivers\Serial目录下,COM_MDD2子目录包含新的串口驱动MDD层函数代码。COM16550子目录包含串口驱动PDD层代码。SER16550子目录包含的一系列函数专用于控制与16550兼容的UART,这样PDD层的主要工作就是调用SER16550中的函数。还有一个ISR16550子目录包含的是串口驱动程序专用的可安装ISR(中断服务例程),而很多硬件设备驱动程序采用CE默认的可安装ISR giisr.dll。一般串口设备相应的注册表设置例子及意义如下:

意义
"SysIntr"=dword:13 串口1的中断ID为十进制13
"IoBase"=dword:02F8 串口1的IO空间首地址为十六进制2F8
"IoLen"=dword:8 串口1的IO空间长度为8个字节
"DeviceArrayIndex"=dword:0 串口1的索引,是1的由来
"Order"=dword:0 串口1驱动的加载顺序
"DeviceType"=dword:0 串口1的设备类型
"DevConfig"=hex: 10,00 .... 串口1在与Modem设备通讯时的配置,如波特率、奇偶校检等
"FriendlyName"="COM1:" 串口1在拨号程序中显示的名字
"Tsp"="Unimodem.dll" 串口1 被用于与Modem设备通讯的时候要加载的TSP(TAPI Service provider)DLL
"Prefix"="COM" 串口1的流接口的前缀
"Dll"="com16550.Dll" 串口1的驱动程序DLL

SysIntr由CE在文件Nkintr.h中预定义,用于唯一标识中断设备。OEM可以在文件Oalintr.h中定义自己的SysIntr。常见的预定义SysIntr有SYSINTR_NOP(中断只由ISR处理,IST不再处理),SYSINTR_RESCHED(重新调度线程),SYSINTR_DEVICES(由CE预定义的设备中断ID的基值),SYSINTR_PROFILE、SYSINTR_TIMING、SYSINTR_FIRMWARE等都是基于SYSINTR_DEVICES定义的。IoBase是串口1的IO地址空间的首地址,IoLen是IO空间的大小。IO地址空间只存在于x86平台,如果在其它平台硬件寄存器必须映射到物理地址空间,那子键的名称为MemBase和MemLen。在x86平台更多硬件的寄存器由于IO空间的局限也映射到物理地址空间。DeviceArrayIndex是设备的索引,用于区分同类型的设备。Prefix是流驱动程序的前缀,当应用程序调用CreateFile函数传递COM1:参数时,文件系统负责与串口驱动程序通信,串口驱动程序是在CE启动时由device.exe加载的。

下面从MDD层函数COM_Init开始探索串口驱动的初始化过程。COM_Init是在串口设备被检测后由设备管理器device.exe调用的,主要的作用是初始化设备,它的唯一参数Identifier是由device.exe传递的,其类型是一个字符串指针,字符串的内容是HLM\Drivers\Active\xx,xx是一个十进制数(device.exe会跟踪系统中每个驱动程序,把加载的驱动程序记录在Active键下)。COM_Init先分配一个HW_INDEP_INFO结构体,这个结构体是独立于串口硬件的头信息(MDD、PDD、SER16550都包含自己独特的结构体,具体的结构体定义请参见串口驱动源码),分配之后再初始化结构体中每个成员,初始化结构体后调用 OpenDeviceKey((LPCTSTR)Identifier)打开HLM\Drivers\Active\xx\Key包含的注册表路径,在这里路径一般为HLM\Drivers\BuiltIn\Serial,即串口的驱动程序信息在注册表中所处的位置。COM_Init接着在HLM\Drivers\BuiltIn\Serial下查询DeviceArrayIndex、Priority256的值,Priority256指定了驱动程序的优先级,如果没有就用默认的优先级。接下来调用GetSerialObject(DeviceArrayIndex),这个函数由PDD层定义,返回HWOBJ结构体,这个结构体主要包含PDD层和SER16550定义的函数的指针。也就是说MDD通过调用这个函数才能调用底层实现的函数。接下来的大多数工作都是调用底层函数实现初始化。第一个调用的底层函数SerInit主要设置由用户设置的硬件配置,例如线路控制、波特率。它调用Ser_GetRegistryData函数得到保存在注册表中的硬件信息,Ser_GetRegistryData在内部调用系统提供的DDKReg_GetIsrInfoDDK和DDKReg_GetWindowInfo函数得到在HLM\Drivers\BuiltIn\Serial下保存的IRQ、SysIntr、IsrDll、IsrHandler、IoBase、IoLen。IRQ是逻辑中断号,IsrDll表示当前驱动程序的可安装ISR所在的DLL名称,IsrHandler 表示可安装ISR的函数名称。在这里顺便提一下可安装ISR,读者在我以前发表的关于OAL的文章中可以了解到OEM在OEMInit函数中关联IRQ和SysIntr,当硬件设备发生中断时,ISR会禁止同级和低级中断,然后根据IRQ返回关联的SysIntr,内核根据ISR返回的SysIntr唤醒相应的IST(SysIntr与IST创建的Event关联),IST处理中断之后调用InterruptDone解除中断禁止。在OEMInit中关联的缺点是一旦编译了CE内核后就无法添加这种关联了,而一些硬件设备会随时插拔或者共享中断,要关联这样的硬件设备解决方法就是可安装ISR,可安装ISR专用于处理指定的硬件设备发出的中断,所以如果硬件设备需要可安装ISR必须在注册表中添加IsrDll、IsrHandler。多数硬件设备采用CE默认的可安装ISR giisr.dll,格式如下:

"IsrDll"="giisr.dll"
"IsrHandler"="ISRHandler"

如果一个硬件驱动程序需要可安装ISR而开发者又不想自己写一个,那么可以利用giisr.dll来实现。除了在注册表中添加如上所示外,还要在驱动程序中调用相关函数注册可安装ISR。伪代码如下:

g_IsrHandle = LoadIntChainHandler(IsrDll, IsrHandler, (BYTE)Irq);
GIISR_INFO Info;
PHYSICAL_ADDRESS PortAddress = {PhysAddr, 0};
TransBusAddrToStatic(BusType, dwBusNumber, PortAddress, dwAddrLen, &dwIOSpace, &(PVOID)PhysAddr)
Info.SysIntr = dwSysIntr;
Info.CheckPort = TRUE;
Info.PortIsIO = (dwIOSpace) ? TRUE : FALSE;
Info.UseMaskReg = TRUE;
Info.PortAddr = PhysAddr + 0x0C;
Info.PortSize = sizeof(DWORD);
Info.MaskAddr = PhysAddr + 0x10;
KernelLibIoControl(g_IsrHandle, IOCTL_GIISR_INFO, &Info, sizeof(Info), NULL, 0, NULL);

时间: 2024-10-30 12:12:57

Windows CE下驱动开发基础的相关文章

解析Windows CE下浏览器源码

有很多网友来信都问关于开发浏览器的问题.能够理解,现在大多数基于CE的产品都具有上网浏览的功能.CE也为此提供了两种IE浏览器的源码.一种IESAMPLE.另一种IESIMPLE.他们的存放路径在%_WINCEROOT%\Public\IE\Oak下.区别在于IESAMPLE就是CE下IE的标准版本的源码,有工具栏.状态栏.地址栏,还有Internet选项.收藏夹等等.和PC Windows的IE几乎一样.而IESIMPLE是mini版本,只有基本的IWebBrowser控件,用户界面上只有全屏

Windows CE下流驱动的动态加载

    我想很多WinCE的开发人员,尤其是刚入门并且做驱动开发的工程师,都曾碰到这样一个问题,要编写一个外围设备的驱动,拿最简单的GPIO驱动来说,编写驱动本身可能只花了一会儿功夫,可要把编译生成的DLL打包到先前做好的操作系统映像当中,最简单也得MakeImg一下,还要修改BIB文件.注册表文件,以让系统启动的时候就加载该驱动,所有工作都做完了,还得花几分钟下载整个操作系统到内存去运行,这也得要个好几分钟.能力强的人一次成功,不走回头路也就算了.如果驱动编写得有问题,那又得改代码,重新编译,

Windows环境下PHP开发环境搭建 - 图文完全教程_win服务器

基于Windows环境下的PHP开发环境搭建 (apache+mysql+php) 一.准备工作   Apache2.2.11 下载地址:http://www.apache.org   MySQL5.0 下载地址:http://www.mysql.com   PHP5.2.9   下载地址:http://www.php.net   二.配置PHP 1. 将php-5.2.9-win32.zip解压缩到指定位置(如C:\ ),并将其改为php[如下图]         2.打开php文件夹,并将p

Windows系统环境下JSP开发环境的配置

js|window Sun推出的JSP(Java Server Pages)是一种执行于服务器端的动态网页开发技术,它基于Java技术.执行JSP时需要在Web服务器上架设一个编译JSP网页的引擎.配置 JSP 环境可以有多种途径,但主要工作就是安装和配置Web服务器和JSP引擎. 下面就以Tomcat作为JSP引擎,配合Tomcat.Apache.IIS这三种Web服务器来讲述3种搭建JSP运行环境的方案. 一.相关软件介绍 1.J2SDK:Java2的软件开发工具,是Java应用程序的基础.

配置Windows CE下浏览器

IESAMPLE和IESIMPLE的许多配置参数都来自注册表,因为他们都采用同一种控件.还有一些配置如Internet选项,IESAMPLE能够根据控制面板中Internet选项对话框中的配置来工作,而这个选项对话框对IESIMPLE不起作用.唯一的办法是修改源码,在源码中设置参数.本篇文章先列举了常见的IE注册表设置,之后讲解如何在IESIMPLE源码中设置参数替代Internet选项对话框. 常见的IE注册表设置 注册表位置:HKEY_CURRENT_USER\Software\Micros

Windows CE下中文输入法编辑器

CE包含了一种简体中文输入法编辑器,如果不想编写自己的输入法编辑器,那么可以直接调用默认的.在讲解中文输入法编辑器之前顺便提一下国际化(Internationalization),中文输入法及输入法编辑器只是国际化组件的一小部分.国际化是编写面向不同语言用户的软件过程中一个重要环节,CE的国际化组件包含很多小的组件 . 下表描述了组件的名称.功能: 名称 功能 Agfa字体压缩 支持字体压缩 字体版本 因为东亚字体占据内存较大,此组件提供了用于选择不同大小字体文件的选项 手写识别 手写识别引擎

Windows的下Android开发环境要如何搭建

随着移动互联网的迅速发展,前端的概念已发生很大的变化,已不仅仅局限在网页端.而Android系统作为智能机市场的老大,作为前端开发工程师,非常有必要了解和学习.但面对众多学习资料,站在前端开发工程师的角色,怎样挑选出合适的路进行快速学习,而不必浪费大量时间去摸索,该系列文章希望能帮助到小伙伴们. 文章会挑选几个实际的例子,贯穿在整个系列中,涉及到Java.Android.程序设计等多方面知识,力求让大家快速掌握.俗话说,工欲善其事,必先利其器,系列的第一篇就从Window系统下Android的环

Windows CE S3C2440A显示驱动编码分析

在Windows CE下显示驱动是一个比较复杂的驱动,不仅仅设计到硬件的操作,还有上层驱动的GDI接口支持,有时候还需要支持DirectDraw等绘图接口.如果所有的编码工作都重新做一遍的话,难度还是挺大的,庆幸的是微软已经把大部分的接口都提供好了,DDI中包含的20个接口函数(以函数指针的方式表示),需要我们实现的也仅仅只有GPEEnableDriver.闲话不多说,我们先来看看S3C2440A_LCD_REG结构体吧,如下所示: typedef struct {     UINT32 LCD

WinXP下USB驱动开发(一)

  目  录 第1节    概述.... 4 第2节       USB相关技术.... 4 2.1.      USB拓扑结构... 4 2.2.      USB数据流模式... 5 2.3.      USB四种传输模式... 7 2.3.1.      批量传输... 7 2.3.2.      控制传输... 7 2.3.3.      中断传输... 8 2.3.4.      同步传输... 9 2.4.      USB协议层规范... 10 2.5.      USB HUB规