陈绍贵,王新华,郭淑琴
(1.浙江工业大学信息学院,浙江杭州310023;2.浙江科技学院信息学院,浙江杭州310023)
随着信息技术的发展,以嵌入式智能设备为核心的后PC时代已经来临,嵌入式技术和产品得到了很大的发展,美国微软公司也发布了一系列嵌入式操作系统,并且取得了巨大的成功。WinCE是微软公司设计的一个开放的、可裁剪的、32位的实时窗口操作系统,具有可靠性好、实时性高、内核体积小等特点;拥有良好的通信能力、出色的图形界面、灵活的电源管理,并内置多媒体功能、支持多种CPU,所以被广泛应用于移动应用产品、消费类电子产品和嵌入式智能设备的开发[1]。为了使操作系统与硬件很好的连接在一起,编写硬件的驱动程序就显得至关重要了。
IIC串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到IIC总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。IIC总线是遵从串行传输协议的。当总线开始工作的时候,即各位串行(一位接一位)发送,由时钟(clock)线指示读数据(data)线的时刻。IIC总线数据由8位构成,传输数据前首先传输一个地址,地址由8位组成,前7位为设备地址,第8位为传输方向。S3C2440A的IIC总线接口有4种工作模式:主机发送模式、主机接收模式、从机发送模式、从机接收模式。在一般嵌入式系统中,IIC总线一般外接一片EEPROM。EEPROM(Electrically Erasable Programmable Read-Only Memory)有8针和14针两种封装,我们的系统采用的是8针封装的芯片。芯片上SCL和SDA两个引脚直接连到CPU上引脚;为了可以控制EEPROM的读写,把WP引脚连接到VD9/GPD1引脚上,当CPU把这个引脚置高电平或低电平时,就可以控制EEPROM是可读可写还是可读不可写。A2、A1和A0是设备地址,没有连接外设或者兼容设备时,应该全部置低电平,这样可以读出EEPROM的地址。为了保护芯片,SCL、SDA和WP信号线都接4.7K的上拉电阻。芯片采用的是AT24C64N-10SI-2.7。IIC硬件连接如图1所示。
图1 IIC总线硬件电路
处理对IIC总线操作通过操作IIC总线寄存器完成,S3C2440A总线寄存器如下:(1)多主机IIC总线控制IICCON寄存器(物理地址0X54000000);(2)多主机IIC总线控制状态IICSTAT寄存器(物理地址0X54000004);(3)多主机IIC总线地址IICADD寄存器(物理地址0X54000008);(4)多主机IIC总线发送接收数据移位IICDS寄存器(物理地址0X5400000C);(5)多主机IIC总线线控制IICLC寄存器(物理地址0X54000010)。
基于WinCE5.0的IIC总线驱动程序是分层驱动。Device.exe(设备管理器)调用LoadLibrary函数而引用动态链接库入口函数DllEntry把i2c.dll(IIC总线驱动的动态链接库的名称)加载到内存当中或者通过Freelibrary引用DllEntry释放资源,然后调用I2C_Init初始化设备或者调用I2C_Deinit卸载这个设备,这些函数都位于IIC总线驱动程序的MDD,MDD层中的函数通过调用PDD层中的函数操作底层硬件。分层驱动是将驱动程序代码分为模型设备驱动(Model Device Driver,MDD)和称为平台相关驱动(Platform Dependent Driver,PDD)的下层。MDD层是微软公司提供的给定类型所有驱动程序公用的代码,在驱动程序修改或者编写的时候,一般不建议修改MDD层代码,以免系统无法使用提供的驱动程序;PDD层是由特定于给定硬件设备或平台的代码组成的,MDD层调用PDD层函数来访问硬件或者特定硬件信息[2、3]。Device.exe通过流驱动接口函数管理IIC总线设备,IIC总线的流驱动借口函数位于程序的MDD层,这个文件在移植过程中是不需要修改的。主要工作是编写或者修改(根据设备或者芯片不同)IIC总线的PPD层。
IIC总线驱动程序代码构成,本文采用飞凌公司OK2440-III提供的SMDK2440A的BSP包。IIC总线的驱动程序位于%_W INCEROOT%PLATFORMSMDK2440ASrcDR IVERSIIC。里面包含了多个文件,其中drv.c和i2c.c是IIC总线的驱动程序代码,drv.h是所需的头文件。其中drv.c是IIC总线驱动的MDD层,而i2c.c是它的PDD层。利用PlatBuilder5.0移植驱动程序。
IIC总线驱动程序实现分析,因为PDD层需要与硬件打交道,而IIC的硬件操作主要是通过操作CPU的寄存器,在S3C2440A_IIC_BUS结构体中定义了它所有的寄存器,S3C2440A所有寄存器地址在s2440addr.h中。由于需要与I/O口打交道,我们要对I/O口进行配置,在s3c2440a_ioport.h中定义一个包含所有GPIO口寄存器的S3C2440A_IOPORT_REG结构体。IIC的操作需要用到时钟PCLK,在S3C2440A_CLKPWR_REG结构体中定义了所有的S3C2440A使用到的时钟,包括FCLK、HCLK和PCLK等。在drv.h文件中定义了一个_I2C_CONTEXT结构体,对于IIC所有操作都指向这个结构体,包括对IIC总线的初始化、中断、IIC总线的状态等。I2C_STATE枚举结构中枚举了IIC的所有状态,有闲置、读、写等。
IIC TX/RX是通过中断的方式完成的。在i2c.def列举了所有的IIC总线需要实现的流接口函数,在PPD层中有几个一定需要实现的流接口函数。在Device.exe完成加载IIC总线驱动后,第一个调用的函数是I2C_Init,而这个MDD层函数这是通过调用PDD层的HW_Init函数完成,这个函数主要做以下几方面的工作:初始化IIC主要的数据结构体变量的结构成员,主要是为控制流服务的;初始化IIC总线接口的寄存器,为后面IIC TX/RX做准备,这个是通过调用InitRegs函数完成的;创建I/O事件、创建IST事件、为IIC物理中断申请相应的逻辑中断号、把IIC的逻辑中断和创建的IST事件绑定在一起、创建IIC线程,这个线程用于控制IIC操作的控制流。HW_Deinit主要在完成中断后关中断。SyncIst主要是同步IIC中断服务线程I2C_IST。参考AT24C64N-10SI-2.7的数据手册,可以编写HW_Read和HW_Write两个函数,
可以发现在数据手册中,对于IIC的读写都是先读写设备地址,再读写数据的。I2C_IST就是响应中断函数,其中用switch语句选择响应怎么样的操作。其整个驱动程序流程图如图2所示:
IIC总线驱动的配置文件,在WINCE5.0中,所有的驱动,无论单层驱动还是流驱动,都是以动态链接库(.dll)的形式存在的,当系统启动时,这些驱动就动态的加载到系统当中。配置文件用来指导如何编译驱动(MakeFile文件),还用来确定驱动程序最后生成的动态链接库的文件名、存放目录等(source、platform.bib、platform.reg),并把这些重要信息放在注册表文件中提供给操作系统,以便操作系统对驱动程序进行管理。Platform.bib文件中对IIC描述如下:
图2 IIC总线驱动程序流程图
IF BSP_NOI2C!
i2c.dll$(_FLATRELEASEDIR)i2c.dllNKSH
ENDIF BSP_NOI2C!
由此可知,i2c.dll将被加载到NK(内核)的存储区域,且i2c.dll具有系统和隐藏属性,NK区域在config.bib中定义为NK80400000。
platform.reg是WINCE5.0的注册表文件,系统根据注册表对驱动程序的描述动态的加载驱动,它对IIC驱动程序的描述如下:
"Prefix"="I2C"//驱动函数的前缀键值
"Dll"="I2C.DLL"//动态链接库的名称
"Order"=dword:8//驱动的加载顺序,这表明IIC驱动不会过早被加载
"Index"=dword:0//驱动索引
"Mode"=dword:1//Mode:0=POLLING,1=INTERRUPT
"SlaveAddress"=dword:0//Bus Driver's Slave Address
"FriendlyName"="I2C Bus Driver"
"IClass"="{A32942B7-920C-486b-B0E6-92A702A99B35}"//电源管理
Source文件包含一些宏定义,编译软件(platformbuider5.0)利用这些宏定义作为选项来决定如何编译和链接源文件,IIC总线的source问价描述如下:
RELEASETYPE=PLATFORM//编译系统
TARGETNAME=i2c//驱动名称
TARGETTYPE=DYNLINK//生成动态链接库
DLLENTRY=DllEntry//驱动入口函数
IIC总线驱动移植,成功的移植IIC总线驱动必须认真研读EEPROM的手册,对于不同的芯片,读地址、读操作、写操作的时序必须分析清楚。AT24C02和AT24C64的读写操作时序是不一样,在读写完成等待时间(延迟)也是不一样的,延迟对于硬件移植来说是非常重要的一环。
IIC总线驱动移植结果,IIC总线驱动移植调试用一款基于WINC5.0的调试软件,调试结果如图3所示:
图3 IIC驱动调试结果
本文简单介绍了基于WINCE5.0的驱动程序的分层驱动,在此基础上讲解了IIC总线的驱动程序,对于移植WINCE下的IIC总线驱动有一定的作用。
[1]周毓林.Windows CE net内核定植及应用开发[M].北京:电子工业出版社,2005:25-23.
[2]顾峥浩,王自强,聂文华.WinCE流驱动程序设计概述[J].微处理机,2007,(3):81-83.
[3]张冬泉,谭南林,苏树强.Windows CE实用开发技术[M].北京:电子工业出版社,2008:272-273.
[4]张毅,王海涛.基于S3C2410的WinCE5.0下触摸屏驱动的实现[J].重庆邮电大学学报,2008,20(6):742-744.
[5]杨泽辉,徐燕玲,刘碧君,等.基于嵌入式WinCE的GPIO驱动开发[J].太原科技大学学报,2010,31(6):446-447.
[6]阳开新.铁氧体材料及应用[J].磁性材料及器件,1996,27(3):19-23.