ARM-Linux驱动--RTC(实时时钟)驱动分析


硬件平台:FL2440(S3C2440)

内核版本:Linux 2.6.28

主机平台:Ubuntu 11.04

内核版本:Linux 2.6.39

交叉编译器版本:arm-linux-gcc 3.4.1

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中,如下

  1. <span style="font-size:16px;">struct platform_driver {  
  2.     int (*probe)(struct platform_device *);  
  3.     int (*remove)(struct platform_device *);  
  4.     void (*shutdown)(struct platform_device *);  
  5.     int (*suspend)(struct platform_device *, pm_message_t state);  
  6.     int (*suspend_late)(struct platform_device *, pm_message_t state);  
  7.     int (*resume_early)(struct platform_device *);  
  8.     int (*resume)(struct platform_device *);  
  9.     struct pm_ext_ops *pm;  
  10.     struct device_driver driver;  
  11. };</span>  
驱动中定义对应的结构体
  1. static struct platform_driver s3c2410_rtc_driver = {  
  2.     .probe      = s3c_rtc_probe,//RTC探测函数   
  3.     .remove     = __devexit_p(s3c_rtc_remove),//RTC移除函数   
  4.     .driver     = {  
  5.         .name   = "s3c2410-rtc",  
  6.         .owner  = THIS_MODULE,  
  7.     },  
  8. };  
下面是驱动中驱动的初始化和退出函数
  1. static int __init s3c_rtc_init(void)  
  2. {  
  3.     printk(banner);  
  4.     return platform_driver_register(&s3c2410_rtc_driver);  
  5. }  
  6.   
  7. static void __exit s3c_rtc_exit(void)  
  8. {  
  9.     platform_driver_unregister(&s3c2410_rtc_driver);  
  10. }  

platform_driver_register()和platform_driver_unregister()函数在/drivers/base/platform.c中实现的。

可以看出,platform_driver_register()函数的作用就是为platform_driver中的driver中的probe、remove等提供接口函数

  1. int platform_driver_register(struct platform_driver *drv)  
  2. {  
  3.     drv->driver.bus = &platform_bus_type;  
  4.     if (drv->probe)  
  5.         drv->driver.probe = platform_drv_probe;  
  6.     if (drv->remove)  
  7.         drv->driver.remove = platform_drv_remove;  
  8.     if (drv->shutdown)  
  9.         drv->driver.shutdown = platform_drv_shutdown;  
  10.     if (drv->suspend)  
  11.         drv->driver.suspend = platform_drv_suspend;  
  12.     if (drv->resume)  
  13.         drv->driver.resume = platform_drv_resume;  
  14.     if (drv->pm)  
  15.         drv->driver.pm = &drv->pm->base;  
  16.     return driver_register(&drv->driver);//注册老的驱动   
  17. }  
-----------------------------------------------
  1. void platform_driver_unregister(struct platform_driver *drv)  
  2. {  
  3.     driver_unregister(&drv->driver);  
  4. }  
  • 1
  • 2
  • 3
  • 下一页

相关内容