RTC驱动调试
本文记录之前做驱动移植工作时调试RTC的一些总结,Platform: RK3368 OS: Android 7.1 RTC:hym8563
/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有关的数据结构 |
设备地址及配置:
模块 hym8563,总线地址: 1010 001 R/W
右移一位得:0101 0001 —> reg = <0x51>
dts 配置
hym8563@51 {
compatible = "haoyu,hym8563";
reg = <0x51>;
#clock-cells = <0>;
};
板子上的设备路径 /sys/bus/i2c/devices/3-0051
class 设备节点 /sys/class/rtc/rtc0
rockchip:/sys/class/rtc/rtc0 $ ls
date device max_user_freq power subsystem uevent
dev hctosys name since_epoch time wakealarm
rockchip:/sys/class/rtc/rtc0 $ cat time
11:33:54
rockchip:/sys/class/rtc/rtc0 $ cat date
2019-01-16
rockchip:/sys/class/rtc/rtc0 $ cat name
hym8563
rockchip:/sys/class/rtc/rtc0 $ cat max_user_freq
64
rockchip:/sys/class/rtc/rtc0 $ cat uevent
MAJOR=253
MINOR=0
DEVNAME=rtc0
驱动路径 /sys/bus/i2c/drivers/rtc-hym8563/3-0051
注册成功;
测试rtc模块的 i2c总线时钟, 输入 hwclock -w 回车检测时钟引脚的波形变化
RTC驱动代码分析:
断电之后上电时RTC的系统时间设置函数位于 drivers/rtc/hctosys.c
/*
* RTC subsystem, initialize system time on startup
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/rtc.h>
static int __init rtc_hctosys(void)
{
int err = -ENODEV;
struct rtc_time tm;
struct timespec64 tv64 = {
.tv_nsec = NSEC_PER_SEC >> 1,
};
struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
if (rtc == NULL) {
pr_info("unable to open rtc device (%s)\n",
CONFIG_RTC_HCTOSYS_DEVICE);
goto err_open;
}
err = rtc_read_time(rtc, &tm);
if (err) {
dev_err(rtc->dev.parent,
"hctosys: unable to read the hardware clock\n");
goto err_read;
}
tv64.tv_sec = rtc_tm_to_time64(&tm);
err = do_settimeofday64(&tv64);
/*
* 上电启动内核时打印 RTC 系统时间设置情况
*/
dev_info(rtc->dev.parent,
"setting system clock to "
"%d-%02d-%02d %02d:%02d:%02d UTC (%lld)\n",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec,
(long long) tv64.tv_sec);
err_read:
rtc_class_close(rtc);
err_open:
rtc_hctosys_ret = err;
return err;
}
late_initcall(rtc_hctosys);
执行上面函数在内核中打印的信息如下:
rockchip:/ $ dmesg | grep rtc
[ 1.086439] rtc-hym8563 3-0051: rtc core: registered hym8563 as rtc0
[ 2.150024] rtc-hym8563 3-0051: setting system clock to 2019-01-16 11:18:42 UTC (1547637522)
// 在给设备上电时,首先将系统时间设定为 2019-01-16 11:18:42 UTC
// 然后由系统运行 RTC
rockchip:/ $ date
Wed Jan 16 11:19:13 GMT 2019
i2c 总线初始化设备函数位于 drivers/rtc/rtc-hym8563.c
static int hym8563_init_device(struct i2c_client *client)
{
int ret;
/* Clear stop flag if present */
ret = i2c_smbus_write_byte_data(client, HYM8563_CTL1, 0); // 写入控制寄存器 0
if (ret < 0)
return ret;
ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2); //读取状态寄存器,返回0初始化成功
if (ret < 0)
return ret;
/* Disable alarm and timer interrupts */
ret &= ~HYM8563_CTL2_AIE;
ret &= ~HYM8563_CTL2_TIE;
/* Clear any pending alarm and timer flags */
if (ret & HYM8563_CTL2_AF)
ret &= ~HYM8563_CTL2_AF;
if (ret & HYM8563_CTL2_TF)
ret &= ~HYM8563_CTL2_TF;
ret &= ~HYM8563_CTL2_TI_TP;
return i2c_smbus_write_byte_data(client, HYM8563_CTL2, ret);
}
对上层提供接口: /dev/rtc0
参考文章:
rtc 晶振不起振问题:
https://www.cnblogs.com/Pual623548198/p/6683934.html
https://blog.csdn.net/u010278579/article/details/47303297?utm_source=blogxgwz1
https://blog.csdn.net/weiwei_xiaoyu/article/details/82819864
RTC时钟驱动:https://www.cnblogs.com/wanghuaijun/p/7189733.html
RTC相关寄存器: http://tech.hqew.com/fangan_1852073
设备树配置:https://www.cnblogs.com/fah936861121/articles/6908230.html
https://www.cnblogs.com/lifexy/p/7839625.html