现在的位置: 首页 > 综合 > 正文

Wince6.0 电源控制驱动程序分析-基于S5PC100

2013年10月12日 ⁄ 综合 ⁄ 共 19912字 ⁄ 字号 评论关闭

     在wince6.0里有一个电源控制模块驱动(Power Controller Driver),该模块主要是反映和控制系统电源状态,以及控制系统硬件模块的电源状态。该驱动也是典型的流式驱动,提供以下接口:

其中主要的是PWC_Init和PWC_IOControl,其余的那些函数都是空函数,仅仅提供接口而已。那接下来我们就来分析PWC_Init和PWC_IOControl.

1.PWC_Init

该函数主要是做一些初始化操作,包括初始化电源控制寄存器和硬件模块控制寄存器(包括摄像头、JPEG解码器、TVOUT、IP电话等)。

寄存器的初始化主要是通过MmMapIoSpace将寄存器的地址映射到虚拟地址空间。接着创建系统电源监视线程:

    g_hThreadPowerMon = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) PowerMonitorThread, NULL, 0, NULL);
    if (g_hThreadPowerMon == NULL )
    {
        RETAILMSG(PWC_ZONE_ERROR,(_T("[PWRCON:ERR] %s->CreateThread() Power Monitor Failed /n"), _T(__FUNCTION__)));
        goto CleanUp;
    }

也就是说系统电源状态的监视和设置是在该线程中完成的,PowerMonitorThread函数具体代码如下:

该函数看起来虽然复杂,但结构和流程上去不复杂。首先要明白一点,系统电源的变化是通过消息事件机制通信的,因此必须要创建一个消息队列: g_hMsgQueue = CreateMsgQueue(NULL, &msgOptions);其中的参数msgOptions是一个消息队列结构体,它定义了该队列的属性:

typedef MSGQUEUEOPTIONS_OS{
  DWORD dwSize;
  DWORD dwFlags;
  DWORD dwMaxMessages;
  DWORD cbMaxMessage;
  BOOL bReadAccess;
} MSGQUEUEOPTIONS, FAR* LPMSGQUEUEOPTIONS, *PMSGQUEUEOPTIONS;

    消息通信机制在wince中是很重要的一点,通过它可以实现驱动程序之间,驱动程序与应用程序之间的通信。

   接着又是一个很重要的函数:

  // Request Power notifications
    hPowerNotification = RequestPowerNotifications(g_hMsgQueue, POWER_NOTIFY_ALL);
    if (!hPowerNotification)
    {
        RETAILMSG(PWC_ZONE_ERROR,(_T("[PWRCON:ERR] %s->RequestPowerNotifications() Failed : Err %d/n"), _T(__FUNCTION__), GetLastError()));
        goto Thread_CleanUp;
    }
函数equestPowerNotifications使电源管理器在发现系统电源状态变化时向它发出通知,即电源状态变化了!它的第一个参数就是上面创建消息队列时得到的句柄,第二个参数POWER_NOTIFY_ALL意思是获取电源任何变化的通知。

       到这里基本工作已经完成,即创建了消息队列,也告诉了电源管理器当系统电源状态改变时发出通知。那么接下来要做的就是接受这些通知并进行相应的操作。这部分主要代码如下:

 

    这里是通过轮询的方式去查看是否有电源状态改变的消息,该函数是:ReadMsgQueue(g_hMsgQueue, msgBuf, QUEUE_SIZE, &iBytesInQueue, INFINITE, &dwFlags);如果读到了消息就返回相应的值,否则返回NULL.

     得到相应的消息后就要进行处理了,这里采用的是结构清晰的switch-case语句,即不同的消息进行不同的处理或打印出提示信息这部分比较简单,这里就不在多少。有一点要提醒,当推出线程的时候记得停止接受电源管理器的消息和关闭消息队列的句柄:

 StopPowerNotifications(hPowerNotification);

CloseMsgQueue(g_hMsgQueue);

      当该驱动程序被加载以后上述监视线程就开始工作了,直到被关闭。从其代码可以看出,该监视线程只能监视系统电源状态的变化并不能进行控制。那么如何去控制系统的电源状态和系统硬件模块的电源状态呢?很显然要用到PWC_IOControl了。

2。PWC_IOControl

     PWC_IOControl就是驱动程序提供给上层应用程序的接口用来控制系统和硬件模块的的电源状态。怎么控制呢?发命令!详细大家对XXX_IOControl的结构十分清晰,我也列出器代码:

     代码虽然长,但并不复杂,逻辑上还是很简单的。从其代码可以看出它的控制操作主要分为两种:IOCTL_PWRCON_SET_POWER_ON,IOCTL_PWRCON_SET_POWER_OFF,即关闭电源和打开电源。这两种操作是针对所以硬件模块来做的,没有具体到控制其中的一个硬件模块,如摄像头。当然我们可以添加自己的命令进行更为灵活的电源控制。

      整体来看该驱动比较简单,难点就是怎么把它用活,用巧。

抱歉!评论已关闭.