在VxWorks RTP上设置和获取系统时间

时间:2018-01-09 17:01:54

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

我正在尝试在运行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上设置和获取系统时间并读取时间戳吗?

1 个答案:

答案 0 :(得分: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);
}

快乐的编码......