天天看點

再回首--我的自考之路

vxworks for x86讀取bios時間的解決方法

 系統時間與bsp有關,在vzworks for x86系列的目标沒有直接讀取rtc(實時時鐘控制器)的函數,用time.h中的函數讀到的始終是 00:00:00, jan. 1 1970.

  是以在x86系列的機器中,我們可以從bios中讀取目前的時鐘。用sysinbyte(),sysoutbyte(),在70,和71端口讀取或寫bios裡的時間.

  首先要分析bios的内容,找出秒,分,時,天,月,年的存放位址。

他們分别是: 0x00,0x02,0x04,0x07,0x08,0x09

然後從71端口讀出相應的值,進行轉換。

如:秒

  sysoutbyte(0x70,0x00);

  second = sysinbyte(0x71);

讀出的second進行轉換,:

  second = (second &0x0f) + 10*((second &0xf0)>>4);

示例代碼:

time_t biostime()

{

  struct tm   ahora;

  unsigned char chour, cmin, csec;

  unsigned char cday, cmonth, cyear;

  sysoutbyte(0x70,0x00/*second*/);

  csec = sysinbyte(0x71);

  ahora.tm_sec = (csec&0x0f) + 10*((csec&0xf0)>>4);

  sysoutbyte(0x70,0x02/*minut*/);

  cmin = sysinbyte(0x71);

  ahora.tm_min = (cmin&0x0f) + 10*((cmin&0xf0)>>4);

  sysoutbyte(0x70,0x04/*hour*/);

  chour = sysinbyte(0x71);

  ahora.tm_hour = (chour&0x0f) + 10*((chour&0xf0)>>4);

 

  sysoutbyte(0x70,0x07/*day*/);

  cday = sysinbyte(0x71);

  ahora.tm_mday = (cday&0x0f) + 10*((cday&0xf0)>>4);

  sysoutbyte(0x70,0x08/*month*/);

  cmonth = sysinbyte(0x71);

  ahora.tm_mon = (cmonth&0x0f) + 10*((cmonth&0xf0)>>4) - 1;

  sysoutbyte(0x70,0x09/*year*/);

  cyear = sysinbyte(0x71);

  ahora.tm_year = 100 + (cyear&0x0f) + 10*((cyear&0xf0)>>4);

  return mktime(&ahora);

}

我們在系統初始化時讀取bios時間一次,然後修改系統時鐘:

 clock_settime(..)

以後我們得到的時間就都是目前的正确時間

示例:

void inittime()

  int res;

  struct timespec ts;

  struct tm daytime;

  time_t stime;

  ts.tv_sec = biostime();

  ts.tv_nsec = 0;

  res = clock_settime(clock_realtime, &ts);

  stime = time(null);

  daytime = *localtime(&stime);

  printf ( "time is :%s\n", asctime(&daytime) );