rtc驱动模型及rx8025驱动学习
rtc驱动模型及rx8025驱动学习
一、芯片简单了解
RX8025-T是一款
拥有I2C接口和温度补偿功能的新型实时时钟芯片
,内部集成32.768KHz温度补偿晶体振荡器,可用于各种需要高精度时钟的场合。通过设置相应补偿的控制位,可以实现不同间隔的温度补偿功能,从而大大提高了时钟的精度。芯片可设置四种不同的时段进行温度补偿,默认设置是2S补偿。该芯片采用C-MOS工艺生产,具有极低的功能消耗,可长期使用电池供电。
芯片特点:
1.内置高稳定度的32.768KHz 的DTCXO (数字温度补偿晶体振荡器)
2. 支持I2C 总线的高速模式(400K)
3. 定时报警功能(可设定:天,日期,小时,分钟)
4. 固定周期定时中断功能。
5. 时间更新中断功能。
6. 32.768KHz频率输出(具有使能OE功能)
7. 闰年自动调整功能。(2000 到2099)
8. 宽范围接口电压:2.2V 到 5.5V
9. 宽范围的时间保持电压:1.8V 到 5.5V
10. 低电流功耗:0.8uA/3V (Typ.)
11. 工作温度:-45℃~85℃
操作模式:
1)实时时钟模式
该功能被用来设定和读取年,月,日,星期,时,分,秒 时间信息。年份为后两位数字表示, 任何可以被4 整除的年份被当成闰年处理。(2000 年到2099 年)
2)固定周期的中断发生功能:
固定周期定时中断发生功能可以产生一个固定周期的中断事件,固定周期可在244.14uS 到 4095 分钟之间的 任意时间设定。
3) 定时更新中断功能:
该功能可以根据内部时钟的定时设定,每秒或每分钟产生一个中断事件。 当中断事件产生,UF 标志位的值变成 1 同时/INT 引脚变成低电平表示一个中断事件的产生。
4)闹钟中断功能:
该功能可以根据报警设定来产生一个中断。
5)32.768K Hz 时钟输出:
可以通过FOUT 引脚来输出一个32.768kHz 频率的时钟信号,该功能可以通过FOE 引脚控制。
6)和CPU 的接口功能:
数据的读写都是通过I2C 总线接口的方式来完成。
二、开发板硬件相关
芯片设计原理图:
与主控芯片连接关系:
设备树中定义:
三、RTC设备驱动模型学习
驱动模型结构
与RTC核心有关的文件有:
/drivers/rtc/class.c 这个文件向linux设备模型核心
注册了一个类RTC
,然后向驱动程序提供了注册/注销接口
/drivers/rtc/rtc-dev.c 这个文件定义了基本的设备文件操作函数,如:open,read等
/drivers/rtc/interface.c 顾名思义,
这个文件主要提供了用户程序与RTC驱动的接口函数,用户程序一般通过ioctl与RTC驱动交互,这里定义了每个ioctl命令需要调用的函数
/drivers/rtc/rtc-sysfs.c 与sysfs有关
/drivers/rtc/rtc-proc.c 与proc文件系统有关
/include/linux/rtc.h 定义了与RTC有关的数据结构
RTC驱动模型结构如下图:(可以看出对于rtc的开发就是对具体的芯片的驱动开发,与应用层交互的字符设备部分内核已经提供,只需建立起相应联系即可)
内核提供的的基本数据结构:
1. struct rtc_device 结构
这个结构是RTC驱动程序的基本数据结构,但是他不像其他核心的基本结构一样,驱动程序以他为参数调用注册函数注册到核心。这个结构是由注册函数返回给驱动程序的。
2. struct rtc_class_ops 结构
这个结构是RTC驱动程序要实现的基本操作函数,注意这里的操作不是文件操作。驱动程序通过初始化这样一个结构,将自己实现的函数与RTC核心联系起来。这里面的大部分函数都要驱动程序来实现。而且这些函数都是操作底层硬件的,属于最底层的函数。
3. struct rtc_time 结构
代表了时间与日期,从RTC设备读回的时间和日期就保存在这个结构体中
4.注册:
为底层驱动提供接口:
rtc_device_register,rtc_device_unregister
四、rx8025驱动分析
首先在probe函数做了如下的工作:
然后实现rx8025读写寄存器的函数,(这里提供了读连续地址的数据的操作函数)
接下来就是填充struct rtc_class_ops结构体的函数:(具体就是对寄存器的操作)
在rtc8025驱动中没有对于相关的字符驱动的函数,所以需要做进一步的分析:
应用层调用关系解读:(具体的字符设备接口函数在rtc-dev.c中实现)
在probe函数中 rtc_device_register()注册rtc时,中会调用rtc_dev_prepare(rtc)函数,
r
tc_dev_prepare()函数rtc-dev.c中定义,这就是对具体的字符设备的初始化,从而将
struct rtc_class_ops结构体的函数与struct file_operations rtc_dev_fops结构体中的函数建立起了联系。
当用户open时会调用 rtc_class_ops 中的open,open则会调用到rtc_class_ops中定义的open,如下:
其中应用层使用核心的是ioctl函数,例如以下的指令调用:(
调用了
中的rtc_read_time和rtc_set_time函数
)
阅读ioctl会发现每个指令都会调用/drivers/rtc/interface.c 中定义的函数,以RTC_RD_TIME命令的rtc_read_time()为例,继续追踪:
调用了__rtc_read_time();
如上图绿色框,最终是调用了rx8025中struct rtc_class_ops中定义实现的函数,即我们写的读时间函数。
所以
最终结论
就是:rtc驱动开发只需要去实现
struct rtc_class_ops结构体的函数即可,具体与应用层交互的字符驱动函数,linux内核在
rtc-dev.c中定义
已经提供,其会产生相应节点为rtc(x)。