WINCE6.0+S3C2443的RTC初始化及存在的问题
1.系統啟動過程中RTC初始化
在WINCE6.0中,我們知道是通過OALIoCtlHalInitRTC()函數來設置RTC的時間的,但是如何調用到這個函數的呢?我們就從NKStartup()函數開始,但系統從nboot開始是如何執行到NKStartup()函數的呢?我后面會抽空寫關于eboot和nk的啟動過程中有涉及。
?
在SystemStartupFunc函數中,通過下面語句來創建一個內核線程RunApps:
hTh?=?CreateKernelThread?(RunApps,0,THREAD_RT_PRIORITY_NORMAL,0);
接著就執行線程RunApps。在線程RunApps中,通過下面語句:
?hFilesys?=?(HMODULE)?NKLoadLibraryEx?(L"filesys.dll",?MAKELONG?(LOAD_LIBRARY_IN_KERNEL,?LLIB_NO_PAGING),?NULL);
來加載filesys.dll,接著通過下面語句:
hTh?=?CreateKernelThread?((LPTHREAD_START_ROUTINE)pfnMain,?hFilesys,?THREAD_RT_PRIORITY_NORMAL,?0);
來創建filesys.dll的線程WinMain(),這個線程在/WINCE600/PRIVATE/TEST/BASEOS/FILESYS/GENFILE/genfile.cpp中定義,這樣就接著執行這個線程。
Filesys.dll的主要工作是初始化文件系統、對象存儲、注冊表、CEDB數據庫、設備通知以及其它一些工作:
⑴Filesys.dll檢測是冷啟動還是熱啟動
如果是冷啟動,對象儲存內存將被初始化并映射給Filesys.dll;對于熱啟動,不用初始化而直接映射給Filesys.dll。
⑵Filesys.dll從nandflash中加載OEM的certification?DLL。
⑶如果必須他能夠必須是冷啟動,Filesys.dll調用OAL函數pNotifyForceCleanboot。
⑷對于冷啟動,Filesys.dll調用OEMIoControl函數,I/O控制代碼為IOCTL_HAL_INIT_RTC,也就是初始化RT。
Filesys.dll還有很多的動作,再這里就不介紹了,我們接下來看看OEMIoControl函數是如何一層層調用到OALIoCtlHalInitRTC的呢?接著往下看。
OEMIoControl():在/WINCE600/PLATFORM/COMMON/SRC/COMMON/IOCTL/ioctl.c下面定義
從上圖可以知道OEMIoControl函數通過傳遞進來的code來和數組g_oalIoCtlTable中的code成員比較,找到吻合的code后便跳出這個for循環,然后往下執行。而數組g_oalIoCtlTable是在/Src/Oal/Oallib/ioctl.c下定義,如下圖
接著看ioctl_tab.h的內容
到這里我們還是沒有直觀看到IOCTL_HAL_INIT_RTC,接著往下看oal_ioctl_tab.h的內容:
在上圖的第31行可以看到IOCTL_HAL_INIT_RTC,那么對應于IOCTL_HAL_INIT_RTC的處理函數是如何得到執行的呢?上面提到,OEMIoControl函數通過傳遞進來的code找到數組g_oalIoCtlTable中吻合的code后,通過下面的處理
會記下i的值,也就是IOCTL_HAL_INIT_RTC所在數組g_oalIoCtlTable的索引值,接著看OEMIoControl函數下面的處理
這段代碼就是根據上面確定的i的值,來執行對應的handler,在這里就是調用OALIoCtlHalInitRTC()函數
?
2.RTC初始化存在的問題
從上面可知,系統啟動過程是通過調用函數OALIoCtlHalInitRTC()來初始化RTC的,這個函數體如下
從這個函數體可知是通過調用OEMSetRealTime()來設置RTC的,g_oalRtcResetTime的定義如下:
SYSTEMTIME?g_oalRtcResetTime?=?{2010,?8,?5,?27,?12,?0,?0,?0};
?
因為我們的系統每次關機后重啟都是冷啟動,所以每次啟動之后都會調用到OALIoCtlHalInitRTC函數,從而不管你之前設置的時間是多少,都會重新初始化為g_oalRtcResetTime中的時間。我把上圖的第98行替換為下面的函數就可以解決了這個問題:
?
3.BOOL?OEMSetRealTime(LPSYSTEMTIME?pTime)?
OEMGetRealTime()用來獲得當前的時間。WinCE啟動以后,默認情況下,WinCE會每隔一段時間調用OEMGetRealTime()函數來獲得系統的時間,這種方式被稱為hardware?mode。WinCE還有另一種獲得系統時間的方法,被稱為software?mode,就是通過調用GetTickCount()函數跟蹤系統的timetick的變化來累加時間。如果要用software?mode,那么需要在注冊表中做如下的設置:
HKEY_LOCAL_MACHINE/Platform/"SoftRTC"?=?1
我來談談我的看法,一般都要使用hardware?mode,這樣獲得的系統時間比較準。software?mode獲得系統時間不會很準的。
4.BOOL?OEMGetRealTime(SYSTEMTIME?*pTime)
OEMGetRealTime()用來獲得當前的時間。WinCE啟動以后,默認情況下,WinCE會每隔一段時間調用OEMGetRealTime()函數來獲得系統的時間,這種方式被稱為hardware?mode。WinCE還有另一種獲得系統時間的方法,被稱為software?mode,就是通過調用GetTickCount()函數跟蹤系統的timetick的變化來累加時間。如果要用software?mode,那么需要在注冊表中做如下的設置:
HKEY_LOCAL_MACHINE/Platform/"SoftRTC"?=?1
我來談談我的看法,一般都要使用hardware?mode,這樣獲得的系統時間比較準。software?mode獲得系統時間不會很準的。
?
5.BOOL?OEMSetRealTime(LPSYSTEMTIME?pTime)?
OEMSetRealTime()用來設置當前的時間。當WinCE啟動以后,我們會在界面的右下角看到時間顯示,我們可以直接在WinCE的界面里面設置時間,這個時候,系統就會調用OEMSetRealTime()把你設置的時間寫到RTC模塊里面。
?
6.LPSYSTEMTIME
LPSYSTEMTIME實際上是一個指向SYSTEMTIME結構的指針,關于SYSTEMTIME,定義如下:
typedef?struct?_SYSTEMTIME
????{
????WORD?wYear;
????WORD?wMonth;
????WORD?wDayOfWeek;
????WORD?wDay;
????WORD?wHour;
????WORD?wMinute;
????WORD?wSecond;
????WORD?wMilliseconds;
????} SYSTEMTIME;
?
總結
以上是生活随笔為你收集整理的WINCE6.0+S3C2443的RTC初始化及存在的问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nandflash K9F1208U0B
- 下一篇: WINCE6.0+2443系统大概过10