PwrButton驱动不能触发 WaitForSingleObject

max   2009-3-4 21:52 楼主
我用的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;

        }

回复评论 (4)



        // 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;
}
点赞  2009-3-4 21:53
你的BSP是 5.0

这个ISR是已经写好的了的,只要弄好以上的代码就可以产生中断,

如果不能产生就是相关寄存器没有设置正确或者被别的驱动覆盖了。可参考我博客的外部串口调试方法,那个小工具很好用。
点赞  2009-3-4 22:55
正解
点赞  2009-3-5 11:53
先检查硬件中断发生了没!然后再调试修改code
点赞  2009-3-6 08:38
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复