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 将系统时间同步到硬件时间