zoukankan      html  css  js  c++  java
  • 《RTC — RTC相关操作以及如何同步系统时间》

    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(
                "
    "
                "Usage: ./test [options] [parameter1] ...
    "
                "Options: 
    "
                "    -s(set)            Set time/alarm,     e.g '-s time 2012/7/15/13/37/59'
    "
                "    -g(get)            Get time/alarm,     e.g '-g alarm'
    "
                "    -w(write)        Write RTC register, e.g '-w <reg> <val>'
    "
                "    -r(ead)            Read RTC register,  e.g '-r <reg>'
    "
                "    -a(alarm)        Alarm ON/OFF',      e.g '-a ON'
    "
                "    -reset            RTC reset
    "
                "    -b(battery monitor) battery ON/OFF,     e.g '-b ON'
    "
                "    -f(requency)        frequency precise adjustment, e.g '-f <val>'
    "
                "
    ");
        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) == ''){
                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 = '';
            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
    ", 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
    ");
                    goto err1;
                }
                printf("set time
    ");
    
                /* code */
                printf("year:%d
    ", tm.year);
                printf("month:%d
    ",tm.month);
                printf("date:%d
    ", tm.date); 
                printf("hour:%d
    ", tm.hour);
                printf("minute:%d
    ", tm.minute);
                printf("second:%d
    ", tm.second);
    
                ret = ioctl(fd, HI_RTC_SET_TIME, &tm);
                if (ret < 0) {
                    printf("ioctl: HI_RTC_SET_TIME failed
    ");
                    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
    ");
                    goto err1;
                }
                printf("set alarm
    ");
    #if 1            
                printf("year:%d
    ", tm.year);
                printf("month:%d
    ",tm.month);
                printf("date:%d
    ", tm.date); 
                printf("hour:%d
    ", tm.hour);
                printf("minute:%d
    ", tm.minute);
                printf("second:%d
    ", tm.second);
    #endif            
                ret = ioctl(fd, HI_RTC_ALM_SET, &tm);
                if (ret < 0) {
                    printf("ioctl: HI_RTC_ALM_SET failed
    ");
                    goto err1;
                }    
             } else {
                printf("unknown options %s
    ", 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]
    ");
                
                ret = ioctl(fd, HI_RTC_RD_TIME, &tm);
                if (ret < 0) {
                    printf("ioctl: HI_RTC_RD_TIME failed
    ");
                    goto err1;
                }
                
                printf("Current time value: 
    ");
            } else if (!strcmp(argv[2], "alarm")) {
            
                printf("[RTC_RD_ALM]
    ");
    
                ret = ioctl(fd, HI_RTC_ALM_READ, &tm);
                if (ret < 0) {
                    printf("ioctl: HI_RTC_ALM_READ failed
    ");
                    goto err1;
                }
                
                printf("Current alarm value: 
    ");
            } else {
                printf("unknow options %s
    ", argv[2]);
                goto err1;
            }
    
            printf("year %d
    ", tm.year);
            printf("month %d
    ", tm.month);
            printf("date %d
    ", tm.date);
            printf("hour %d
    ", tm.hour);
            printf("minute %d
    ", tm.minute);
            printf("second %d
    ", tm.second);
            printf("weekday %d
    ", 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
    ", regv.reg);
                goto err1;
            }
    
            ret = str_to_num(argv[3], &(regv.val));
            if (ret != 0) {
                printf("val 0x%08x invalid
    ", regv.val);
                goto err1;
            }
            
            printf("
    ");
            printf("[RTC_REG_SET] reg:%02x, val:%02x
    ", regv.reg, regv.val);
            printf("
    ");
    
            ret = ioctl(fd, HI_RTC_REG_SET, &regv);
            if (ret < 0) {
                printf("ioctl: HI_RTC_REG_SET failed
    ");
                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
    ", 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
    ");
                goto err1;
            }
    
            printf("
    ");
            printf("[RTC_REG_GET] reg:0x%02x, val:0x%02x
    ", regv.reg, regv.val);
            printf("
    ");
        } 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
    ");
                goto err1;
            }
    
        } else if (!strcmp(argv[1],"-reset")) {
    
            printf("[RTC_RESET]
    ");
    
            ret = ioctl(fd, HI_RTC_RESET);
            if(ret){
                printf("reset err
    ");
                goto err1;
            }
        } else if (!strcmp(argv[1], "-b")) {
    
            if (argc < 3) {
                usage();
                goto err1;
            }
    
            if (!strcmp(argv[2], "ON")) {
                //printf("RTC temperature compensation on!
    ");
                ret = ioctl(fd, HI_RTC_BM_ON);
            } else if (!strcmp(argv[2], "OFF")) {
                //printf("RTC temperature compensation off!
    ");
                ret = ioctl(fd, HI_RTC_BM_OFF);
            }
    
            if (ret < 0) {
                printf("ioctl: HI_RTC_BM_ON/OFF failed
    ");
                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
    ");
                    goto err1;
                }    
                
                freq = value.freq_l;
                printf("current frequency : %d
    ", freq);    
            }    
            // set frequency 
            else if (argc == 3)
            {
                freq = atoi(argv[2]);
                
                if (freq > 3277600 || freq < 3276000)
                {
                    printf("invalid freq %d
    ", freq);
                    goto err1;
                }
            
                value.freq_l = freq;
                
                ret = ioctl(fd, HI_RTC_SET_FREQ, &value);
                if (ret < 0)
                {
                    printf("get current frequency failed
    ");
                    goto err1;
                }
            }
    
        } else {
            printf("unknown download mode.
    ");
            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
    ", tm.year);
        printf("month %d
    ", tm.month);
        printf("date %d
    ", tm.date);
        printf("hour %d
    ", tm.hour);
        printf("minute %d
    ", tm.minute);
        printf("second %d
    ", tm.second);
        printf("weekday %d
    ", 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);
  • 相关阅读:
    关于RSA加密算法的长度限制问题
    Rendering Problems:android.support.v7.internal.widget.ActionBarOverlayLayout 解决方法
    Adb refused a command 解决方法
    项目总结[2]_svg+ajax+webservice+pSpace sdk实现实时数据的web展示
    C#调用斑马打印机打印条码标签(支持COM、LPT、USB、TCP连接方式和ZPL、EPL、CPCL指令)【转】
    基于C#在WPF中使用斑马打印机进行打印【转】
    MYSQL超时连接问题(com.mysql.jdbc.MysqlIO.readFully)
    IDEA类文件不编译问题
    svn“Previous operation has not finished; run 'cleanup' if it was interrupted
    Redis常用API-使用文档
  • 原文地址:https://www.cnblogs.com/zhuangquan/p/12053385.html
Copyright © 2011-2022 走看看