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

admin 3117次浏览

摘要:1.查看系统时间 date 2.查看RTC时间 由于不同的RTC驱动读取时间的方法不一样。我这边使用的是hi_rtc。是使用海思中自动的测试程序。 ./tim -g time 3.

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_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

#include

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

#include

#include

#include

#include

#include

#include

#include

#include

#include

#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 '\n"

" -r(ead) Read RTC register, e.g '-r '\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 '\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, ®v);

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, ®v);

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);

相关文章
友情链接