分类:
2010-03-21 21:32:11
摘要:将操作系统和相应硬件设备连接起来,编写联系硬件和软件的驱动程序至关重要。本文主要讨论在 WinCE操作系统下,如何设计实现S
关键词:WinCE 流驱动 I
引言
随着以计算机技术、通信技术和软件技术为核心的信息技术的迅速发展,嵌入式系统在各行业得到了广泛的应用,极大地推动了行业的渗透性应用。嵌入式系统是 “以应用为中心、以计算机技术为基础、软硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统”,由嵌入式硬件和嵌入式软件两部分组成。嵌入式软件包括嵌入式操作系统和嵌入式应用软件。Microsoft的桌面操作系统已经为人们熟悉和使用,嵌入式的操作系统Windows CE.net也日益风行。Windows CE.net是Microsoft推出的功能强大的紧凑、高效、可伸缩的32位嵌入式操作系统,主要面对各种各样的嵌入式系统和产品。该系统所具有的多线程、多任务、完全抢占式的特点是专为各种具有严格资源限制的硬件系统所设计的。为了将操作系统和硬件设备连接起来,联系硬件和软件的驱动就显得很重要。
下面主要针对三星公司ARM9内核的芯片S
1 I
I
I
S
S
◇ IIC控制寄存器,IICCON(物理地址0X54000000,内存映射后的虚拟地址);
◇ IIC控制/状态寄存器,IICSTAT(物理地址0X54000004);
◇ IIC数据寄存器,IICDS(物理地址0X54000008);
◇ IIC地址寄存器,IICADD(物理地址0X
本设计主要是CPU工作在主模式下与下面的I
2 Windows CE系统驱动特点
Windows CE.net驱动有两种模型:本机设备驱动程序和流接口驱动程序。本机设备驱动适于集成到基于Windows CE.net平台的设备。这些设备驱动程序是一些硬件所必需的,是由原始设备制造商创建的,用以驱动如键盘、触摸屏、音频设备等,往往在设备售出后就不会再更换,如通用LED驱动、电源驱动、键盘驱动和显示驱动等都是本机设备驱动。对于本机设备驱动程序,Platform Builder提供了一些驱动程序样本,目的是为了方便开发人员快速开发出自己的驱动程序。当Win CE系统启动时,本地设备驱动程序将被加载到系统的内存中。本地驱动程序的开发分为分层驱动和单片驱动程序。分层驱动要利用微软提供的与应用程序通信的上层,称为模块驱动程序层MDD(Model Device Driver)。MDD层通过设备驱动程序接口DDI(Device Driver Interface)与应用程序通信,开发驱动程序通常不修改MDD层,主要关心与具体硬件相关的下层,依赖平台的设备驱动程序层PDD (Platform Dependent Driver), PDD层通过设备驱动服务接口(Device Driver Service Provider Interface)直接管理硬件。流接口设备驱动程序(指可安装的启动程序)可以由第三方生产商提供,以支持添加到系统中的设备。Windows CE下的设备驱动程序在与应用程序相同的保护级上工作。当系统启动时,大多数驱动程序是由设备管理进程(DEVICE.EXE)加载的,所有这些驱动程序将共享同一个进程地址空间。
3 I
I
3.1 初始化I
I
#defineSYSINTR_I
然后在文件cfw.c的文件中添加I
在OEMInterruptEnable函数中加入
case SYSINTR_IIC:
s2410INT->rSRCPND=BIT_IIC;
if (s2410INT->rINTPND & BIT_IIC) s2410INT->rINTPND = BIT_IIC;
s2410INT->rINTMSK&= ~BIT_IIC;
break;
在OEMInterruptDisable函数中加入
case SYSINTR_IIC:
s2410INT->rINTMSK|= BIT_IIC;
break;
在armint.c文件中添加ISR程序,处理中断发生后返回定义的中断号。具体代码如下:
在OEMInterruptHandler函数中添加
else if (IntPendVal == INTSRC_IIC) {
s2410INT->rSRCPND= BIT_IIC; /* 清除中断 */
if (s2410INT->rINTPND & BIT_IIC) s2410INT->rINTPND= BIT_IIC;
s2410INT->rINTMSK|= BIT_IIC; /* I
return (SYSINTR_RTC_ALARM);
}
3.2 编写流驱动程序
I
reg = (PVOID)VirtualAlloc(0, sz, MEM_RESERVE, PAGE_NOACCESS);
if (reg) {
if (!VirtualCopy(reg, addr, sz, PAGE_READWRITE | PAGE_NOCACHE )) {
RETAILMSG( DEBUGMODE,( TEXT( "Initializing interrupt " ) ) );
VirtualFree(reg, sz, MEM_RELEASE);
reg = NULL;
}
}
其中sz是申请的长度,addr是申请虚拟地址空间的实际物理地址在Win CE中的映射地址。
然后对申请到的虚拟地址进行操作,安装Windows中的流驱动的模型进行驱动的编写,主要包括下面函数的编写。
IIC_Init()
在函数中,主要是对I
v_pIICregs = ( volatile IICreg *)IIC_RegAlloc((PVOID)IIC_BASE, sizeof(IICreg));
v_pIOPregs = ( volatile IOPreg *)IOP_RegAlloc((PVOID)IOP_BASE, sizeof(IOPreg));
v_pIOPregs->rGPEUP|= 0xc000;
v_pIOPregs->rGPECON |= 0xa00000;
v_pIICregs->rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);
v_pIICregs->rIICADD= 0x10;
v_pIICregs->rIICSTAT = 0x10;
VirtualFree( ( PVOID )v_pIOPregs,sizeof( IOPreg ),MEM_RELEASE );
v_pIOPregs = NULL;
if ( !StartDispatchThread( pIIcHead) )
{ IIC_Deinit( pIIcHead );return ( NULL );}在StartDispatchThread()函数中,主要是创建线程、关联事件和中断,主要语句如下:
InterruptInitialize( 36,pIicHead->hIicEvent,NULL,0 );//关联时间和中断
CreateThread( NULL,0,IicDispatchThread,pIicHead,0,NULL );//创建线程等待时间
在IicDispatchThread()函数中,主要是等待中断的产生,然后去执行:WaitReturn = WaitForSingleObject( pIicHead->hIicEvent,INFINITE );
IicEventHandler( pIicHead );//事件处理函数
InterruptDone( 36 );
最后,在函数IIC_Open、IIC_Read、IIC_Write中,对各个寄存器进行操作,进行数据的赋值,得到I
4 I
通过上面的工作,能编译一个DLL函数,但这还不能叫流接口驱动程序。因为它的接口函数还没有导出,还需要告诉链接程序需要输出什么样的函数,为此要建立一个自己的def文件,可以用记事本建一个,取名mydrive.Def:
LIBRARY MyDriver
EXPORTS
IIC_Close
IIC_Deinit
IIC_Init
IIC_IOControl
IIC_Open
IIC_PowerDown
IIC_PowerUp
IIC_Read
IIC_Seek
IIC_Write
然后同样用记事本编写一个注册表文件,取名为mydrive.reg:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\STRINGS]
"Index"=dword:1
"Prefix"="IIC"
"Dll"="MyDriver.dll"
"Order"=dword:0
最后编写自己的CEC文件。主要是添加一个Build Method,任务是复制注册表到Win CE的系统目录下面。加一个Bib File,其主要功能是把编译的mydrive.dll文件添加到系统内核中去。保存写好的CEC文件。打开Platform Builder,打开“File”菜单,添加刚刚编写的CEC特征到系统选项中去。生成系统的时候,添加自己的CEC特性,就可以包含刚刚编写的I
以上介绍了Win CE的驱动结构,并给出了基于Win CE的 I