本文的部分内容取自内核文档。
Linux有两个用户空间的RTC API,他们是
* /dev/rtc... 兼容PC系统的RTC,对非x86结构支持不完整。
* /dev/rtc0,/dev/rtc1 ... 系统框架的一部分,支持多种RTC
老的兼容PC/AT驱动:/dev/rtc
所有的pc系统都内建实时时钟。这个时钟在系统关机之后可以保存时间和日期。特别之处,用户进程可以通过/dev/rtc的read(2) 或是select(2)监视中断,同时他会阻塞/停止用户进程,直到下一个中断接受。这个对于高速数据采集避免CPU占用100%是很有效果的方法。
新的借口“RTC Class”驱动:/dev/rtcN
由于Linux支持多种非ACPI和非PC平台,它可能包含不只一种RTC时钟,所以Linux就需要一个新的RTC接口解决这些问题。RTC Class结构包含多种RTCs,它的范围从内部集成RTC到使用I2C、SPI或是其他总线与CPU主机通讯的独立芯片。Linux提供三个不同的用户空间接口:
* /dev/rtcN... 类似老的/dev/rtc接口
* /sys/class/rtc/rtcN... sysfs支持只读访问RTC
* /proc/driver/rtc... 首个RTC(rtc0)使用procfs接口访问它,这个要比sysfs包含的信息多
Sysfs接口
Sysfs接口在/sys/class/rtc/rtcN文件夹下不需ioctls就可以访问多种rtc属性。内容如下
date: RTC日期
hctosys: 1 通过RTC内核设置CONFIG_RTC_HCTOSYS产生一个系统时间,提供启动使用
0 不产生
max_user_freq: RTC 提供给未授权用户的最大中断数
name: RTC名
since_epoch: epoch访问RTC时的秒数
time: RTC时间
wakealarm: 定时产生一个系统唤醒事件。如果一个唤醒事件被申请,系统重起。
IOCTL接口
Ioctl()支持RTC Class结构也支持/dev/rtc,尽管芯片和系统不是标准化的,PC/AT功能可能会不支持。同样的,一些新特性可能在ACPI和RTC Class结构中支持但是在老的驱动中部支持。
* RTC_RD_TIME,RTC_SET_TIME ... 每个RTC至少支持读时间返回日期和时间结果
* RTC_AIE_ON,RTC_AIE_OFF, RTC_ALM_SET, RTC_ALM_READ ... 当RTC连接上一个中断线,它可以在未来24小时发送一个报警中断(使用RTC_WKALM_*).
* RTC_WKALM_SET,RTC_WKALM_RD ... 在24小时内发送一个警告
* RTC_UIE_ON,RTC_UIE_OFF ... 如果RTC提出中断,他可能在“秒”计数变化时提出一个中断刷新。
* RTC_PIE_ON,RTC_PIE_OFF, RTC_IRQP_SET, RTC_IRQP_READ ... another feature often accessiblewith an IRQ line is a periodic IRQ, issued at settable frequencies (usually 2^NHz).
* RTC_RD_TIME,RTC_SET_TIME: read_time/set_time 功能调用.
* RTC_ALM_SET,RTC_ALM_READ, RTC_WKALM_SET, RTC_WKALM_RD: set_alarm/read_alarm 功能调用.
* RTC_IRQP_SET,RTC_IRQP_READ: irq_set_freq 功能调用。设置并读取rtc_device中的irq_freq频率。你的驱动需要在启动时初始化irq_freq。确保申请频率在irq_set_freq功能的范围。如果失败,返回-EINVAL。如果没有改变频率,不要定义irq_set_freq。
* RTC_PIE_ON,RTC_PIE_OFF: irq_set_state 功能调用.
读取时钟的简单例程:
RTC的设备注册过程,只要在批量处理platform_device中添加RTC设备即可:
staticstruct platform_device *mini6410_devices[] __initdata = {
…
#endif
#ifdefCONFIG_S3C_DEV_RTC
&s3c_device_rtc,
#endif
…
}
用户空间测试程序:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/rtc.h>
#include <sys/time.h>
#include <sys/ioctl.h>
int main(){
intfd;
structrtc_time rtc;
fd= open("/dev/rtc0", O_RDONLY);
if(!fd){
perror("Opening rtc0");
exit(EXIT_FAILURE);
}
ioctl(fd,RTC_RD_TIME,&rtc);
printf("\n\nCurrentRTC data/time is %d-%d-%d, %02d:%02d:%02d.\n", rtc.tm_mday, rtc.tm_mon +1,rtc.tm_year + 1900, rtc.tm_hour, rtc.tm_min, rtc.tm_sec);
close(fd);
exit(EXIT_SUCCESS);
}