这篇文章主要介绍“Linux应用层系统时间写入RTC时钟的办法”,在日常操作中,相信很多人在Linux应用层系统时间写入RTC时钟的办法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Linux应用层系统时间写入RTC时钟的办法”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
一、写入时间
1、预备知识:
a、mktime
头文件:#include <time.h>
函数:time_t mktime(struct tm *timeptr)
函数说明:mktime()用来将timeptr所指的tm结构体数据换成从公元1970年1月1日0时0分0 秒算起至今的本地时间所经过的秒数。
返回值:返回经过的秒数。当发生错误的时候,返回-1。
b、settimeofday
头文件:#include <sys/time.h>
#include <unistd.h>
函数:int settimeofday(const struct timeval *tv,const struct timezone *tz)
函数说明:settimeofday()会把目前时间设成由tv所指的结构体信息,当地时区信息则设成tz所指的结构体。
返回值:只有root权限才能使用此函数修改时间。成功则返回0,失败返回-1,错误代码存于errno。
2、实践:
通过mktime和settimeofday配合使用,即可完成时间的写入。
3、代码如下:
#include <stdio.h>#include <time.h>#include <sys/time.h>#include <unistd.h>#include <stdlib.h>#include <bits/types.h>#include <linux/rtc.h>struct my_timeval { __time_t tv_sec; __suseconds_t tv_usec; };/************************************************* *函数名 : System_SetTime *功能 : 写入系统时间 *使用方法 : char* dt = "2016-04-15 21:00:00"; System_SetTime(dt); **************************************************/int System_SetTime(char* dt) {struct rtc_time tm;struct tm _tm;struct my_timeval tv; time_t timep;sscanf(dt,"%d-%d-%d %d:%d:%d",&tm.tm_year,&tm.tm_mon,&tm.tm_mday,&tm.tm_hour,&tm.tm_min,&tm.tm_sec); _tm.tm_sec = tm.tm_sec; _tm.tm_min = tm.tm_min; _tm.tm_hour = tm.tm_hour; _tm.tm_mday = tm.tm_mday; _tm.tm_mon = tm.tm_mon - 1; _tm.tm_year = tm.tm_year - 1900; timep = mktime(&_tm); tv.tv_sec = timep; tv.tv_usec = 0;if(settimeofday(&tv, (struct timezone *) 0) < 0) {printf("Set system datetime error!\n");return -1; } return 0; }void main(void) {char *dt = "2016-4-15 21:00:00"; System_SetTime(dt); }
4、测试结果:
二、保存时间
从上面的测试结果可以看出,可以正常写入系统时间了。我起初也以为这样就可以了,但是我发现,这样是不行的。因为一旦我重新启动开发板,系统时间又会回复到原来的时间。想想也是,我们只是写入了系统时间,没有将系统时间同步到硬件时间,这样系统每次重启读取的硬件时间是没有改变的,启动后得到的系统时间CST = UTC + 8,还是换来的系统时间。那怎样将我们设置的系统时间同步到硬件时间呢?我们知道在终端里,可以通过hwclock –systohc将系统时间同步到硬件时间上去,在应用层怎么实现呢?我不知道有没有其他好的解决办法,我想出来的办法就是在应用层创建子进程,在子进程里调用脚本文件,脚本里的指令就是hwclock –systohc。这样就完成了同步。当然如果有更简单和更合适的方法,欢迎指导、交流。说了这么多,言归正传。
1、预备知识:
a、fork创建子进程,代码如下:
/************************** *功能:创建子进程fork()测试 *时间:2016-4-15 *作者:Jack Cui ***************************/#include <unistd.h> #include <stdio.h> int main (void) { pid_t fpid; //fpid表示fork函数返回的值int count=0; fpid=fork(); if (fpid < 0) //创建子进程失败printf("error\n"); else if (fpid == 0) { printf("I am the child process,my process id is %d\n",getpid()); count++; }else { printf("I am the parent process,my process id is %d\n",getpid()); count++; } printf("count = %d\n",count);return 0; }
b、fork测试程序结果显示:
c、execve()应用层调用脚本文件:
头文件:#include <unistd.h>
函数:int execve(const char * filename, char * const argv[], char * const envp[]);
函数说明: execve()用来执行参数filename 字符串所代表的文件路径, 第二个参数系利用数组指针来传递给执行文件, 最后一个参数则为传递给执行文件的新环境变量数组。
返回值:如果执行成功则函数不会返回, 执行失败则直接返回-1, 失败原因存于errno 中。
d、execve()测试代码:
/************************** *功能:测试execve *时间:2016-4-15 *作者:Jack Cui ***************************/#include <stdio.h> //perror#include <stdlib.h> //EXIT_SUCCESS EXIT_FAILURE#include <unistd.h> //execvevoid main(void) {char * args[] = { "/home/nfsroot/hwclock.sh", NULL};if(-1 == (execve("/home/nfsroot/hwclock.sh",args,NULL))) { perror("execve"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
e、脚本内容:
f、execve测试结果:
可以看出execve使用正常,我们将脚本内容改为hwclock –systohc就可以实现将系统时间同步到硬件时间了。
三、整体代码如下:
/****************************************** *功能:Linux应用层系统时间写入RTC时钟的方法 *时间:2016-4-15 *作者:Jack Cui *******************************************/#include <stdio.h>#include <time.h>#include <sys/time.h>#include <unistd.h>#include <stdlib.h>#include <bits/types.h>#include <linux/rtc.h>struct my_timeval { __time_t tv_sec; __suseconds_t tv_usec; };/************************************************* *函数名 : System_SetTime *功能 : 写入系统时间 *使用方法 : char* dt = "2016-04-15 21:00:00"; System_SetTime(dt); **************************************************/int System_SetTime(char* dt) {struct rtc_time tm;struct tm _tm;struct my_timeval tv; time_t timep;sscanf(dt,"%d-%d-%d %d:%d:%d",&tm.tm_year,&tm.tm_mon,&tm.tm_mday,&tm.tm_hour,&tm.tm_min,&tm.tm_sec); _tm.tm_sec = tm.tm_sec; _tm.tm_min = tm.tm_min; _tm.tm_hour = tm.tm_hour; _tm.tm_mday = tm.tm_mday; _tm.tm_mon = tm.tm_mon - 1; _tm.tm_year = tm.tm_year - 1900; timep = mktime(&_tm); tv.tv_sec = timep; tv.tv_usec = 0;if(settimeofday(&tv, (struct timezone *) 0) < 0) {printf("Set system datetime error!\n");return -1; } return 0; }void main(void) {char *dt = "2016-4-15 21:00:00"; pid_t fpid; //fpid表示fork函数返回的值fpid=fork(); if (fpid < 0) //创建子进程失败printf("error\n"); else if (fpid == 0) {char * args[] = { "/home/nfsroot/hwclock.sh", NULL};if(-1 == (execve("/home/nfsroot/hwclock.sh",args,NULL))) { perror("execve");exit(EXIT_FAILURE); }exit(EXIT_SUCCESS); }else{ System_SetTime(dt); }return 0; }
四、最终结果显示:
1、脚本内容:
2、测试结果:
这样我们重新启动开发板,系统时间不会变,设置成功~!
到此,关于“Linux应用层系统时间写入RTC时钟的办法”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。