摘要: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
" -r(ead) Read RTC register, e.g '-r
" -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");
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);
