您的位置:首页 > 其它

wince RTC 学习

2014-01-03 14:20 232 查看
 WinCE中如何调用控制面板程序

调用控制面板中的那个程序。

要是在Linux里,简单,直接system("/path/filename arg……")就好了,但请注意,这是在winCE中,就比较郁了。

首先要找一个类似system这样的函数(winCE里不支持system()),找到了一个——
CreateProcess(

LPCWSTR
lpszImageName,

LPCWSTR
lpszCmdLine,

LPSECURITY_ATTRIBUTES
lpsaProcess,

LPSECURITY_ATTRIBUTES
lpsaThread,

BOOL
fInheritHandles,

DWORD
fdwCreate,

LPVOID
lpvEnvironment,

LPWSTR
lpszCurDir,

LPSTARTUPINFOW
lpsiStartInfo,

LPPROCESS_INFORMATION
lppiProcInfo);

WinCE的控制面板没有URL,右键也不提供“属性”,这个系统又不是我做的,搜了一圈也没有,估计是被隐藏了,死活想不出查看路径的办法。只好上网搜一下,于是查找到以下有用信息:

WinCE系统中的控制面板和Windows系统中的控制面板原理是一样的,里面就是包含了一些应用程序。WinCE系统的控制面板由 Ctlpnl.exe,Control.exe和一些.cpl文件组成,其中Ctlpnl.exe和Control.exe用于控制控制面板的文件夹显示和架构,而.cpl文件和控制面板中的实际应用程序相对应。fromhttp://ieoqmdce.blog.163.com/blog/static/389399542009913117425/

用脚本实现对WINCE控制面板功能的直接调用

控制面板其实也是个动态链接库,区别只在于后缀名为.cpl

如何调用.cpl

就像PC机中.dll文件不能直接运行,需要借助rundll32.exe来运行一样,WinCE下的.cpl也需要相应的程序来调用,这个程序就是:"ctlpnl.exe".

比如我们需要调用系统自带的cplmain.cpl的"电源管理",只要在开始菜单的运行中输入:"ctlpnl.exe /windows/cplmain.cpl,5".在路径后面紧跟的"5"只是因为"电源管理"在cplmain.cpl中输入第五个Applet而已.

在WINCE实际使用过程中可以使用脚本来做到一机多图中,如脚本RunWait("/Windows/ctlpnl.exe", "cplmain.cpl,6,1")就可直接调用控制面板并进入调整内存

RunWait("/Windows/ctlpnl.exe", "cplmain.cpl,9,1")/可以直接进入校准(

RunWait("/Windows/ctlpnl.exe", "cplmain.cpl,10")进入调整音量";

以下所列就是不同数字对应的功能

0    CPL_Comm               连接属性

1    CPL_Dialing              拨号属性

2    CPL_Keyboard          键盘属性

3    CPL_Password          密码属性/

4    CPL_Owner               所有者

5    CPL_Power               电源属性  

6    CPL_System             系统属性

7    CPL_Screen              显示属性

8    CPL_Mouse              鼠标属性

9    CPL_Stylus               笔针属性(这里可以校准)

10  CPL_Sounds             音量属性

11    CPL_SIP"                输入面板

12    CPL_Remove          删除程序

13    CPL_DateTime       日期时间

14    CPL_Certs              证书

from http://bbs.manbu.cc/viewthread.php?tid=27484
于是在“运行”里试了一下ctlpnl.exe /windows/cplmain.cpl,5,果然可以!那办法就有了,只要在程序中需要的地方加入:

 PROCESS_INFORMATION pi = {0};

 CreateProcess(_T("//Windows//ctlpnl.exe"), _T(" cplmain.cpl,9,2"), NULL, NULL, NULL,

     0, NULL, NULL, NULL, &pi);

问题就解决了

 

1.系统启动过程中RTC初始化

在WINCE6.0中,我们知道是通过OALIoCtlHalInitRTC()函数来设置RTC的时间的,但是如何调用到这个函数的呢?

在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;

 




RTC测试程序

void RTC_Display(void) 
{
U16 year ;
U8 month, day ;// week
U8 hour, minute, second ;

RTC_Time_Set() ; 
注:初始日期和时间的设置 
   Uart_Printf( "\nRTC TIME Display, press ESC key to exit !\n" ) ;

while( Uart_GetKey() != ESC_KEY )
{
rRTCCON = 1 ;//RTC read and write enable

year = 0x2000+rBCDYEAR  ;//2012
month = rBCDMON  ;//??
day = rBCDDATE  ;//??

//
week = rBCDDAY  ; //????
hour = rBCDHOUR  ;//???±
minute = rBCDMIN  ;//·?
second = rBCDSEC  ;//??

rRTCCON &= ~1 ;//RTC read and write disable

Uart_Printf( "RTC time : %04x-%02x-%02x %02x:%02x:%02x\n", year, month, day, hour, minute, second );
Delay( 900 ) ;
注:延迟900ms左右,差不多1S显示一次当前时间
}
 }

void RTC_Time_Set( void )
{
rRTCCON = 1 ;//RTC read and write enable
注:在读或写rBCDYEAR这些寄存器时都必须先置一该位
rBCDYEAR = 0x12 ;//设定年
rBCDMON  = 0x05 ;//设定月
rBCDDATE = 0x15 ;//设定日
rBCDDAY  = 0x05 ;//设定星期
rBCDHOUR = 0x12 ;//设定小时
rBCDMIN  = 0x00 ;//设定分钟
rBCDSEC  = 0x00 ;//设定秒

注:16进制标志10进制   表示的是0012年 05月 15日,12:00:00

rRTCCON &= ~1 ;//RTC read and write disable
}
末完,待续。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  RTC 驱动