1 前言
觉得Imx6内部的RTC时钟不是很准,于是外置RTC芯片ds3231
在源码里一查, 发现在driver/rtc/rtc-ds1307.c中
2 修改设备树
ds3231地址可以查询数据表: 0xd0 , 但是linux 设备树要右移一位, 于是就成了0x68
也可以通过i2ctest来检测地址
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
status = "okay";
/* EEPROM */
at24c512c@50 {
compatible = "at24c512c";
reg = <0x50>;
status = "ok";
};
/* 时钟芯片 */
ds3231mz@68 {
compatible = "dallas,ds3232";
reg = <0x68>;
status = "ok";
};
2 修改内核支持
source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi
#配置defconfig文件
make imx_v7_defconfig -j 16
make menuconfig
#编译内核模块
make modules -j 16
3 应用测试
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/rtc.h>
#include <sys/ioctl.h>
int main(int argc, char** argv)
{
int fds1302, ret;
struct rtc_time rtc_tm;
int fd, retvalue;
char *filename;
if(argc != 2){
printf("Error Usage!\r\n");
return -1;
}
filename = argv[1];
/* 打开led驱动 */
fds1302 = open(filename, O_RDWR);
if(fd < 0){
printf("file %s open failed!\r\n", argv[1]);
return -1;
}
ret = ioctl(fds1302, RTC_RD_TIME, &rtc_tm);
printf("ret:%d\r\n",ret);
if(ret == 0)
{
printf("Time: %04d-%02d-%02d %02d:%02d:%02d\n", rtc_tm.tm_year+1900, rtc_tm.tm_mon+1,
rtc_tm.tm_mday, rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
}
else{
memset(&rtc_tm, 0, sizeof(struct rtc_time));
rtc_tm.tm_year = 2013 - 1900;
rtc_tm.tm_mon = 5 - 1;
rtc_tm.tm_mday = 10;
rtc_tm.tm_hour = 14;
rtc_tm.tm_min = 18;
rtc_tm.tm_sec = 59;
ret = ioctl(fds1302, RTC_SET_TIME, &rtc_tm);
}
return 0;
}
第一次打开会写入时间, 之后打开就是读取时间
把纽扣电池上了之后, 断电也能读取时间
读取时间:
hwclock -f /dev/rtc1
同步系统时间到RTC
hwclock -f /dev/rtc1 -w
hwclock -s 将硬件时间同步到系统时间
hwclock -w 将系统时间同步到硬件时间