注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

My Unix World

不要迷恋Unix,Unix只是计算世界很小的一部分!

 
 
 

日志

 
 

转:S3C2440 Windows CE的RTC模块驱动设计与实现  

2010-03-06 11:38:23|  分类: develop-arm/ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
似乎这一篇对RTC的介绍比较详细,尽管是为了WinCE服务,仍值得一读。

1 引言
桌面Windows系统的时间显示功能已为大家所熟知,它是通过BIOS上的时钟模块实现的。用户通过点击桌面系统任务栏右下脚的时间,可以修改当前时间、时区以及实现与Internet时间同步等功能。
目前流行的手机、PDA、HMI(人机接口设备)等嵌入式系统中,都大量移植了微软的Windows CE操作系统。虽然WinCE系统也实现了时间显示,但是在具体的实现中,其原理和方法与桌面系统大不相同,即使是基于不同嵌入式硬件平台的WinCE开 发,也有所不同。由于嵌入式系统的复杂性、分散性,目前嵌入式系统的实时时钟RTC功能的实现,大部分是在基于内嵌于SoC处理器的RTC功能IP模块的 基础上,通过软件驱动实现的。
S3C2440是三星公司推出的一款基于ARM920T处理器构架的低功耗、高性能的嵌入式SoC处理器,应用极为广泛。RTC是S3C2440的一个内 部功能模块,本文首先对于S3C2440的硬件架构进行介绍,在此基础上对S3C2440的RTC功能模块的工作机理进行了分析,最后给出Windows CE.net下的RTC功能的驱动程序设计、实现,本驱动程序成功地应用在基于S3C2440Window CE平台的手持GPS机实时时钟功能的实现,对于基于Windows CE.net其它硬件平台的RTC功能实现具有一定的借鉴作用。

2 硬件构架
WinCE下RTC功能实现是基于RTC模块的,在此先对S3C2440处理器作简单介绍,主要对于S3C2440的RTC的硬件结构、工作机理进行分析,这些是Windows CE.net下RTC功能实现的基础。
2.1 简介
S3C2440 是三星公司推出的基于ARM920T的嵌入式处理器,主频高达400MHz,最高可达533MHz,低功耗、高性能,广泛地应用于PDA、便携媒体播放 器、卫星导航仪等多媒体终端,片上集成指令/数据分开的16KCache、SDRAM控制器、LCD控制器、4通道DMA、3通道UART、IIC总线、 IIS总线、SD主机接口、PWM定时器、看门狗、片上PLL时钟发生器、8通道10位AD控制器和触摸屏接口以及带日历函数的实时时钟,极大地方便于系 统开发。

2.2 S3C244O处理器的RTC硬件构架
S3C2440内部RTC模块结构框图如图1所示。S3C2440处理器的RTC模块依靠外部32.768kHz晶振提供基准时钟,系统能够在断电的情况 下由后备电池供电继续工作,能够将8位数据转换为BCD码的格式传送给处理器。这些数据包括秒、分、时、日期、星期、月、年。
如图1所示,RTC模块由基准晶振的连接引脚、时钟滴答发生器、215时钟分频器、控制和重置寄存器、闰年发生器、报警发生器以及BCD数字(秒、分、 时、日期、星期、月、年)等几部分组成:XTlrtc与XTortc是连接外部晶振32.768kHz的两个引脚,为RTC内部提供输入。215时钟分频 器负责对基准频率进行分频。时钟滴答发生器可以产生时钟滴答,它可以引起中断。闰年发生器按照从日期、月、年得来的BCD数据决定一个月最后一天是28、 29、30还是31号(也就是计算是否是闰年)。报警发生器可以根据系统设定时间和当前时间决定是否报警。控制寄存器控制包括读/写BCD寄存器使能、时 钟复位、时钟选择等。重置寄存器可以选择”秒”对”分”进位边界,提供三个可选边界:30、40或者50秒。

  转:S3C2440 Windows CE的RTC模块驱动设计与实现 - liqi xie - My Unix World 
图1 S3C2440内部RTC模块结构图


2.3 S3C2440处理器的RTC工作原理
由RTC模块的结构图可以看出,RTC模块的有三种功能:产生时钟滴答、实时计时和作为系统的触发唤醒器。RTC时钟滴答可以作为实时操作系统(RTOS)的内核时钟滴答,当时钟滴答周期确定后,就会定时产生中断,操作系统的中断服务程序会实时处理这个中断。
RTC模块可以在处理器的掉电模式或普通模式在设定时间(由BCD数据给出)和当前时间相同时发生报警。在普通模式下,ALMINT(报警中断)处于激活状态。在掉电模式下,PMWKUP(电源管理唤醒信号)与ALMINT一起处于报警状态。
RTC最重要的功能就是显示时间。在掉电模式下,RTC依然能够正常工作,此时,RTC模块通过外部的电池工作。RTC时间显示功能是通过读/写寄存器来 实现的。要显示秒、分、时、日期、月、年,处理器只要读取存在于BCDSEC、BCDMIN、BCDHOUR、BCDDAY、BCDDATE、 BCDMON和BCDYEAR寄存器中的值即可。

3 驱动程序实现
本RTC功能的实现在基于S3C2440嵌入式开发平台上,通过WinCE下的RTC模块的驱动程序完成,而WinCE下RTC的驱动是在底层实现的,具 体要在OAL(OEM Adaption Layer)实现。下面对于OAL代码层进行简要介绍,然后分析RTC驱动代码,在此基础上给出部分源程序。
3.1 OAL概述
OAL的全称是OEM Adaption Layer,即原始设备制造商适配层。从逻辑结构上看,它位于操作系统的内核与硬件之间,是连接系统与硬件的枢纽;从功能上看,OAL是被链接到内核的 库,它可以用来创建内核的可执行文件。OAL在系统内核与目标设备之间进行通信,隶属于操作系统.是操作系统的一部分。从存在方式上讲OAL是一组函数的 集合体,这些函数体现出OAL的功能,如图2所示。

图2 OAL功能结构关系框图
OAL层包含Startup()、OEMInit()、实时时钟函数、串口调试函数、底层中断处理函数、以太网口调试函数、KITL(Kernel Independent Transport Layer)内核独立传输层,此外,它还实现了包括电源管理、模块认证等高级功能。
WinCE的启动过程为:CPU执行引导向量,跳转到硬件初始化代码,即Startup函数。
在Startup函数完成最小硬件环境初始化后跳转到KernelStart函数来对内核进行初始化;KernelStart函数调用 OEMInitDebugSerial完成对调试串口的初始化,调用OEMInit函数来完成硬件初始化工作以及设置时钟、中断,调用 OEMGetExtensionDRAM函数来判断是否还有另一块DRAM。
因此,实时时钟驱动实现代码是在OAL层实现的,当Windows CE启动时,会调用实时时钟函数来初始化系统时间,下面介绍这些函数的具体实现。

3.2 时钟函数
实现RTC功能需要编写3个函数,分别是OEMGetRealTime()、OEMSetRealTime()与OEMSetAlarmTime()。下面对于这三个函数分别介绍。
OEMGetRealTime()得到当前时间。此函数名不可更改,是WinCE内核规定好了的,也就是当内核需要知道当前时间的时候直接调用此函数。图3为函数OEMGetRealTime()执行流程。

由于RTC不能任意地修改,不然会造成时间的混乱,所以每次获取时间或者设置时间完毕以后必须禁止RTC,具体是通过设置RTC使能/禁止寄存器实现的。 而在每次读取时间或者设置时间的时候必须先使用它。在读取时间的时候若读取的“秒”为0必须重新读取时间,因此时的“分”已经被进位了。
OEMSetRealTime()设置时间。与OEMGetRealTime()一样,它也不可改名,通过此函数核心可以直接修改时间。也就是说,如果用户点击WinCE任务栏中的时间以后,修改时间最终都是调用此函数。
OEMSetAlarmTime()设置系统报警时间,其参数为指向含有SYSTEMTIME结构体缓冲区的长指针。如果此函数执行成功则返回TRUE, 执行失败则返回FALSE。此函数必须是可重人的以防止对硬件的多次操作。对于一般用户的操作,用户可以不用编写此函数。如果需要系统在特定的时间完成特 定的功能就需要完成此函数的编写。
下面给出OEMGetRealTime()的源代码仅供参考。
OEMGetRealTime(LPSYSTEMTIME lpst)
{
volatile RTCreg *s2440RTC;
s2440RTC = (RTCreg *)RTC_BASE;
//RETAILMSG(1,(_T("OEMGetRealTime ")));
//使能RTC
s2440RTC->rRTCCON =0x1;
lpst->wMilliseconds=0;
lpst->wSecond= FROM_BCD(s2440RTC->rBCDSEC&0x7f);
lpst->wMinute= FROM_BCD(s2440RTC->rBCDMIN&0x7f);
lpst->wHour= FROM_BCD(s2440RTC->rBCDHOUR&0x3f);
lpst->wDayOfWeek=(s2440RTC->rBCDDATE-1);
lpst->wDay= FROM_BCD(s2440RTC->rBCDDAY&0x3f);
lpst->wMonth=FROM_BCD(s2440RTC->rBCDMON&0x1f);
//lpst->wYear=(2000+s2440RTC->rBCDYEAR);
lpst->wYear=FROM_BCD(s2440RTC->rBCDYEAR)+2000;
if(lpst->wSecond==0)
{
lpst->wSecond=FROM_BCD(s2440RTC->rBCDSEC&0x7f);
lpst->wMinute=FROM_BCD(s2440RTC->rBCDMIN&0x7f);
lpst->wHour=FROM_BCD(s2440RTC->rBCDHOUR&0x3f);
lpst->wDayOfWeek=(s2440RTC->rBCDDATE-1);
lpst->wDay=FROM_BCD(s2440RTC->rBCDDAY&0x3f);
lpst->wMonth=FROM_BCD(s240RTC->rBCDMON&0x1f);
lpst->wYear=(2000+s240RTC->rBCDYEAR);
}
//禁止RTC
s2440RTC->rRTCCON=0;
return TRUE;
}
3.3 系统I/O
OAL代码层提供了与内核交互的函数,通过它内核可以获得硬件平台的信息。在OAL层中,完成此功能的函数为OEMIOcontrol()。其函数原型如下:
Bool OEMIoContol(……)
{switch(dwIoContro1)
{case IOCTL_HAL_INIT_RTC;
if(nInBufSize>= sizeof(SYSTEMTIME))
return OEMSetRealTime((LPSYSTEMTIME)lpInBuf);
else
return FALSE;
break;
……
default: return FALSE;
}
WinCE每次启动时都会由KernelIoContrl()函数调用OEMIOcontrol(),完成底层硬件信息的读取,其中参数 dwIoControl为内核与OAL通信的控制代码,通过它可以完成硬件信息的读取。控制代码一般都是微软定义好的,其中RTC模块定义的控制代码为 IOCTL_HAL_INIT_RTC,通过它内核可以完成底层RTC模块的初始化。
nInBufSize是由lpInBuf(指针)指向的缓冲区的大小,缓冲区是按字节大小计算的。SYSTEMTIME是WinCE内部定义的一个表示时 间的结构体,LPSYSTEMTIME为指向此结构体的指针。SYSTEMTIME结构体原型如下,原型中定义了字格式的年、月、星期、日、时、分、秒、 毫秒。
typedef struct _SYSTEMTIME
{
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSeeond;
WORD wMilliseconds;
}SYSTEMTIME;
在本设计中,RTC的时间分辨率为“秒”,这是因为S3C2440的RTC模块所能提供的最小时间基准就是“秒”。用户可以根据实际需求编写系统I/O下 的RTC初始化代码,也可以禁止这部分代码。若WinCE从OAL层读不到时钟参数的话,它会以系统的默认时间值来初始化SYSTEMTIME结构体。

4 结束语
当前比较流行的ARM嵌入式处理器,如Samsung的S3C系列、Intel的Xscale系列、Motorola的龙珠系列等几乎都内嵌有RTC模 块。使许多嵌入式产品如手机、PDA等的时间显示丰富多彩,如具有显示阳历、阴历、万年历等功能。本文给出了RTC模块的WinCE驱动程序实现,基于本 设计可以进一步开发如时钟界面等时钟应用功能,以满足多姿多彩的嵌入式系统对于时钟功能的应用需求。

http://www.rosoo.net/a/embedded_o/200912/8192.html

  评论这张
 
阅读(252)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017