ARMLinux驱动RTC(实时时钟)驱动分析
内核版本:Linux 2.6.28
主机平台:Ubuntu 11.04
内核版本:Linux 2.6.39
交叉编译器版本:arm-linux-gcc 3.4.1
原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/6584285
1、实时时钟概述
实时时钟(RTC)单元可以在断电的情况下使用纽扣电池继续计时工作。RTC使用STRB/LDRB ARM操作传输二进制码十进制数的8位数据给CPU。其中的数据包括秒、分、时、日期、天、月、年的时间信息。可以执行报警功能。
2、实时时钟操作
下面是RTC模块的电路图
3、RTC寄存器介绍
实时时钟控制寄存器(RTCCON)-REAL TIME CLOCK CONTROL REGISTER
节拍时间计数寄存器(TICNT)-TICK TIME COUNT REGISTER
RTC报警控制寄存器(RTCALM)-RTC ALARM CONTROL REGISTER
报警秒数寄存器(ALMSEC)-ALARM SECOND DATA REGISTER
报警分钟计数寄存器(ALMMIN)-ALARM MIN DATA REGISTER
报警小时数据寄存器(ALMHOUR)-ALARM HOUR DATA REGISTER
报警日期数据寄存器(ALMDATE)-ALARM DATE DATA REGISTER
报警月数数据寄存器(ALMMON)-ALARM MON DATA REGISTER
报警年数数据寄存器(ALMYEAR)-ALARM YEAR DATA REGISTER
BCD数据寄存器的格式和报警寄存器结构相同,只是对应的地址不同。
BCD秒寄存器(BCDSEC)-BCD SECOND REGISTER 地址:0x57000070(L)0x57000073(B)
BCD分寄存器(BCDMIN)-BCD MINUTE REGISTER 地址:0x57000074(L)0x57000077(B)
BCD小时寄存器(BCDHOUR)-BCD HOUR REGISTER 地址:0x57000078(L)0x5700007B(B)
BCD日期寄存器(BCDDATE)-BCD DATE REGISTER 地址:0x5700007C(L)0x5700007F(B)
BCD日寄存器(BCDDAY)-BCD DAY REGISTER 地址:0x57000080(L)0x57000083(B)
BCD月寄存器(BCDMON)-BCD MONTH REGISTER 地址:0x57000084(L)0x57000087(B)
BCD年寄存器(BCDYEAR)-BCD YEAR REGISTER 地址:0x57000088(L)0x5700008B(B)
4、驱动实例分析
为了使驱动更容易理解,现在这个RTC驱动只完成了计时功能,没有添加相应的报警功能,也没有添加电源管理的功能,缺少的功能今后完善。
下面先总体了解驱动:
首先是RTC驱动的结构体,在/include/linux/platform_device.h中,如下
struct platform_driver {int (*probe)(struct platform_device *);int (*remove)(struct platform_device *);void (*shutdown)(struct platform_device *);int (*suspend)(struct platform_device *, pm_message_t state);int (*suspend_late)(struct platform_device *, pm_message_t state);int (*resume_early)(struct platform_device *);int (*resume)(struct platform_device *);struct pm_ext_ops *pm;struct device_driver driver;};驱动中定义对应的结构体
static struct platform_driver s3c2410_rtc_driver = {.probe = s3c_rtc_probe,//RTC探测函数.remove = __devexit_p(s3c_rtc_remove),//RTC移除函数.driver = {.name = "s3c2410-rtc",.owner = THIS_MODULE,},};下面是驱动中驱动的初始化和退出函数
static int __init s3c_rtc_init(void){printk(banner);return platform_driver_register(&s3c2410_rtc_driver);}static void __exit s3c_rtc_exit(void){platform_driver_unregister(&s3c2410_rtc_driver);}
platform_driver_register()和platform_driver_unregister()函数在/drivers/base/platform.c中实现的。
可以看出,platform_driver_register()函数的作用就是为platform_driver中的driver中的probe、remove等提供接口函数
int platform_driver_register(struct platform_driver *drv){drv->driver.bus = &platform_bus_type;if (drv->probe)drv->driver.probe = platform_drv_probe;if (drv->remove)drv->driver.remove = platform_drv_remove;if (drv->shutdown)drv->driver.shutdown = platform_drv_shutdown;if (drv->suspend)drv->driver.suspend = platform_drv_suspend;if (drv->resume)drv->driver.resume = platform_drv_resume;if (drv->pm)drv->driver.pm = &drv->pm->base;return driver_register(&drv->driver);//注册老的驱动}
void platform_driver_unregister(struct platform_driver *drv){driver_unregister(&drv->driver);}
接下来是RTC平台驱动探测函数s3c_rtc_probe,下面函数定义的时候使用了__devinit的作用是使编译器优化代码,将其放在和是的内存位置,减少内存占用和提高内核效率。
probe函数接收到plarform_device
ARMLinuxRTC实时时 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)