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

Set&Get system time on VxWorks RTP

我正在尝试在运行 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 时,一切正常,功能在它必须在的地方。但是,对于用户 space RTP sysLib.h 没有任何对 sysOutByte 函数的调用。

是不是因为在用户RTP space不允许调用系统函数读写实时时钟?

或者是否有任何其他方法可以在 RTP 上设置和获取系统时间以及读取时间戳?

好像在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) 当系统以新镜像重启时,会自动获取最近的时间。 (需要根据 his/her 时区的正确设置更改计算)

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);
}

编码愉快...