【问题标题】:Set&Get system time on VxWorks RTP在 VxWorks RTP 上设置和获取系统时间
【发布时间】:2018-01-09 17:01:53
【问题描述】:

我正在尝试在运行 VxWorks 7 的英特尔架构上设置和获取系统时间。

我可以使用带有上述代码的 DKM(可下载内核模块)设置时间。

#include "vxWorks.h"
#include "time.h"
#include "stdio.h"
#include "memLib.h"
#include "sysLib.h"

#define RTCDEBUG  /* define to get debug output */

STATUS timeTest (void)
{
    int i;
    time_t myTime1;
    struct tm *myTime2;

    unsigned int month_array[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    unsigned int current_second_bcd;
    unsigned int current_minute_bcd;
    unsigned int current_hour_bcd;
    unsigned int current_day_of_week_bcd;
    unsigned int current_date_bcd;
    unsigned int current_month_bcd;
    unsigned int current_year_bcd;
    unsigned int current_century_bcd;
    unsigned int second;
    unsigned int minute;
    unsigned int hour;
    unsigned int day;
    unsigned int date;
    unsigned int month;
    unsigned int year;
    unsigned int yday;
    unsigned int century;
    struct timespec mytimespec;

    /* displays VxWorks uninitialized time = THU JAN 01 00:00:01 1970*/

    myTime1 = time (0);
    myTime2 = localtime (&myTime1);

#ifdef RTCDEBUG
    printf ("\ncurrent vxWorks Time = %s", asctime (myTime2));
#endif

    /* reads PC real time clock maintained in CMOS RAM */
    /* RTC CMOS RAM contents are accessed by writes and reads from */
    /* I/O addresses 0x70 and 0x71 respectively */
    sysOutByte (0x70, 0x0);
    current_second_bcd = sysInByte (0x71);
    sysOutByte (0x70, 0x2);
    current_minute_bcd = sysInByte (0x71);
    sysOutByte (0x70, 0x4);
    current_hour_bcd = sysInByte (0x71);
    sysOutByte (0x70, 0x6);
    current_day_of_week_bcd = sysInByte (0x71);
    sysOutByte (0x70, 0x7);
    current_date_bcd = sysInByte (0x71);
    sysOutByte (0x70, 0x8);
    current_month_bcd = sysInByte (0x71);
    sysOutByte (0x70, 0x9);
    current_year_bcd = sysInByte (0x71);
    sysOutByte (0x70, 0x32);
    current_century_bcd = sysInByte (0x71);

    /* displays PC real time clock BCD data*/
#ifdef RTCDEBUG

    printf ("\nsecond = %02X \nminute = %02X \nhour = %02X \nday = %02X \ndate = %02X ",
        current_second_bcd, current_minute_bcd, current_hour_bcd, current_day_of_week_bcd,
        current_date_bcd);
    printf ("\nmonth = %02X \nyear = %02X \ncentury = %02X", current_month_bcd,
        current_year_bcd, current_century_bcd);
#endif
    /* convert PC real time clock BCD data to decimal for entry */
    /* into tm structure, see /WIND_BASE/target/h/time.h */

    second = ((current_second_bcd & 0xF0) >> 4) * 10;
    second = second + (current_second_bcd & 0x0F);

    minute = ((current_minute_bcd & 0xF0) >> 4) * 10;
    minute = minute + (current_minute_bcd & 0x0F);

    hour = ((current_hour_bcd & 0xF0) >> 4) * 10;
    hour = hour + (current_hour_bcd & 0x0F);

    day = ((current_day_of_week_bcd & 0xF0) >> 4) * 10;
    day = day + (current_day_of_week_bcd & 0x0F);

    date = ((current_date_bcd & 0xF0) >> 4) * 10;
    date = date + (current_date_bcd & 0x0F);

    month = ((current_month_bcd & 0xF0) >> 4) * 10;
    month = month + (current_month_bcd & 0x0F);

    year = ((current_year_bcd & 0xF0) >> 4) * 10;
    year = year + (current_year_bcd & 0x0F);

    century = ((current_century_bcd & 0xF0) >> 4) * 10;
    century = century + (current_century_bcd & 0x0F);
    century = century * 100;

    year = century + year;
    year = year - 1900;

    for (i = 0; i < month; i++)
        yday = yday + month_array[i];
    yday = yday + date;

    /* display converted data*/
#ifdef RTCDEBUG
    printf ("\n\nsecond = %d minute = %d hour = %d ",
        second, minute, hour);
    printf ("\ndate = %d month = %d year = %d day = %d yday = %d", date, month, year, day, yday);
#endif
    /* initialize tm structure with converted data */

    myTime2->tm_sec = second;
    myTime2->tm_min = minute;
    myTime2->tm_hour = hour;
    myTime2->tm_mday = date;
    myTime2->tm_mon = month-1; /* months are 0-11 */
    myTime2->tm_year = year;
    myTime2->tm_wday = day;
    myTime2->tm_yday = yday;
    myTime2->tm_isdst = 1;       /* daylight savings time in effect (does nothing)*/

    /* convert tm structure to seconds */
    myTime1 = mktime (myTime2);

    /* initialize VxWorks time with new value */
    mytimespec.tv_sec = myTime1;
    mytimespec.tv_nsec = 0;

    clock_settime(CLOCK_REALTIME, &mytimespec);

    /* test to make sure time update took */
    myTime1 = time(0);
    myTime2 = localtime(&myTime1);

#ifdef RTCDEBUG
    printf("\n\nnew vxWorks Time = %s", asctime(myTime2));
#endif

    return (OK);
}

int main()
{
    timeTest();

    return 0;
}

我想做的是使用此代码来处理用户 RTP。当我在 RTP 项目上编译代码时,它给出了一个错误代码,说它在 sysLib.h 中找不到 sysOutByte 函数。当我查看内核 sysLib.h 时,一切正常,函数就在它必须在的地方。但是,对于用户空间 RTP sysLib.h,没有任何对 sysOutByte 函数的调用。

是因为我不允许在用户RTP空间调用系统函数来读写实时时钟吗?

或者还有其他方法可以在 RTP 上设置和获取系统时间并读取时间戳吗?

【问题讨论】:

  • sysOutByte 仅在内核上下文中可用,并且未在 sysLib.h 中为用户空间定义。
  • @AhmedMasud 那么,是否可以在 VIP(VxWorks 内核映像项目)的 usrAppInit.c 中调用 sysOutByte 和 sysInByte,以便我能够在 RTP 中使用 localtime() 读取时间戳?

标签: c timestamp i2c vxworks real-time-clock


【解决方案1】:

好像在usrAppInit.c函数里设置一次就够了,如下。

1) 将代码复制并粘贴到 Kernel Module Projcet 同一目录下的另一个 .c 文件中。 (例如 myRtcWrapper.c)

2) 在usrAppInit.c中调用timeTest()

void usrAppInit (void)
{
    #ifdef  USER_APPL_INIT
        USER_APPL_INIT;     
    #endif  
        timeTest();
    ...
}

3) 当系统使用新镜像重新启动时,它会自动获取最近的时间。 (需要根据正确设置到他/她的时区来更改计算)

4) 所以,要从 RTP 调用它,只需添加这段代码

time_t myTime1; 
struct tm *myTime2; 

myTime1 = time(0); 
myTime2 = localtime(&myTime1); 

printf("\nTime is = %s now!\n", asctime(myTime2));

或更简单的读取秒数的方法,只需使用以下内容:

struct timespec seconds;

if (clock_gettime(CLOCK_REALTIME, &seconds) == OK)
{
    printf("%d, seconds.tv_sec);
}

编码愉快...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多