unnamed
unnamed

Reputation: 856

Set&Get system time on VxWorks RTP

I'm trying to set and get the system time on an intel architecture that runs VxWorks 7.

I'm able to set the time using a DKM (Downloadable Kernel Module) with the code above.

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

What I want to do is to use this code to work on user RTP. When I compile the code on an RTP project, It gives an error code saying that it can't find sysOutByte function in sysLib.h. When I look at the kernel sysLib.h, Everything is OK, the function is where it has to be. But, for the user space RTP sysLib.h there is not any call for sysOutByte function.

Is it because I'm not allowed to call system functions to read&write real time clock at user RTP space?

Or are there any other ways to set and get system time on a RTP and reading timestamps?

Upvotes: 0

Views: 3971

Answers (1)

unnamed
unnamed

Reputation: 856

It seems that it is enough to set once in the usrAppInit.c function as follows.

1) Copy and paste code into another .c file within the same directory of Kernel Module Projcet. (For example myRtcWrapper.c)

2) Call timeTest() in the usrAppInit.c

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

3) When the system is reboot with the new image, it will automatically get the recent time. (One needs to change the calculations according to set properly to his/her timezone)

4) So, to call it from an RTP simply add this piece of code

time_t myTime1; 
struct tm *myTime2; 

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

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

or easier way to read as seconds, just use the following:

struct timespec seconds;

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

Happy coding...

Upvotes: 1

Related Questions