我们板子上一般带有一个RTC模块,实时时钟,你断电之后,里面的时钟还是会维持的,就像你的手机,关了机或者拔了电池之后里面实际上还有个备份时钟,维持里面的一个时钟模块在运行,这样就可以保持你的时间了。我们来看一下原理图
这个电池是给RTC模块用的,你开发板即使关了电RTC模块还是会运行的,RTC模块耗电非常少,一小块电池就可以维持1 2年了
我们每次data一次 如果RTC工作了,那么时间就会变
我们来看看rtc的驱动
在内核下的rtc-s3c.c
看一个驱动从入口函数开始看
入口函数就是注册一个平台驱动
我们关心它的probe函数,我们说如果内核里面有同名的平台设备的话probe函数才会被调用
我们来看一下probe函数做了什么事情
从平台设备中获得某些信息
看下面是注册一个rtc_device
进入这个函数看一下这个函数做了什么事情
给你提供一个ops,我们来看一下这个ops
这里面应该就是硬件相关,读时间,设置时间,读闹钟,设置闹钟等等这些函数
在这个函数里面要操作你板子的RTC模块
我们来分析其框架
static int __init s3c_rtc_init(void)
--------------------
platform_driver_register(&s3c_rtc_driver);
--------------------
static int __devinit s3c_rtc_probe(struct platform_device *pdev)
--------------------
做了很多硬件相关的操作之后
注册一个rtc设备
rtc_device_register("s3c", &pdev->dev, &s3c_rtcops,THIS_MODULE);
这个函数在class.c里面
所以这里就分为了两层
rtc_device_register
drivers/rtc/class.c rec-dev.c <----------------------------------------------rtc_s3c.c
我们先看一看class.c做了什么事情
入口函数创建一个类
我们看一下rtc_dev_init这个函数
动态分配一个设备号
从这里可以看出最多有16个次设备号
我们看下rtc_device_register这个函数,里面这么一个函数调用
prepare准备,看看这个函数做了什么事情
cdev_init就出来了
然后退出这个函数接着往回看
rtc_dev_add_device
看看这个函数做了什么事情
cdev_add就出来了
我们来看看这个fops( cdev_init(&rtc->char_dev, &rtc_dev_fops);)
假设我们读时间
第一步得到一个RTC结构体,
我们在rtc_s3c.c的时候
带入了一个说rtc_ops
假设进行如下操作
app:open(“/dev/rtc0”)
------------------------------
KERNEL:sys_open
rtc_dev_fops->open
这里第一句根据次设备号得到一个rtc_device结构体,
如果有open函数就调用它的open函数
在看看读时间
app:read
-------------------------
kernel:sys_read
rtc_dev_fops->read
看看read函数做了什么事情
首先还是得到这个结构体
然后是将这个进程放入等待队列里面来
设置当前进程为休眠状态
但是这个函数不是很明了
一般我们都是用ioctl来做的
我们来看一看
比如说我想设置时间
比如说我要读取时间
首先在ioctl的第一句就是
得到rtc_device结构体
然后我们看看rtc_read_time这个函数
在看看__rtc_read_time函数
这里就调用了我们底层的read函数
date是显示系统时间
设置系统时间为12月30号15点40分2011年30秒
date 123015402011.30
把系统时间写入RTC芯片是用
hwclock -w
然后重启 执行date命令
然后时间就变了