DIY编程器网
标题:
基于WinCE的I2C驱动程序设计
[打印本页]
作者:
admin
时间:
2014-10-11 02:18
标题:
基于WinCE的I2C驱动程序设计
引言
随着以计算机技术、通信技术和软件技术为核心的信息技术的迅速发展,嵌入式系统在各行业得到了广泛的应用,极大地推动了行业的渗透性应用。嵌入式系统是
“
以应用为中心、以计算机技术为基础、软硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统
”
,由嵌入式硬件和嵌入式软件两部分组成。嵌入式软件包括嵌入式操作系统和嵌入式应用软件。
Microsoft
的桌面操作系统已经为人们熟悉和使用,嵌入式的操作系统
Windows CE.net
也日益风行。
Windows CE.net
是
Microsoft
推出的功能强大的紧凑、高效、可伸缩的
32
位嵌入式操作系统,主要面对各种各样的嵌入式系统和产品。该系统所具有的多线程、多任务、完全抢占式的特点是专为各种具有严格资源限制的硬件系统所设计的。为了将操作系统和硬件设备连接起来,联系硬件和软件的驱动就显得很重要。
下面主要针对三星公司
ARM9
内核的芯片
S3C2410
进行分析,介绍在
Windows CE.net
系统下进行底层设备驱动开发的方法并提供
I2C
通信的实例。
1 I2C
通信协议及
S3C2410
芯片介绍
I2C(Inter Integrated Circuit)
总线是
1980
年由
Philips
公司推出的。
I2C
总线用两条线(
SDA
和
SCL
)在总线和装置之间传递信息,在微控制器和外部设备之间进行串行通信或在主设备和从设备之间进行双向数据传送。两条通信线通过上拉电阻被拉升至
+5 V
。在控制系统中的每个集成电路可以通过一个
CMOS
缓冲器来读每一条线路,也可以通过一个栅极开路的
FET
管将每一条线的电平下拉。因此,对每个芯片来说,每条线既是输入线,又是输出线。
I2C
总线遵从同步串行传输协议,即各位串行(一位接一位)发送,由时钟(
clock
)线指示读数据(
data
)线的时刻。每个数据包前有一个地址,以指示由哪个器件来接收该数据。
S3C2410
是一款基于
ARM920T
的
16/32
位
RISC
微处理器,主要用于手持设备,拥有高性价比,低功耗等特点,也是目前市面上出现较多的嵌入式开发板的处理器之一。芯片拥有
16 KB
的指令和数据缓存器,有存储管理单元(
MMU
)、
LCD
控制器、
3
个串口、
4
路
DMA
、
4
个时钟定时器、
8
路
10
位的
A/D
转换;支持
I2C
、
I2S
、
SPI
、主从
USB
等接口以及
SD/MMC
卡。
S3C2410
微处理器的
I2C
总线可以处于下面
4
种模式下:主接收模式、主发送模式、从接收模式和从发送模式。处理器对
I2C
进行的操作,主要是对下面的几个寄存器进行读
/
写:
◇
IIC
控制寄存器,
IICCON
(物理地址
0X54000000
,内存映射后的虚拟地址);
◇
IIC
控制
/
状态寄存器,
IICSTAT
(物理地址
0X54000004
);
◇
IIC
数据寄存器,
IICDS
(物理地址
0X54000008
);
◇
IIC
地址寄存器,
IICADD
(物理地址
0X5400000C
)。
本设计主要是
CPU
工作在主模式下与下面的
I2C
接口设备进行通信。
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 I2C
总线底层驱动设计
I2C
总线驱动是放在
Windows CE
操作系统的内核下层,位于
OEM Adaptation Layer
(
OAL
)层的一个真正的驱动。
3.1
初始化
I2C
中断和编写
ISR
例程
I2C
的通信是通过操作
I2C
的寄存器进行的。在
I2C
通信中主要对上面介绍的
4
个寄存器进行读写。通过读写这些寄存器中的命令状态字可以检测和控制
I2C
总线的行为。在
Windows CE.net
下,首先要在文件
oalintr.h
添加
I2C
的中断号的宏定义:
#defineSYSINTR_I2C(SYSINTR_FIRMWARE+19)
然后在文件
cfw.c
的文件中添加
I2C
中断的初始化,禁止和复位。具体代码如下
:
在
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; /* I2C
中断禁止
*/
return (SYSINTR_RTC_ALARM);
}
3.2
编写流驱动程序
I2C
总线驱动程序采用的是
Win CE
流驱动的标准形式。在
IIC_Init
的函数中,首先通过函数
VirtualAlloc
()和
VirtualCopy
(),把芯片中针对
I2C
的物理地址和操作系统的虚存空间联系起来,对虚拟地址空间的操作就相当于对芯片的物理地址进行操作。地址映射的代码如下:
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 \n\r" ) ) );
VirtualFree(reg, sz, MEM_RELEASE);
reg = NULL;
}
}
其中
sz
是申请的长度,
addr
是申请虚拟地址空间的实际物理地址在
Win CE
中的映射地址。
然后对申请到的虚拟地址进行操作,安装
Windows
中的流驱动的模型进行驱动的编写,主要包括下面函数的编写。
IIC_Init
()
在函数中,主要是对
I2C
的初始化,主要语句如下:
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
中,对各个寄存器进行操作,进行数据的赋值
,
得到
I2C
读取的数据和发送数据。
4 I2C
驱动的封装和添加到
Windows CE
中
通过上面的工作,能编译一个
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_MACHINEDriversBuiltInSTRINGS]
"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
特性,就可以包含刚刚编写的
I2C
驱动了。
以上介绍了
Win CE
的驱动结构,并给出了基于
Win CE
的
I2C
驱动程序部分源代码。实验证明该设计是可行的。
欢迎光临 DIY编程器网 (http://diybcq.com./)
Powered by Discuz! X3.2