6410+wince6.0定时关屏
1、读取注册表的超时时间值,在线程中以这个时间为超时时间,超时后关屏。
2、等待用户输入事件(点击触摸屏或按键等)和注册表超时时间改变事件。当这两个事件出现时重新读取超时时间。这些事件需要设定为同名事件以便不同文件间使用。
代码如下:
一、LCD驱动
#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
#include <pm.h>
#include <DrvLib.h>
#include <s3c6410_gpio.h>
#include <s3c6410_base_regs.h>
//#include <s3c6410_pwm.h>
#include "pmplatform.h"
#include "Pkfuncs.h"
//#include "pwm.h"
#include <bsp.h>
BOOL LCD_Close(DWORD hOpenContext);
BOOL LCD_Deinit(DWORD hDeviceContext);
DWORD LCD_Init(DWORD dwContext);
DWORD LCD_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode);
void LCD_PowerUp(DWORD hDeviceContext);
void LCD_PowerDown(DWORD hDeviceContext);
DWORD LCD_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count);
DWORD LCD_Seek(DWORD hOpenContext, long Amount, DWORD Type);
DWORD LCD_Write(DWORD hOpenContext, LPCVOID pSourceBytes, DWORD NumberOfBytes);
BOOL LCD_IOControl(DWORD hOpenContext,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut);
static volatile S3C6410_GPIO_REG * GPIOReg = 0;
//static volatile S3C6410_PWM_REG * PWMReg = 0;
#define LCDON 1 //开屏
#define LCDOFF 2 //关屏
static HANDLE gThread;
BOOL WINAPI
DllEntry(HANDLE hinstDLL,
DWORD dwReason,
LPVOID Reserved/* lpvReserved */)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
DEBUGREGISTER((HINSTANCE)hinstDLL);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
#ifdef UNDER_CE
case DLL_PROCESS_EXITING:
break;
case DLL_SYSTEM_STARTED:
break;
#endif
}
return TRUE;
}
//读取注册表获取关屏的时间
BOOL GetCloseLCDTime(BYTE *Buffer)
{
HKEY hResult;
LONG lRet;
LPWSTR lpSubKey = _T("\\Drivers\\BuiltIn\\BackLight");
DWORD size = sizeof(Buffer);
lRet =RegOpenKeyEx(HKEY_LOCAL_MACHINE,lpSubKey,0,KEY_ALL_ACCESS,&hResult);
if (lRet != ERROR_SUCCESS)
{
return FALSE;
}
lRet = RegQueryValueEx(hResult,_T("BKLTimeout"), NULL, NULL, (LPBYTE)Buffer, &size);
if(lRet != ERROR_SUCCESS)
{
return FALSE;
}
RegCloseKey(hResult);
return TRUE;
}
//等待事件线程
DWORD EventThread(PVOID pArg)
{
DWORD dwResult;
DWORD dwTimeout=INFINITE;
HANDLE gEvent[2];
//创建事件
gEvent[0] = CreateEvent(NULL, FALSE, FALSE, L"CLoseLCDTimeOutChange");
gEvent[1] = CreateEvent(NULL, FALSE, FALSE, L"UserInputEvent");
// gEvent[1] = CreateEvent(NULL, FALSE, FALSE, L"PowerManager/ActivityTimer/UserActivity");
//读自动关机时间
GetCloseLCDTime((BYTE*)&dwTimeout);
dwTimeout = dwTimeout*1000;
// dwTimeout=10000; //给成固定的10秒
while (1)
{
dwResult = WaitForMultipleObjects(2,gEvent,FALSE, dwTimeout );
if (dwResult == WAIT_TIMEOUT)
{
GPIOReg->GPEDAT &= 0xE; //把GPE0置为低,LCD灭
}
else
{
if (dwResult ==(WAIT_OBJECT_0) || dwResult==(WAIT_OBJECT_0+1))
{
//时间修改,需要重读
GetCloseLCDTime((BYTE*)&dwTimeout);
dwTimeout = dwTimeout*1000;
GPIOReg->GPEDAT |= 0x1; //把GPE0置为高,LCD亮
//dwTimeout=10000; //给成固定的10秒
}
}
}
return 0;
}
BOOL LCD_Deinit(DWORD hDeviceContext)
{
if (GPIOReg) {
DrvLib_UnmapIoSpace((PVOID)GPIOReg);
}
/* if (PWMReg) {
DrvLib_UnmapIoSpace((PVOID)PWMReg);
}*/
GPIOReg = NULL;
// PWMReg = NULL;
return TRUE;
}
DWORD LCD_Init(DWORD dwContext)
{
BOOL bRet = TRUE;
GPIOReg = (S3C6410_GPIO_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_GPIO, sizeof(S3C6410_GPIO_REG), FALSE);
if (GPIOReg == NULL) {
RETAILMSG(1,(TEXT("PWM GPIO: VirtualAlloc failed\r\n")));
}
// PWMReg = (S3C6410_PWM_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_PWM, sizeof(S3C6410_PWM_REG), FALSE);
// if (PWMReg == NULL) {
// RETAILMSG(1,(TEXT("PWM PWM: VirtualAlloc failed\r\n")));
// }
// bRet = GPIOReg != NULL && PWMReg != NULL;
bRet = GPIOReg != NULL;
return bRet;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
BOOL LCD_IOControl(DWORD hOpenContext,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut)
{
switch(dwCode)
{
case LCDON:
GPIOReg->GPEDAT |= 0x1; //把GPE0置为高,LCD亮
break;
case LCDOFF:
GPIOReg->GPEDAT &= 0xE; //把GPE0置为低,LCD灭
break;
default:
break;
}
return TRUE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD LCD_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode)
{
GPIOReg->GPECON &= (~0xf); //把GPE0清零
GPIOReg->GPECON |= 0x1; //配置GPE0为output
DWORD IDThread;
gThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)EventThread , 0, 0, &IDThread);
if (gThread == 0)
{
return FALSE;
}
return TRUE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
BOOL LCD_Close(DWORD hOpenContext)
{
return TRUE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void LCD_PowerDown(DWORD hDeviceContext)
{
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void LCD_PowerUp(DWORD hDeviceContext)
{
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD LCD_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)
{
return 0;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD LCD_Seek(DWORD hOpenContext, long Amount, DWORD Type)
{
return 0;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD LCD_Write(DWORD hOpenContext, LPCVOID pSourceBytes, DWORD NumberOfBytes)
{
return 0;
}
二、在按键驱动和触摸屏驱动中加入
HANDLE gEvent;
gEvent = CreateEvent(NULL, FALSE, FALSE, L"UserInputEvent");
SetEvent(gEvent);
三、应用程序中重写注册表并设置同名事件CLoseLCDTimeOutChange
HKEY hKEY;
HKEY hKeyRoot = HKEY_LOCAL_MACHINE;
CString strPath=_T("\\Drivers\\BuiltIn\\BackLight");
long ret0=(::RegOpenKeyEx(hKeyRoot,strPath,0,KEY_READ,&hKEY));
if(ret0!=ERROR_SUCCESS)//如果无法打开hKEY,则中止程序的执行
{
AfxMessageBox(_T("错误:无法打开有关的hKEY"));
return ;
}
if (::RegSetValueEx(hKEY, _T("BKLTimeout"), 0, REG_DWORD, (const BYTE *) &m_dwBrightness, sizeof(DWORD)) != ERROR_SUCCESS)
{
AfxMessageBox(_T("错误:无法设置背光亮度"));
return ;
}
RegCloseKey(hKEY);
RegFlushKey( HKEY_CURRENT_USER);
HANDLE hld = CreateEvent(NULL, FALSE, FALSE,TEXT("CLoseLCDTimeOutChange"));
if (hld)
{
SetEvent(hld);
CloseHandle(hld);
Sleep(10);
}
注:其实进程间通信有常用的方法有use named event,还有use point-to-point message queues,这次用的是同名事件的方法,感觉很简单,消息队列那个以后我也看看怎么弄的。