none
x86平台wince6.0中断驱动问题 RRS feed

  • 问题

  • 正在调试x86平台wince6.0中断驱动,查了很多资料,调用总是失败,大家帮忙看看有什么问题:
    #include <windows.h>
    #include <devload.h>
    #include <pm.h>
    #include <nkintr.h>
    #include <types.h>
    #include <ceddk.h>
    #include <Pkfuncs.h>

    #define DBGMSG  NKDbgPrintfW

    #define SIZE  0x20

    #define PHADDRESS 0xd0200

    BOOL APIENTRY DllMain( HANDLE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
          )
    {
        return TRUE;
    }


    unsigned int FPGAAddrbase;
    char buffer[SIZE];
    LPVOID AAddrbase;
    HANDLE mhevent;  //中断响应事件句柄
    DWORD midint;   //逻辑中断号
    DWORD g_midint=10; //物理中断号
    HANDLE mhthread;  //中断服务线程句柄


    /*
     * Allow only one person to hold it open
     */

    DWORD MEM_Open(DWORD hDeviceContext,DWORD AccessCode, DWORD ShareMode)
    {

     DBGMSG(TEXT("Mem START...\r\n"));
     return hDeviceContext;

    }

    /*
     * shut off the timer.
     * lock it in if it's a module and we defined...NOWAYOUT
     * oddly, the watchdog can only be enabled, but we can turn off
     * the interrupt, which appears to prevent the watchdong timing out.
     */

    DWORD MEM_Deinit(DWORD hDeviceContext)
    {

     int ret = 0;
     DBGMSG(TEXT("stop MEM\r\n"));
     return ret;

    }

    DWORD MEM_Write(DWORD hOpenContext,LPCVOID pSourceBytes,DWORD NumberOfBytes)
    {

     DWORD dTotal = 0;
     DBGMSG(TEXT("MSC_Write...\r\n"));
     return dTotal;

    }

    DWORD MEM_IOControl (DWORD hOpenContext, DWORD Cmd, DWORD Value, DWORD dwLenIn,
       PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut)
    {

     return true;

    }

    DWORD KeypadIST(void * dat)
    {

     mhevent=CreateEvent(NULL,FALSE,FALSE,NULL);//创建中断事件mhevent

     if (InterruptInitialize(midint,mhevent,NULL,0))//绑定逻辑中断号midint和事件mhevent
     {
      DBGMSG(TEXT("InterruptInitialize successed!\r\n"));
     }

     while(1)
     {
      DBGMSG(TEXT("WaitForSingleObject...\r\n"));

      WaitForSingleObject(mhevent,INFINITE);//等待事件mhevent发生
    //****************中断相应后所做的操作可按需要更改*****************
    //*********************这里是对内存的读取操作**********************
      unsigned int pAddrbase=PHADDRESS;

      for(int i=0;i<SIZE;i++)
      {
       if(i%16==0)
       {
        RETAILMSG(TRUE, (TEXT("\r\n")));
       }
      RETAILMSG(TRUE, (TEXT("%4x"),*(unsigned char * )(pAddrbase+i))); 
      }

      PHYSICAL_ADDRESS FPGAAddress = {PHADDRESS,0};

      AAddrbase=MmMapIoSpace( FPGAAddress, SIZE,FALSE );//把物理内存FPGAAddress映射到虚拟内存,MmMapIoSpace返回值即为虚拟内存地址

      FPGAAddrbase =(unsigned int)AAddrbase;

      RETAILMSG(TRUE, (TEXT("\r\nMmMapIoSpace=%x\r\n"),FPGAAddrbase));

      for(int i=0;i<SIZE;i++)
      {

       if(i%16==0)
       {
        RETAILMSG(TRUE, (TEXT("\r\n")));
       }

      RETAILMSG(TRUE, (TEXT("%4x"),*(unsigned char * )(FPGAAddrbase+i)));

      }
    //*************************************************************
      InterruptDone(midint);//中断完成

      RETAILMSG(TRUE, (TEXT("\r\n")));

     }
    }

    DWORD MEM_Init (DWORD dwContext)
    {

     DBGMSG(TEXT("\r\n\n\n\n\ninit MEM \r\n"));
    // midint=Mapirq2Sysintr(5);

     if(KernelIoControl(IOCTL_HAL_TRANSLATE_IRQ,&g_midint,sizeof(UINT32),&midint,sizeof(UINT32),NULL)) //计算物理中断号对应的虚拟中断号
            {
                DBGMSG(TEXT("KernelIoControl successed!\r\n"));
            }

     RETAILMSG(TRUE, (TEXT("g_midint=%d\r\n"),g_midint));

     RETAILMSG(TRUE, (TEXT("midint=%d\r\n"),midint));

     mhthread=CreateThread(NULL,0,&KeypadIST,0,0,NULL);//创建中断服务线程mhthread

     if(mhthread!=NULL)
     {
      DBGMSG(TEXT("CreateThread successed!\r\n"));
     }

     CeSetThreadPriority(mhthread,0);//改变中断服务线程的优先级

    // InterruptDisable(midint);//关闭中断

     return dwContext;
    }

     

    BOOL MEM_Close (DWORD hOpenContext)
    {
     BOOL bRet = TRUE;

     DBGMSG(TEXT("MEM_Close... \r\n"));
     return bRet;
    }

    void MEM_PowerDown (DWORD hDeviceContext)
    {
     return;
    }

    void MEM_PowerUp (DWORD hDeviceContext)
    {
     return;
    }

    DWORD MEM_Read (DWORD hOpenContext,LPVOID pBuffer,DWORD Count)
    {

     DBGMSG(TEXT("MSC_Read...\r\n"));
    /*
     memset(pBuffer,0,SIZE);

        for(int i=0;i<SIZE;i++)
     {
      if(i%16==0){
      RETAILMSG(TRUE, (TEXT("\r\n")));
     }

     RETAILMSG(TRUE, (TEXT("%4x"),*(unsigned char * )(FPGAAddrbase+i)));

     }

     RETAILMSG(TRUE, (TEXT("\r\npBuffer=%x\r\n"),(unsigned int)pBuffer));

     for(int i=0;i<SIZE;i++)
     {

     *(unsigned char * )(((unsigned int)pBuffer)+i)=*(unsigned char * )(FPGAAddrbase+i);

     }

    */
     return 9;
    }

    DWORD MEM_Seek (DWORD hOpenContext,long Amount,DWORD Type)
    {
     DWORD dwRet = TRUE;

     return dwRet;
    }
    注册表:
    [HKEY_LOCAL_MACHINE\Drivers\BuiltIn\MEM]
        "Index"=dword:1
        "Dll"="mem.dll"
        "Prefix"="MEM"
        "Order"=dword:0
    调用程序如下:
    // CAllDriver.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include <windows.h>
    #include <commctrl.h>
    HANDLE CALLD;

    int _tmain(int argc, _TCHAR* argv[])
    {
    HANDLE hStr;
    hStr=CreateFile(_T("MEM1:"),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,0);
    if (INVALID_HANDLE_VALUE==hStr)
    { MessageBox(NULL,_T("Cannot open MEM1"),_T("StringAPP"),MB_OK); }
    else
    { MessageBox(NULL,_T("success open MEM1"),_T("StringAPP"),MB_OK); }
    while(1)
    {
    Sleep(INFINITE); }
     return 0;
    }
    调用返回是失败!

    2010年2月24日 7:43

全部回复

  • 你的代码有以下几点问题
    1。 MEM_Init应该有两个参数,而不是一个。它的prototype是DWORD XXX_Init(LPCTSTR RegistryPath, DWORD dwBusContect)。
    2。 MEM_Init的第一个参数是一个字符串,这个字符串是指向该驱动程序自己在注册表里信息的位置。这个不应该作为函数返回值。Device.exe所期望的返回值是一个指针,指向一个内存空间,该空间用来保存驱动程序自己的一些信息。
    3。 MEM_Open的参数hDeviceContext,一般来说就是之前MEM_Init返回的值。既然MEM_Init中所返回的是一个错误的值(字符串指针,很有可能这个字符串的空间已经被release了),你如果直接返回hDeviceContext的话,Device.exe很可能会产生错误。一般来说MEM_Open返回的应该是一个指针,指向一个内存空间,该空间用来保存与当前打开该驱动程序的用户进程相关的一些信息。
    4。 这两个函数中任何一个返回0,都会导致驱动程序无法打开。
    2010年3月3日 2:23
    版主
  • 可以设断点的。不妨做一个Debug Build,然后hardcode一个DebugBreak()函数在驱动的Init和Open函数里面,然后一步一步跟踪,即可知道错在哪里。
    最近有了小宝宝,他比较淘气,所以来这里的时间少了挺多。非常抱歉。
    2010年3月8日 13:49
    版主