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);
  • 相关阅读:
    POJ 2240 Arbitrage spfa 判正环
    POJ 3259 Wormholes spfa 判负环
    POJ1680 Currency Exchange SPFA判正环
    HDU5649 DZY Loves Sorting 线段树
    HDU 5648 DZY Loves Math 暴力打表
    HDU5647 DZY Loves Connecting 树形DP
    CDOJ 1071 秋实大哥下棋 线段树
    HDU5046 Airport dancing links 重复覆盖+二分
    HDU 3335 Divisibility dancing links 重复覆盖
    FZU1686 神龙的难题 dancing links 重复覆盖
  • 原文地址:https://www.cnblogs.com/zhuangquan/p/12053385.html
Copyright © 2011-2022 走看看