摘 要:介绍了Windows CE 的体系结构和中断处理机制,研究了Windows CE 设备驱动程序的类型和初始化过程,以维信诺VGG13264C 132×64 OLED 显示模块的WindowsCE 驱动程序设计为例,详细阐述了嵌入式Windows CE 驱动程序的开发过程。
关键词: Windows CE; 驱动模型; OLED驱动程序; 开发过程
随着计算机技术和嵌入式技术的迅猛发展,嵌入式软、硬件设计需求越来越广泛,嵌入式软件开发,特别是嵌入式软件的驱动开发,成为一个热点。
Windows CE 是一个新的、可移植的、实时的、模块化的操作系统[1],具有简捷、高效的完全抢先式多任务操作核心,支持强大的通信和图形显示功能,能够适应广泛的系统需求,在最新一代的工业和家用电子设备中得到了广泛的应用。
在进行嵌入式Windows CE项目开发的过程中,经常需要根据需求定制显示屏,如何为定制的显示屏开发Windows CE驱动程序成为嵌入式系统开发的关键步骤。本文在深入研究Windows CE 驱动程序工作原理的基础上,以维信诺VGG13264C 132×64 OLED 显示模块的WindowsCE 驱动程序设计为例,详细阐述了嵌入式Windows CE 驱动程序的开发过程,并对设计实现的驱动程序进行了测试。
1 Window CE的系统体系结构
Windows CE是微软设计开发的一种可升级的抢先式多任务32 位实时操作系统。一个基于Windows CE的平台主要由以下几部分组成:Windows CE内核组件、OAL层和驱动程序。OAL层和驱动程序作为目标设备和Windows CE内核组件之间的接口,将操作系统上层与硬件隔离,便于支持硬件扩展和即插即用功能[2],图1详细描述了三者之间的关系。
2 Windows CE中断处理
Windows CE将中断处理分为两个步骤:中断服务例程(ISR)和中断服务线程(IST)[3]。把每个硬件的设备中断请求(IRQ)和一个ISR联系起来,当一个中断发生并未被屏蔽时,内核调用该中断注册的ISR。因为ISR运行于内核模式,所以应设计得尽可能短,ISR引导内核调度和启动合适的IST,IST在设备驱动程序软件模块中编写,运行于用户模式,它从硬件获取或向硬件发送数据和控制代码,并进一步处理设备中断。Windows CE还提供了中断嵌套功能,即在一个ISR运行时,内核并不关闭中断,当优先级比之高的中断发生时,内核保存当前执行的中断服务例程ISR的运行状态,挂起该ISR,转而执行更高优先级中断的ISR。等到高优先级中断的ISR执行完后,被挂起的低优先级中断的ISR才重新开始被CPU调度执行。Windows CE的中断处理框图如图2所示。
3 Windows CE设备驱动程序
设备驱动程序将操作系统和设备连接起来,使操作系统能够识别设备,并为应用程序提供服务。
3.1 设备驱动程序模型
Windows CE提供了用于驱动开发的模型[4],其中包括来自其他操作系统的驱动程序模型。
因为有这些多变的驱动程序模型,使Windows CE可以适应大部分的内部和外围设备。目前,Windows CE提供了4种设备模型,其中两种是专用于Windows CE模型,另外两种外部模型来自其他的操作系统,汇总如图3所示。
3.2 本机驱动程序
要把Windows CE移植到目标平台上,必须为平台上已建立的设备提供驱动程序。一些类型的设备,如键盘、显示器和PC卡插槽等对操作系统都有一个自定义接口。因为这些接口是专门用于Windows CE的,所以称这类驱动程序为本机驱动程序。Windows CE 平台生成器提供本机设备驱动程序的样本,可考虑把本机设备驱动程序样本应用到平台上,而不需要再从头开发自己的本机驱动程序。用户可根据驱动程序样本快速开发自己的驱动程序。
3.3 流接口驱动程序
流接口驱动程序由设备管理应用程序加载、管理和卸载,与具有单独目的接口的本机驱动程序相比,所有流接口驱动程序使用同一个接口并调用同一个函数集——流接口函数。流接口驱动程序把外设抽象成一个文件,使用标准文件I/O函数和电源管理函数,这些函数由Windows CE 操作系统的内核使用。流接口驱动程序的入口点函数为: XXX_ Init、XXX_Deinit、XXX_IOControl、XXX_Open、XXX_Close、 XXX_PowerDown、 XXX_PowerUp、XXX_Read、XXX_Seek、XXX_Write 。流接口驱动程序函数的作用及调用关系如表1所示。
流接口驱动程序从设备管理器和通过文件系统调用的应用程序接受命令,装入驱动将这些命令翻译成其所控制设备的适当操作的所有信息。所有的流接口驱动,无论它管理的是内置式设备还是可安装式设备,是系统引导加载还是动态加载,它们与其他的系统组件都有类似的交互过程。
3.4 设备驱动程序的初始化过程
在Windows CE中,所有的设备驱动程序都以动态链接库(DLL)的形式存在,需要通过进程加载。设备驱动程序向外提供接口函数,应用程序使用API对设备进行访问。Windows CE共有三类系统进程用来加载驱动程序:Device.exe、GWES.exe、FileSys.exe。驱动程序的初始化过程为:设备上电——启动bootloader——启动NK.exe——启动Device.exe——初始化数据结构和I/O——加载总线枚举器——枚举注册表Driver/BuildIn下所有的子键。这里的枚举就是循环调用ActivateDeviceEx函数加载驱动程序。
4 Windows CE开发流接口驱动程序实例
以维信诺VGG13264C 132×64 OLED显示模块的驱动程序为例,具体阐述Windows CE驱动开发的过程。
4.1 硬件结构
系统硬件以飞凌OK6410-B开发板为主板,以维信诺VGG13264C显示模块为OLED显示屏。系统硬件框图如图4所示。
飞凌OK6410-B开发板基于三星公司最新的ARM11处理器S3C6410,拥有强大的内部资源和视频处理能力,可稳定运行在667 MHz主频以上,支持Mobile DDR和多种NAND Flash。FL6410开发板上集成了多种高端接口,如复合视频信号、摄像头、USB、SD卡、液晶屏、以太网等,丰富的接口可帮助用户实现高端产品级设计。
维信诺VGG13264C是132列×64行点阵的OLED单色、字符、图形显示模块,使用单芯片SSD1303T6进行驱动,具有8位并行数据接口,模块内含132×64显示数据 RAM,通过用户I/O接口连接到飞凌OK6410-B开发板。
4.2 流接口驱动程序开发过程
Windows CE提供了两种编写流接口驱动的方法:(1)通过编写动态链接库的方法实现; (2)通过修改BSP的方法实现。由于第二种方法可以加快开发进度,在该实例中,使用修改BSP的方法进行流接口驱动程序开发,其开发步骤为:首先在BSP中新建一个目录,编写驱动程序文件并确定驱动程序向外提供的接口函数,然后进行注册表设置,最后进行测试。
(1)驱动程序代码编写
设备初始化使用OED_Init函数实现,设备卸载使用OED_Deinit函数实现。在OED_Init函数中,使用DrvLib_MapIoSpace函数实现物理地址到虚拟地址映射;在OED_Deinit函数中,使用VirtualFree函数释放驱动程序使用的虚拟内存从而实现了设备的卸载。
设备的I/O控制向设备发出命令,按照维信诺VGG13264C OLED显示模块的时序关系,通过控制相应管脚的电平高低实现向设备发出命令。设备的I/O控制在OED_IOControl函数中实现,函数部分代码如下:
switch (dwIoControlCode) {
case IOCTL_OLED_INIT:
v_pIOPregs->GPPCON&=0xF000FFFF;
v_pIOPregs->GPPCON|=0x5550000;
……
Delay_ns(2);
v_pIOPregs->GPEDAT|=(0x01<<4);
Delay_ns(2);
v_pIOPregs->GPEDAT|=(0x01<<2);
break;
case IOCTL_OLED_WRITECOMMAND:
v_pIOPregs->GPEDAT&=~(0x01); //A0低
v_pIOPregs->GPEDAT|=(0x01<<3); //CS高
v_pIOPregs->GPEDAT|=(0x01<<1); //WR高
Delay_ns(1);
v_pIOPregs->GPEDAT&=~(0x01<<3); //CS低
v_pIOPregs->GPEDAT&=~(0x01<<1); //WR低
if((0x01<<7)&(*pInBuf))
v_pIOPregs->GPQDAT|=(0x01<<6);
else v_pIOPregs->GPQDAT&=~(0x01<<6);
……
Delay_ns(1);
v_pIOPregs->GPEDAT|=(0x01<<1); //WR高
Delay_ns(1);
v_pIOPregs->GPEDAT|=(0x01<<3); //CS高
break;
case IOCTL_OLED_WRITEDATA:
v_pIOPregs->GPEDAT|=(0x01); //A0高
v_pIOPregs->GPEDAT|=(0x01<<3); //CS高
v_pIOPregs->GPEDAT|=(0x01<<1); //WR高
v_pIOPregs->GPEDAT&=~(0x01<<3); //CS低
v_pIOPregs->GPEDAT&=~(0x01<<1); //WR低
if((0x01<<7)&(*pInBuf))
v_pIOPregs->GPQDAT|=(0x01<<6);
else v_pIOPregs->GPQDAT&=~(0x01<<6);
……
Delay_ns(1);
v_pIOPregs->GPEDAT|=(0x01<<1); //WR高
Delay_ns(1);
v_pIOPregs->GPEDAT|=(0x01<<3); //CS高
break;
}
(2)向外提供函数接口
通过配置OED.def文件导出OLED提供的接口函数,供设备管理器使用。在OED.def 文件中添加如下代码:
LIBRARY OED
EXPORTS OED_Init
OED _Deinit
OED _Open
OED _Close
OED _Read
OED _Write
OED _Seek
OED _PowerDown
OED _PowerUp
OED _IOControl
(3)注册表配置
注册表文件Platform. reg 用来配置与OLED驱动有关的信息,配置如下:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\IoControler]
“Prefix”=“OED”
“Dll”=“OED.dll”
“Index”=dword:0
随着嵌入式系统广泛应用到信息家电、工业控制、移动通信、互联网等领域,大量嵌入式系统的开发必将对人类科技的发展起着重要的作用。本文介绍的基于嵌入式操作系统Windows CE 的驱动程序会帮助读者开发出更多的嵌入式系统产品。
参考文献
[1] GOGGIN T A. Windows CE 高级开发指南[M]. 尤滔,张平,周晓权,译,北京:电子工业出版社,2001.
[2] Microsoft . Microsoft Windows CE Device Driver Kit[M]. 北京:北京希望电子出版社,2000.
[3] 胡军辉,王友钊.Windows CE设备驱动程序开发[J].计算机工程,2006,32(16):41-43.
[4] 李长河,王永强,刘刚,等.嵌入式Windows CE设备驱动的研究实现[J].微机发展,2003,13(7):69-72.