Reputation: 856
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
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