分享

《RTC — RTC相关操作以及如何同步系统时间》

 启云_9137 2020-10-30

1.查看系统时间

date

2.查看RTC时间

  由于不同的RTC驱动读取时间的方法不一样。我这边使用的是hi_rtc。是使用海思中自动的测试程序。

./tim  -g  time

3.系统时间同步成RTC时间

复制代码
hwclock –r 显示硬件时钟与日期hwclock –s 将系统时钟调整为与目前的硬件时钟一致。hwclock –w 将硬件时钟调整为与目前的系统时钟一致。
复制代码

  但是我使用相关命令会出现:

   提示找不到相对应的设备节点。

  因为我的设备节点是加载在/dev/hi_rtc中,所以通用的这个是不行了。(海思的RTC不能使用通过的系统时间同步命令)

  利用mktime和settimeofday的直接在读取RTC时间时,将RTC时间再通过这两个函数再写入到系统时间中。

mktime函数:

  C 库函数 time_t mktime(struct tm *timeptr) 把 timeptr 所指向的结构转换为一个依据本地时区的 time_t 值。

复制代码
#include <time.h>time_t mktime(struct tm *timeptr)

参数:
struct tm {
int tm_sec; /* 秒,范围从 0 到 59                */ int tm_min; /* 分,范围从 0 到 59                */ int tm_hour; /* 小时,范围从 0 到 23                */ int tm_mday; /* 一月中的第几天,范围从 1 到 31     */ int tm_mon; /* 月份,范围从 0 到 11                */ int tm_year; /* 自 1900 起的年数                */ int tm_wday; /* 一周中的第几天,范围从 0 到 6         */ int tm_yday; /* 一年中的第几天,范围从 0 到 365     */ int tm_isdst; /* 夏令时                        */    };

返回值:
该函数返回一个 time_t 值,该值对应于以参数传递的日历时间。如果发生错误,则返回 -1 值。
复制代码

  作用是,将时间转换为自1900年1月1日以来持续时间的秒数,发生错误时返回-1。(注意这边是自1900的1月份)

settimeofday函数:

复制代码
#include<sys/time.h>#include<unistd.h>int settimeofday ( const struct timeval *tv,const struct timezone *tz);参数:struct  timeval{       long  tv_sec;/**/       long  tv_usec;/*微妙*/};struct  timezone{        int tz_minuteswest;/*和greenwich 时间差了多少分钟*/        int tz_dsttime;/*type of DST correction*/}返回值:函数执行成功后返回0,失败后返回-1,错误代码存于errno中。
复制代码

4.实例

复制代码
/* * RTC sample&test code. */#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <string.h>#include <sys/time.h>#include <time.h>#include 'hi_rtc.h'void usage(void){ printf( '\n' 'Usage: ./test [options] [parameter1] ...\n' 'Options: \n' ' -s(set) Set time/alarm, e.g '-s time 2012/7/15/13/37/59'\n' ' -g(get) Get time/alarm, e.g '-g alarm'\n' ' -w(write) Write RTC register, e.g '-w <reg> <val>'\n' ' -r(ead) Read RTC register, e.g '-r <reg>'\n' ' -a(alarm) Alarm ON/OFF', e.g '-a ON'\n' ' -reset RTC reset\n' ' -b(battery monitor) battery ON/OFF, e.g '-b ON'\n' ' -f(requency) frequency precise adjustment, e.g '-f <val>'\n' '\n'); exit(1);}static int _atoul(const char *str, unsigned char *pvalue){ unsigned int result=0; while (*str) { if (isdigit((int)*str)) { if ((result<429496729) || ((result==429496729) && (*str<'6'))) { result = result*10 + (*str)-48; } else { *pvalue = result; return -1; } } else { *pvalue=result; return -1; } str++; } *pvalue=result; return 0;}#define ASC2NUM(ch) (ch - '0')#define HEXASC2NUM(ch) (ch - 'A' + 10)static int _atoulx(const char *str, unsigned char *pvalue){ unsigned int result=0; unsigned char ch; while (*str) { ch=toupper(*str); if (isdigit(ch) || ((ch >= 'A') && (ch <= 'F' ))) { if (result < 0x10000000) { result = (result << 4) + ((ch<='9')?(ASC2NUM(ch)):(HEXASC2NUM(ch))); } else { *pvalue=result; return -1; } } else { *pvalue=result; return -1; } str++; } *pvalue=result; return 0;}/*used for convert hex value from string to int*/static int str_to_num(const char *str, unsigned char *pvalue){ if ( *str == '0' && (*(str+1) == 'x' || *(str+1) == 'X') ){ if (*(str+2) == '\0'){ return -1; } else{ return _atoulx(str+2, pvalue); } } else { return _atoul(str,pvalue); }}/*used for convert time frome string to struct rtc_time_t*/static int parse_string(char *string, rtc_time_t *p_tm){ char *comma, *head; int value[10]; int i; if (!string || !p_tm) return -1; if (!strchr(string, '/')) return -1; head = string; i = 0; comma = NULL; for(;;) { comma = strchr(head, '/'); if (!comma){ value[i++] = atoi(head); break; } *comma = '\0'; value[i++] = atoi(head); head = comma+1; } if (i < 5) return -1; p_tm->year = value[0]; p_tm->month = value[1]; p_tm->date = value[2]; p_tm->hour = value[3]; p_tm->minute = value[4]; p_tm->second = value[5]; p_tm->weekday = 0; return 0;}int main(int argc, const char *argv[]){ struct tm tm_time; struct timeval val_time; rtc_time_t tm; reg_data_t regv; int ret = -1; int fd = -1; const char *dev_name = '/dev/hi_rtc'; char string[50] = {0}; if (argc < 2){ usage(); return 0; } fd = open(dev_name, O_RDWR); if (fd < 0) { printf('open %s failed\n', dev_name); return -1; } if (!strcmp(argv[1],'-s')) { if (argc < 4) { usage(); goto err1; } if (!strcmp(argv[2], 'time')) { strncpy(string, argv[3], sizeof(string)-1); ret = parse_string(string, &tm); if (ret < 0) { printf('parse time param failed\n'); goto err1; } printf('set time\n'); /* code */ printf('year:%d\n', tm.year); printf('month:%d\n',tm.month); printf('date:%d\n', tm.date); printf('hour:%d\n', tm.hour); printf('minute:%d\n', tm.minute); printf('second:%d\n', tm.second); ret = ioctl(fd, HI_RTC_SET_TIME, &tm); if (ret < 0) { printf('ioctl: HI_RTC_SET_TIME failed\n'); goto err1; } } else if (!strcmp(argv[2], 'alarm')) { strncpy(string, argv[3], sizeof(string)-1); ret = parse_string(string, &tm); if (ret < 0) { printf('parse alarm param failed\n'); goto err1; } printf('set alarm\n');#if 1 printf('year:%d\n', tm.year); printf('month:%d\n',tm.month); printf('date:%d\n', tm.date); printf('hour:%d\n', tm.hour); printf('minute:%d\n', tm.minute); printf('second:%d\n', tm.second);#endif ret = ioctl(fd, HI_RTC_ALM_SET, &tm); if (ret < 0) { printf('ioctl: HI_RTC_ALM_SET failed\n'); goto err1; } } else { printf('unknown options %s\n', argv[2]); goto err1; } } else if (!strcmp(argv[1],'-g')) { if (argc < 3) { usage(); goto err1; } //read RTC if (!strcmp(argv[2], 'time')) { printf('[RTC_RD_TIME]\n'); ret = ioctl(fd, HI_RTC_RD_TIME, &tm); if (ret < 0) { printf('ioctl: HI_RTC_RD_TIME failed\n'); goto err1; } printf('Current time value: \n'); } else if (!strcmp(argv[2], 'alarm')) { printf('[RTC_RD_ALM]\n'); ret = ioctl(fd, HI_RTC_ALM_READ, &tm); if (ret < 0) { printf('ioctl: HI_RTC_ALM_READ failed\n'); goto err1; } printf('Current alarm value: \n'); } else { printf('unknow options %s\n', argv[2]); goto err1; } printf('year %d\n', tm.year); printf('month %d\n', tm.month); printf('date %d\n', tm.date); printf('hour %d\n', tm.hour); printf('minute %d\n', tm.minute); printf('second %d\n', tm.second); printf('weekday %d\n', tm.weekday); tm_time.tm_year = tm.year - 1900; tm_time.tm_mon = tm.month -1; tm_time.tm_mday = tm.date; tm_time.tm_hour = tm.hour; tm_time.tm_min = tm.minute; tm_time.tm_sec = tm.second; tm_time.tm_wday = tm.weekday; val_time.tv_sec = mktime(&tm_time); val_time.tv_usec = 0; settimeofday(&val_time,NULL); } else if (!strcmp(argv[1],'-w')) { if (argc < 4) { usage(); goto err1; } ret = str_to_num(argv[2], &(regv.reg)); if (ret != 0) { printf('reg 0x%08x invalid\n', regv.reg); goto err1; } ret = str_to_num(argv[3], &(regv.val)); if (ret != 0) { printf('val 0x%08x invalid\n', regv.val); goto err1; } printf('\n'); printf('[RTC_REG_SET] reg:%02x, val:%02x\n', regv.reg, regv.val); printf('\n'); ret = ioctl(fd, HI_RTC_REG_SET, &regv); if (ret < 0) { printf('ioctl: HI_RTC_REG_SET failed\n'); goto err1; } } else if (!strcmp(argv[1],'-r')) { if (argc < 3) { usage(); goto err1; } ret = str_to_num(argv[2], &(regv.reg)); if (ret != 0) { printf('reg 0x%08x invalid\n', regv.reg); goto err1; } regv.val = 0; ret = ioctl(fd, HI_RTC_REG_READ, &regv); if (ret < 0) { printf('ioctl: HI_RTC_REG_READ failed\n'); goto err1; } printf('\n'); printf('[RTC_REG_GET] reg:0x%02x, val:0x%02x\n', regv.reg, regv.val); printf('\n'); } else if (!strcmp(argv[1],'-a')) { if (argc < 3) { usage(); goto err1; } if (!strcmp(argv[2], 'ON')) { ret = ioctl(fd, HI_RTC_AIE_ON); } else if (!strcmp(argv[2], 'OFF')) { ret = ioctl(fd, HI_RTC_AIE_OFF); } if (ret < 0) { printf('ioctl: HI_RTC_AIE_ON/OFF failed\n'); goto err1; } } else if (!strcmp(argv[1],'-reset')) { printf('[RTC_RESET]\n'); ret = ioctl(fd, HI_RTC_RESET); if(ret){ printf('reset err\n'); goto err1; } } else if (!strcmp(argv[1], '-b')) { if (argc < 3) { usage(); goto err1; } if (!strcmp(argv[2], 'ON')) { //printf('RTC temperature compensation on!\n'); ret = ioctl(fd, HI_RTC_BM_ON); } else if (!strcmp(argv[2], 'OFF')) { //printf('RTC temperature compensation off!\n'); ret = ioctl(fd, HI_RTC_BM_OFF); } if (ret < 0) { printf('ioctl: HI_RTC_BM_ON/OFF failed\n'); goto err1; } } else if (!strcmp(argv[1], '-f')) { unsigned int freq; rtc_freq_t value; // print current frequency value if (argc < 3) { ret = ioctl(fd, HI_RTC_GET_FREQ, &value); if (ret < 0) { printf('get current frequency failed\n'); goto err1; } freq = value.freq_l; printf('current frequency : %d\n', freq); } // set frequency else if (argc == 3) { freq = atoi(argv[2]); if (freq > 3277600 || freq < 3276000) { printf('invalid freq %d\n', freq); goto err1; } value.freq_l = freq; ret = ioctl(fd, HI_RTC_SET_FREQ, &value); if (ret < 0) { printf('get current frequency failed\n'); goto err1; } } } else { printf('unknown download mode.\n'); goto err1; }err1: close(fd); return 0;}
复制代码

  以上是基于海思SDK中的/drv/rtc中的rtc_test.c修改的,修改的部分如下。(上面代码已经是修改完的了,下面的代码是从上面代码中截取出来的)

复制代码
    struct tm tm_time;    struct timeval val_time;//读取RTC时间,放在结构体变量tm中        ret = ioctl(fd, HI_RTC_RD_TIME, &tm);    printf('year %d\n', tm.year);    printf('month %d\n', tm.month);    printf('date %d\n', tm.date);    printf('hour %d\n', tm.hour);    printf('minute %d\n', tm.minute);    printf('second %d\n', tm.second);    printf('weekday %d\n', tm.weekday);        tm_time.tm_year        = tm.year - 1900;        tm_time.tm_mon        = tm.month -1;        tm_time.tm_mday        = tm.date;        tm_time.tm_hour        = tm.hour;        tm_time.tm_min        = tm.minute;        tm_time.tm_sec        = tm.second;        tm_time.tm_wday        = tm.weekday;                val_time.tv_sec   = mktime(&tm_time);        val_time.tv_usec        = 0;        settimeofday(&val_time,NULL);
复制代码

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多