// 適当に システム時間を RTC に同期(?)させるプログラム。 #define _BSD_SOURCE #include #include #include #include #include #include #include #include #include time_t rtc_time2time_t(struct rtc_time * rtc) { struct tm temp_tm; memset(&temp_tm, 0, sizeof(temp_tm)); temp_tm.tm_sec = rtc->tm_sec; temp_tm.tm_min = rtc->tm_min; temp_tm.tm_hour = rtc->tm_hour; temp_tm.tm_mday = rtc->tm_mday; temp_tm.tm_mon = rtc->tm_mon; temp_tm.tm_year = rtc->tm_year; return mktime(&temp_tm); } int main(void) { int fd, res; struct rtc_time cur_rtc; struct timeval cur_sys; time_t cur_rtc_sec; struct timeval delta, old_delta; unsigned long tmp; fd = open("/dev/rtc", O_RDONLY); if(fd == -1) { fprintf(stdout, "open rtc device error :%d [%s]\n", errno, strerror(errno)); return(errno); } if(ioctl(fd, RTC_UIE_ON, 0) == -1) // RTC interrupt 1/s on. { fprintf(stdout, "ioctl RTC_UIE_ON error :%d [%s]\n", errno, strerror(errno)); close(fd); return(errno); } res = read(fd, &tmp, sizeof(tmp)); // Wait RTC update interrupt. if (res == -1) { fprintf(stdout, "read error :%d [%s]\n", errno, strerror(errno)); close(fd); return(errno); } if(ioctl(fd, RTC_UIE_OFF, 0) == -1) // RTC interrupt 1/s off. { fprintf(stdout, "ioctl RTC_UIE_OFF error :%d [%s]\n", errno, strerror(errno)); close(fd); return(errno); } if(ioctl(fd, RTC_RD_TIME, &cur_rtc) == -1) // Read RTC. { fprintf(stdout, "ioctl RTC_RD_TIME error :%d [%s]\n", errno, strerror(errno)); close(fd); return(errno); } gettimeofday(&cur_sys, NULL); cur_rtc_sec = rtc_time2time_t(&cur_rtc); delta.tv_sec = (long)cur_rtc_sec - (long)cur_sys.tv_sec; delta.tv_usec = (long)delta.tv_sec <= 0 ? (long)cur_sys.tv_usec * (-1) : (long)(1000000 - cur_sys.tv_usec); if(adjtime(&delta, &old_delta)) // Adjust system time. { fprintf(stdout, "adjtime error :%d [%s]\n", errno, strerror(errno)); close(fd); return(errno); } fprintf(stdout, "adjtime :sys = %ld.%06ld, rtc = %ld, (old delta = %s%ld.%06ld)\n", (long) cur_sys.tv_sec, (long) cur_sys.tv_usec, cur_rtc_sec, (long)old_delta.tv_sec < 0 || (long)old_delta.tv_usec < 0 ? "-" : "+", abs((long)old_delta.tv_sec), abs((long)old_delta.tv_usec)); close(fd); return(0); }