我用的wince 5 2410平台,在PwrButton驱动不能触发 WaitForSingleObject(gPwrButtonIntrEvent, INFINITE)
下面是PwrButton驱动的代码:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*
* This driver uses EINT0 button as POWER ON/OFF Button.
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "pwrbtn2410.h"
#define PRIVATE static
#define PUBLIC
typedef DWORD (*PFN_SetSystemPowerState)(LPCWSTR, DWORD, DWORD);
PFN_SetSystemPowerState gpfnSetSystemPowerState;
// PRIVATE HANDLE gPwrButtonIntrEvent;
// PRIVATE HANDLE gPwrButtonIntrThread;
PRIVATE BOOL gOffFlag;
UINT32 g_PwrButtonIrq = IRQ_EINT8_23; // Determined by SMDK2410 board layout.
UINT32 g_PwrButtonSysIntr = SYSINTR_NOP;
PRIVATE volatile S3C2410X_IOPORT_REG * v_pIOPregs;
volatile S3C2410X_INTR_REG * v_pINTregs;
PRIVATE VOID
PBT_EnableInterrupt(VOID)
{
//v_pIOPregs->GPFCON &= ~(0x3 << 0); /* Set EINT0(GPF0) as EINT0 */
//v_pIOPregs->GPFCON |= (0x2 << 0);
// v_pIOPregs->GPGDAT &= ~(0x1 << 3); /* Set EINT11(GPG3) as EINT11 */
v_pIOPregs->GPGCON &= ~(0x3 << 6); /* Set EINT11(GPG3) as EINT11 */
v_pIOPregs->GPGCON |= (0x2 << 6);
//v_pIOPregs->EXTINT0 &= ~(0x7 << 0); /* Configure EINT0 as Falling Edge Mode */
//v_pIOPregs->EXTINT0 |= (0x2 << 0);
v_pIOPregs->EXTINT1 &= ~(0x7 << 12); /* Configure EINT11 as Falling Edge Mode */
v_pIOPregs->EXTINT1 |= (0x2 << 12);
v_pIOPregs->EINTMASK &= (~(1<<11)); // enable eint11 submask
v_pINTregs->INTMOD &= (~(1<<5)); //irq
v_pINTregs->INTMSK &= (~(1<<5)); //enable irq mask
}
PRIVATE BOOL
PBT_IsPushed(VOID)
{
//return ((v_pIOPregs->GPFDAT & (1 << 0)) ? FALSE : TRUE);
return ((v_pIOPregs->GPGDAT & (1 << 3)) ? FALSE : TRUE);
// return ((v_pIOPregs->GPGDAT & (1 << 3)) ? TRUE : FALSE);
// return FALSE;
}
PRIVATE BOOL
PBT_InitializeAddresses(VOID)
{
BOOL RetValue = TRUE;
RETAILMSG(1, (TEXT(">>> PBT_initalization address..set..\r\n")));
/* IO Register Allocation */
v_pIOPregs = (volatile S3C2410X_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2410X_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
v_pINTregs = (volatile S3C2410X_INTR_REG *)VirtualAlloc(0, sizeof(S3C2410X_INTR_REG), MEM_RESERVE, PAGE_NOACCESS);
// if (v_pIOPregs == NULL)
if((NULL==v_pINTregs) || (v_pIOPregs == NULL))
{
ERRORMSG(1,(TEXT("For IOPregs : VirtualAlloc failed!\r\n")));
RetValue = FALSE;
}
else
{
if (!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(S3C2410X_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2410X_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)
|| (!VirtualCopy((PVOID)v_pINTregs, (PVOID)(S3C2410X_BASE_REG_PA_INTR >> 8), sizeof(S3C2410X_INTR_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)))
{
ERRORMSG(1,(TEXT("For IOPregs: VirtualCopy failed!\r\n")));
RetValue = FALSE;
}
}
if (!RetValue)
{
RETAILMSG (1, (TEXT("::: PBT_InitializeAddresses - Fail!!\r\n") ));
if (v_pIOPregs)
{
VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE);
}
v_pIOPregs = NULL;
}
else RETAILMSG (1, (TEXT("::: PBT_InitializeAddresses - Success\r\n") ));
return(RetValue);
}
DWORD
PBT_IntrThread(PVOID pArg)
{
HANDLE gPwrButtonIntrEvent;
PBT_InitializeAddresses();
//init gpf0 the key led
v_pIOPregs->GPFDAT &= (~(1<<0));
v_pIOPregs->GPFCON &= (~(3<<0));
v_pIOPregs->GPFCON |= (1<<0);
v_pIOPregs->GPFUP &= (~(1<<0));
RETAILMSG(1,(TEXT("PWRBTN: Power on Keybd LED ! \n\r")));
PBT_EnableInterrupt();
gPwrButtonIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (NULL == gPwrButtonIntrEvent)
{
// ERRMSG("Unable to create gPwrButtonIntrEvent interrupt event");
RETAILMSG(1, (TEXT("::: Unable to create gPwrButtonIntrEvent interrupt event \r\n")));
return(FALSE);
}
RETAILMSG(1, (TEXT("::: Create gPwrButtonIntrEvent interrupt event OOKK \r\n")));
// Request a SYSINTR value from the OAL.
//
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &g_PwrButtonIrq, sizeof(UINT32), &g_PwrButtonSysIntr, sizeof(UINT32), NULL))
{
RETAILMSG(1, (TEXT("ERROR: PwrButton: Failed to request sysintr value for power button interrupt.\r\n")));
// g_PwrButtonSysIntr=SYSINTR_UNDEFINED;
return(0);
}
RETAILMSG(1,(TEXT("INFO: PwrButton: Mapped Irq 0x%x to SysIntr 0x%x.\r\n"), g_PwrButtonIrq, g_PwrButtonSysIntr));
if (!(InterruptInitialize(g_PwrButtonSysIntr, gPwrButtonIntrEvent, NULL, 0)))
{
// CloseHandle(gPwrButtonIntrEvent);
RETAILMSG(1, (TEXT("ERROR: PwrButton: Interrupt initialize failed.\r\n")));
return 0;
}
// update the IST priority
// CeSetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
while (1)
{
WaitForSingleObject(gPwrButtonIntrEvent, INFINITE);
if (gOffFlag == FALSE)
{
if (PBT_IsPushed()) /* To Filter Noise */
{
Sleep(200);
if (PBT_IsPushed())
{
RETAILMSG(1, (TEXT("::: Back Light On/Off \r\n")));
}
else
{
// Soft reset and standard suspend-resume both start with suspend for now.
#if (WINCEOSVER >= 400)
// call whichever shutdown API is available
if(gpfnSetSystemPowerState != NULL)
{
gpfnSetSystemPowerState(NULL, POWER_STATE_SUSPEND, POWER_FORCE);
}
else
{
PowerOffSystem();
}
#else
PowerOffSystem();
#endif
// Give control back to system if it wants it for anything. Not in
// power handling mode yet. All suspend and resume operations
// will be performed in the PowerOffSystem() function.
Sleep(0);
}
}
InterruptDone(g_PwrButtonSysIntr);
}
}
RETAILMSG(1, (TEXT(":::end while 1 \r\n")));
return 0;
}
PUBLIC DWORD
DSK_Init(DWORD dwContext)
{
PDISK pDisk;
DWORD IDThread;
HMODULE hmCore;
HANDLE gPwrButtonIntrThread;
pDisk = (PDISK)dwContext;
// contain the appropriate APIs.
gpfnSetSystemPowerState = NULL;
hmCore = (HMODULE) LoadLibrary(_T("coredll.dll"));
if(hmCore != NULL) {
gpfnSetSystemPowerState = (PFN_SetSystemPowerState) GetProcAddress(hmCore, _T("SetSystemPowerState"));
if(gpfnSetSystemPowerState == NULL) {
FreeLibrary(hmCore);
}
}
do
{
gPwrButtonIntrThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) PBT_IntrThread, 0, 0, &IDThread);
RETAILMSG(1, (TEXT("::: PBT_IntrThread ID = %x\r\n"), IDThread));
if (gPwrButtonIntrThread == 0)
{
RETAILMSG(1, (TEXT("::: CreateThread() Fail\r\n")));
break;
}
} while (0);
RETAILMSG(1, (TEXT("::: PBT_Init Out\r\n")));
pDisk->d_DiskCardState = 1;
return (DWORD)pDisk;
}
PUBLIC BOOL WINAPI
DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
switch ( dwReason )
{
case DLL_PROCESS_ATTACH:
RETAILMSG(1, (TEXT("PwrButton : DLL_PROCESS_ATTACH\r\n")));
DisableThreadLibraryCalls((HMODULE) hInstDll);
break;
}
return (TRUE);
}
BOOL
DSK_Close(
DWORD Handle
)
{
return TRUE;
} // DSK_Close
//
// Device deinit - devices are expected to close down.
// The device manager does not check the return code.
//
BOOL
DSK_Deinit(
DWORD dwContext // future: pointer to the per disk structure
)
{
return TRUE;
} // DSK_Deinit
//
// Returns handle value for the open instance.
//
DWORD
DSK_Open(
DWORD dwData,
DWORD dwAccess,
DWORD dwShareMode
)
{
return 0;
} // DSK_Open
//
// I/O Control function - responds to info, read and write control codes.
// The read and write take a scatter/gather list in pInBuf
//
BOOL
DSK_IOControl(
DWORD Handle,
DWORD dwIoControlCode,
PBYTE pInBuf,
DWORD nInBufSize,
PBYTE pOutBuf,
DWORD nOutBufSize,
PDWORD pBytesReturned
)
{
return FALSE;
} // DSK_IOControl
DWORD DSK_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes)
{
return 0;
}
DWORD DSK_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes)
{
return 0;
}
DWORD DSK_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod)
{
return 0;
}
void DSK_PowerUp(void)
{
return;
}
void
DSK_PowerDown(void)
{
RETAILMSG(1,(TEXT("PBT_PowerDown!\r\n")));
return;
}
你的BSP是 5.0
这个ISR是已经写好的了的,只要弄好以上的代码就可以产生中断,
如果不能产生就是相关寄存器没有设置正确或者被别的驱动覆盖了。可参考我博客的外部串口调试方法,那个小工具很好用。