zoukankan      html  css  js  c++  java
  • ZLG7290(wince下)驱动之不停执行同一动作的解决办法(作者:wogoyixikexie@gliet)

    ZLG7290(wince下)驱动之不停执行同一动作的解决办法(作者:wogoyixikexie@gliet)

    //-----------------------------------------------------------------------------------------------------------

    // 日期:2009年3月23日 8:31:19

    // 作者:wogoyixikexie@gliet

    // 版权:桂林电子科技大学一系科协wogoyixikexie@gliet

    // 平台:wince5.0 2440 5.0 BSP

    // 最后修改:2009年3月23日 8:31:30

    //-----------------------------------------------------------------------------------------------------------

         今天,把原来4.2BSP的ZLG7290驱动搬到2440 5.0BSP下,只是简单修改一下中断的获得方式就成功了,哈哈,看到按键控制菜单真是爽呆了。可是出现了非常郁闷的事情,那就是按一下就会不停的执行按下的相应动作。这明显是中断不停的产生了,真是不知道如何搞的。现在的机子是成品不给拆卸,示波器用不上了,真是奇了,刚才我认为是是BSP没有处理好中断。OEMInterruptHandler函数有禁止中断的功能,在处理完相应的线程以后,我们必须调用InterruptDone函数来重新使能中断,我看了一下代码,发现这个OEMInterruptHandler并没有问题,并且即使没有禁止,也只会在按下的时候多次中断发生,而不会没有按的时候不停的中断。我觉得还是这个ZLG7290的问题,极有可能他不停的产生了中断信号,明天使用示波器之后就会知道了。

         现在不妨看看这个键盘驱动是怎么回事。在命令行窗口输入 dumpbin  /exports  键盘驱动DLL

          --明天继续吧,下班打篮球了。

          继续.........

         先来看看这个DLL到处了什么函数。

    LIBRARY         LAYOUTMANAGER——哈哈,这个名字可以改动的吗?以前没有注意这个问题。

     EXPORTS

     KeybdDriverInitializeEx
     KeybdDriverPowerHandler
     KeybdDriverGetInfo
     KeybdDriverSetMode
     KeybdDriverInitStates
     KeybdDriverVKeyToUnicode
     KeybdDriverMapVirtualKey

     LayoutMgrGetKeyboardType
     LayoutMgrGetKeyboardLayout
     LayoutMgrGetKeyboardLayoutName
     LayoutMgrGetKeyboardLayoutList
     LayoutMgrLoadKeyboardLayout
     LayoutMgrActivateKeyboardLayout

     IL_00000409
     Matrix
     PS2_AT_00000409

         从这些函数找突破口很容易找到问题所在。

         根据现象,我觉得产生这种原因有两种可能:一个是中断不停的产生,一个是没有检测按键弹起出了问题。我设置接ZLG7290的中断引脚的EINT11为双边沿触发的?难道上升沿触发无效(即检测按键弹起)?好用sunrain_hjb的工具修改一下中断方式看看到底是怎么回事。

          

           

     

         0x22224242是把EINT11设置成上升沿触发(检测键盘弹起中断),这样之后按键按下弹起不会做任何动作了,难道真的是没有检测到上升沿中断?我把把EINT11设置成下降沿触发(检测键盘按下中断),按键又能工作了,效果和双边触发一样。上面的猜测不一定成功,要把键盘的IST移到BSP中加入打印信息就知道是否产生了上升沿触发中断了。

         郁闷,当设置成上升沿触发的时候果然什么反映都没有啊,怎么搞的?难道上升沿是什么事情都不做?

         我在keyboard IST里面加了打印信息,来看看按一次是否能产生两次中断。

    BOOL
    KeybdIstLoop(
        PKEYBD_IST pKeybdIst
        )
    {
        SETFNAME(_T("KeybdIstLoop"));

        UINT32  rguiScanCode[16];
        BOOL    rgfKeyUp[16];
        UINT    cEvents;
     // add by wogo at 2009-03-12
     RETAILMSG(1, (TEXT("In KeybdIstLoop Funtion:\r\n")));
        DEBUGCHK(pKeybdIst->hevInterrupt != NULL);
        DEBUGCHK(pKeybdIst->pfnGetKeybdEvent != NULL);
        DEBUGCHK(pKeybdIst->pfnKeybdEvent != NULL);

        SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

    wait_for_keybd_interrupt:
        if (WaitForSingleObject(pKeybdIst->hevInterrupt, INFINITE) == WAIT_OBJECT_0)
        {
      // add by wogo at 2009-03-12
      RETAILMSG(1, (TEXT("Deal with hevInterrupt@@@!!! :\r\n")));
            cEvents = (*pKeybdIst->pfnGetKeybdEvent)
                (pKeybdIst->uiPddId, rguiScanCode, rgfKeyUp);
               
            for (UINT iEvent = 0; iEvent < cEvents; ++iEvent) {
                (*pKeybdIst->pfnKeybdEvent)(pKeybdIst->uiPddId,
                    rguiScanCode[iEvent], rgfKeyUp[iEvent]);
            }
            // cEvents could be 0 if this was a partial scan code, like 0xE0

            InterruptDone(pKeybdIst->dwSysIntr_Keybd);
      // add by wogo at 2009-03-12
      RETAILMSG(1, (TEXT("InterruptDone(pKeybdIst->dwSysIntr_Keybd)@@@!!! :\r\n")));
        }

        goto wait_for_keybd_interrupt;

        ERRORMSG(1, (TEXT("KeybdIstLoop: Keyboard driver thread terminating.\r\n")));
     RETAILMSG(1, (TEXT("KeybdIstLoop: Keyboard driver thread terminating!!! :\r\n")));
        return TRUE;
    }

         找到问题了,果然按下一次按键只打印了如下信息

    Deal with hevInterrupt@@@!!! :
    InterruptDone(pKeybdIst->dwSysIntr_Keybd)@@@!!! :
         按照常理,使用双边触发,按一次应该打印如下。

    Deal with hevInterrupt@@@!!! :
    InterruptDone(pKeybdIst->dwSysIntr_Keybd)@@@!!! :
    Deal with hevInterrupt@@@!!! :
    InterruptDone(pKeybdIst->dwSysIntr_Keybd)@@@!!! :

         现在难搞了,使用应用程序去读中断寄存器的设置,读出是0x22226242,这个和要求完全吻合,怎么就不产生双边沿触发呢?难道是干扰?我的天啊,真是越来越神奇了。神啊,救救我吧!

         后来我根据CSDN的shuiyan牛人的建议做了如下事情:

         一、在按下之后禁止下降沿中断,使能上升沿中断——》结果:当按下键盘太久的时候,可以产生弹起中断,快点只能产生按下中断;配置成双边触发却不行,这个说明双边触发的反映速度比单片触发要慢。

         二、把中断线程里面的代码全部删除——》结果:可以产生按下、弹起中断。这个足以证明是中断处理线程调用的ZLG7290的键盘扫描函数花掉了大量时间,后来我把里面的for循环延时全部删除,但是还是无济于事,后来逼急了想了个绝招——在按下之后设置一个标志告诉系统,已经按下,这样系统就不会不停的做同一件事情啊。结果成功解决问题。

         现在把结果公布,造福后人——把微软的键盘IST移植到BSP下添加的。

    键盘功能通过偏方实现了功能,但是不能扑捉到键盘弹起中断的问题依然没有解决。

    我在按下线程里面加了一个键盘弹起的标志,告诉系统,就这样,这个键盘就搞定了。哈哈
    哎,就是加了两行东西。
    wait_for_keybd_interrupt:
        if (WaitForSingleObject(pKeybdIst->hevInterrupt, INFINITE) == WAIT_OBJECT_0)
        {
    // add by wogo at 2009-03-12
    //RETAILMSG(1, (TEXT("Deal with hevInterrupt@@@!!! :\r\n")));
    //#if 0
            cEvents = (*pKeybdIst->pfnGetKeybdEvent)
                (pKeybdIst->uiPddId, rguiScanCode, rgfKeyUp);
            //
            //RETAILMSG(1, (TEXT("cEvents=%d\r\n"), cEvents));
            for (UINT iEvent = 0; iEvent < cEvents; ++iEvent) {
            //UINT iEvent = 0
            (*pKeybdIst->pfnKeybdEvent)(pKeybdIst->uiPddId, rguiScanCode[iEvent], rgfKeyUp[iEvent]);
    rgfKeyUp[iEvent]=TRUE;——我原来太执着于本身了,不过键盘功能是实现了,但是本质没有解决。
    (*pKeybdIst->pfnKeybdEvent)(pKeybdIst->uiPddId, rguiScanCode[iEvent], rgfKeyUp[iEvent]);

            }
            // cEvents could be 0 if this was a partial scan code, like 0xE0
        //#endif

            InterruptDone(pKeybdIst->dwSysIntr_Keybd);
    // add by wogo at 2009-03-12
    //RETAILMSG(1, (TEXT("InterruptDone.Keybd)\r\n")));
        } 

         感谢各位关照,尤其是shuiyan前辈,他自己忙着加班,还要回我的问题。

         现在来对键盘驱动做个总结吧。

         MDD太复杂了,这里就不谈了,现在就来谈PDD和IST

         C:\WINCE500\PLATFORM\SMDK2440A\Src\Drivers\Keybd\Kbdcommon里面的东西构成了PDD

         初始化(中断,IO等)——》申请中断——》调用键盘IST——》等待中断(MDD IST)

         下面代码相当重要,用来绑定IST,使MDD和PDD紧密结合起来。

     KEYBD_IST keybdIst;
     keybdIst.hevInterrupt = m_hevInterrupt;
     keybdIst.dwSysIntr_Keybd = dwSysIntr_Keybd;
     keybdIst.uiPddId = v_uiPddId;
     keybdIst.pfnGetKeybdEvent = KeybdPdd_GetEventEx2;
     keybdIst.pfnKeybdEvent = v_pfnKeybdEvent;
      
     KeybdIstLoop(&keybdIst);

          论坛同步帖子http://topic.csdn.net/u/20090312/14/51c097e2-11a8-49eb-b5f0-38bf15d84107.html

  • 相关阅读:
    Judy alpha 第九天
    Judy alpha 第八天
    Judy alpha 第七天
    Judy alpha 第六天
    Judy alpha 第五天
    Judy alpha 第四天
    Fieldtrip 和 spm 文件读取
    matlab更改打开时候默认路径
    mne-python 安装大法
    Greenhouse-Geisser;统计结果报告;效应力大小介绍
  • 原文地址:https://www.cnblogs.com/gooogleman/p/1869718.html
Copyright © 2011-2022 走看看