以下是系统启动时串口的打印信息
KEY:DLL SUCCESS ATTACH !
*****EINT_INITALIIZATION ADDRESS.SET
INITALIZEADDRESS SUCCESS!!!
INFO:ANJIAN:MAPPED IRQ success!!
InterruptDisable!
KEY_INIT SUCCESS!
IST SUCCESS!
***EINTKey interrupt done!!
以下是当某个键按下时的信息
***THE KEY[0] PUSHED.***
***THE KEY[0] done.***
问题是:当某个键按下后,可以相应并在串口可以打引出相关信息,但是此后其他按键(包括此按键)不在响应,因为串口不在打印相关信息。
以下是驱动程序
#include<windows.h>
#include<types.h>
#include<memory.h>
#include<ceddk.h>
#include<excpt.h>
#include<tchar.h>
#include<diskio.h>
#include<windev.h>
#include<nkintr.h>
#include<ethdbg.h>
#include<pkfuncs.h>
#include<s3c2440a_intr.h>
#include<s3c2440a_ioport.h>
#include<s3c2440a_base_regs.h>
#include "bsp.h"
#define EINT0 EXTINT0
#define PRIVATE static
#define PUBLIC
//gpio jicunqi duying de xuni dizhi
PRIVATE volatile S3C2440A_IOPORT_REG* IOPreg;
PRIVATE UINT32 intnum; //INTERRUPT NUMBER
PRIVATE HANDLE gReadKeyEvent[5];//du anjian shijian
PRIVATE HANDLE gWaitEvent;//anjian anxia zhongduan shijian
PRIVATE UINT32 g_KillIST=FALSE;//SHIFOU TUICHU ZHONGDUAN XIANCHENG
PRIVATE HANDLE KeyThread;//ZHONGDUAN CHULI XIANCHENG
PRIVATE UINT32 gOpenCount=0;//qudong dakai jishuqi;
PRIVATE UINT32 IRQ;//物理中断号及逻辑中断号
PRIVATE UINT32 KeySysIntr[4];//中断IST 标识符
//PRIVATE UINT32 EINTSysIntr[4];
DWORD EINTKey_IntrThread(PVOID pArg);
PRIVATE BOOL Key_IsPushed(INT32 num);
PRIVATE VOID EINT_ConfigPinDefault(void);
//流驱动入口
BOOL WINAPI MYK_DllEntry(HANDLE hInstDll,DWORD dwReason,LPVOID IpvReserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
RETAILMSG(1,(TEXT("KEY:DLL SUCCESS ATTACH !\r\n")));
DisableThreadLibraryCalls((HMODULE)hInstDll);
break;
case DLL_PROCESS_DETACH:
RETAILMSG(1,(TEXT("key:DEATTCH!\r\n")));
break;
}
return(TRUE);
}
//初始化中断地址,申请虚拟内存并将其对应到物理内存
PRIVATE BOOL EINT_InitializeAddresses(VOID)
{
BOOL RetValue=TRUE;
RETAILMSG(1,(TEXT("*****EINT_INITALIIZATION ADDRESS.SET\r\n")));
IOPreg=(volatile S3C2440A_IOPORT_REG*)VirtualAlloc(0,sizeof(S3C2440A_IOPORT_REG),MEM_RESERVE,PAGE_NOACCESS);
if(IOPreg==NULL)
{
ERRORMSG(1,(TEXT("VIRTUALALLOC FAILED!\r\n")));
RetValue=FALSE;
}
else
{
if(!VirtualCopy((PVOID)IOPreg,(PVOID)(S3C2440A_BASE_REG_PA_IOPORT>>8),sizeof(S3C2440A_IOPORT_REG),PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE))
{
ERRORMSG(1,(TEXT("VIRTUALCOPY FAILED!\r\n")));
RetValue=FALSE;
}
}
if(!RetValue)
{
RETAILMSG(1,(TEXT("INITALIZEADDRESS FAILED!!\r\n")));
if(IOPreg)
{
VirtualFree((PVOID)IOPreg,0,MEM_RELEASE);
}
IOPreg=NULL;
}
else
{
RETAILMSG(1,(TEXT("INITALIZEADDRESS SUCCESS!!!\r\n")));
return(RetValue);
}
}
//中断口配置
PRIVATE VOID EINT_ConfigInterruptPin(void)
{
IOPreg->GPFCON &=~(0X3<<8);//GPF4 INT4
IOPreg->GPFCON |=(0X2<<8);
IOPreg->GPFCON &=~(0X3<<6);//GPF3 INT3
IOPreg->GPFCON |=(0X2<<6);
IOPreg->GPFCON &=~(0X3<<4);//GPF2 INT2
IOPreg->GPFCON |=(0X2<<4);
IOPreg->GPFCON &=~(0X3);//GPF0 INT0
IOPreg->GPFCON |=(0X2);
IOPreg->EINT0&=~(0X7<<16);
IOPreg->EINT0|=(0X2<<16);//FALLING EDGE TIGGERED MODS
IOPreg->EINT0&=~(0X7<<12);
IOPreg->EINT0|=(0X2<<12);//FALLING EDGE TIGGERED MODS
IOPreg->EINT0&=~(0X7<<8);
IOPreg->EINT0|=(0X2<<8);//FALLING EDGE TIGGERED MODS
IOPreg->EINT0&=~(0X7<<0);
IOPreg->EINT0|=(0X2<<0);//FALLING EDGE TIGGERED MODS
}
//流驱动加载,申请逻辑中断号,中断禁止及创建中断线程
DWORD MYK_Init(LPCTSTR dwContext)
{
DWORD IDThread;
INT32 i;
if(EINT_InitializeAddresses()==FALSE)
return 0;
EINT_ConfigInterruptPin();
//从OAL请求一个SYSINTR值
IRQ=0;//INT0
if(!(KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,&IRQ,sizeof(UINT32),&KeySysIntr[0],sizeof(UINT32),NULL)))//#DEFINE IOCTL_HAL_REQUSE_IRQ CTL_CODE(DEVICETYPE(16-31),ACCESS(14-15)FUNCTION,METHOD) tashi yongyu chuangjian yige weiyi de 32 wei io kongzhima
{
RETAILMSG(1,(TEXT("ERROR:FAILED TO REQUEST SYSINTR VALUE!\r\n")));
return FALSE;
}
IRQ=2;//INT2
if(!(KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,&IRQ,sizeof(UINT32),&KeySysIntr[1],sizeof(UINT32),NULL)))//#DEFINE IOCTL_HAL_REQUSE_IRQ CTL_CODE(DEVICETYPE(16-31),ACCESS(14-15)FUNCTION,METHOD) tashi yongyu chuangjian yige weiyi de 32 wei io kongzhima
{
RETAILMSG(1,(TEXT("ERROR:FAILED TO REQUEST SYSINTR VALUE!\r\n")));
return FALSE;
}
IRQ=3;//INT3
if(!(KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,&IRQ,sizeof(UINT32),&KeySysIntr[2],sizeof(UINT32),NULL)))//#DEFINE IOCTL_HAL_REQUSE_IRQ CTL_CODE(DEVICETYPE(16-31),ACCESS(14-15)FUNCTION,METHOD) tashi yongyu chuangjian yige weiyi de 32 wei io kongzhima
{
RETAILMSG(1,(TEXT("ERROR:FAILED TO REQUEST SYSINTR VALUE!\r\n")));
return FALSE;
}
IRQ=32;//INT4
if(!(KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,&IRQ,sizeof(UINT32),&KeySysIntr[3],sizeof(UINT32),NULL)))//#DEFINE IOCTL_HAL_REQUSE_IRQ CTL_CODE(DEVICETYPE(16-31),ACCESS(14-15)FUNCTION,METHOD) tashi yongyu chuangjian yige weiyi de 32 wei io kongzhima
{
RETAILMSG(1,(TEXT("ERROR:FAILED TO REQUEST SYSINTR VALUE!\r\n")));
return FALSE;
}
RETAILMSG(1,(TEXT("INFO:ANJIAN:MAPPED IRQ success!!\r\n")));
InterruptDisable(KeySysIntr[0]);
InterruptDisable(KeySysIntr[1]);
InterruptDisable(KeySysIntr[2]);
InterruptDisable(KeySysIntr[3]);
RETAILMSG(1,(TEXT(" InterruptDisable!\r\n")));
//创建外部中断线程IST
KeyThread=CreateThread(0,0,(LPTHREAD_START_ROUTINE)EINTKey_IntrThread,0,0,&IDThread);
if(KeyThread==NULL)
{
RETAILMSG(1,(TEXT("CREATETHREAD() FAILED!\r\n")));
return 0;
}
for(i=0;i<4;i++)
{
gReadKeyEvent[i]=CreateEvent(NULL,FALSE,FALSE,NULL);
}
RETAILMSG(1,(TEXT("KEY_INIT SUCCESS!\r\n")));
return(DWORD)KeyThread;
}
//中断线程函数
DWORD EINTKey_IntrThread(PVOID pArg)
{
DWORD ret;
INT32 numb;
gWaitEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
if(gWaitEvent==NULL)
{
RETAILMSG(1,(TEXT("FRAILED CREATEEVENT!\r\n")));
return FALSE;
}
for(numb=0;numb<4;numb++)
{
if(!InterruptInitialize(KeySysIntr[numb],gWaitEvent,NULL,0))
{
RETAILMSG(1,(TEXT("ERROR:FAILED TO INITIALIZE USEKEY %d INTERRUPT EVENT\n\r"),numb));
CloseHandle(gWaitEvent);
return FALSE;
}
}
RETAILMSG(1,(TEXT("IST SUCCESS!\r\n")));
while(1)
{
ret=WaitForSingleObject(gWaitEvent,INFINITE);
if((ret==WAIT_OBJECT_0) && (g_KillIST==FALSE))
{
for(intnum=0;intnum<4;intnum++)
{
if(Key_IsPushed(intnum))
{
Sleep(20);//delay filter noise
if(Key_IsPushed(intnum))
{
SetEvent(gReadKeyEvent[0]);
RETAILMSG(1,(TEXT("***THE KEY[%d] PUSHED.***\r\n"),intnum));
InterruptDone(KeySysIntr[intnum]);
InterruptInitialize(KeySysIntr[intnum],gWaitEvent,NULL,0);
RETAILMSG(1,(TEXT("***THE KEY[%d] done.***\r\n"),intnum));
return intnum;
if(intnum==4)
{
intnum=0;
RETAILMSG(1,(TEXT("intnum=0!!\r\n")));
}
break;
}
}
}
}
else
{
CloseHandle(gWaitEvent);
RETAILMSG(1,(TEXT("***EINTKey_INTRThread EXIT!!\r\n")));
return 0;
}
InterruptDone(KeySysIntr[0]);
InterruptDone(KeySysIntr[1]);
InterruptDone(KeySysIntr[2]);
InterruptDone(KeySysIntr[3]);
RETAILMSG(1,(TEXT("***EINTKey interrupt done!!\r\n")));
}
return 1;
}
//判断是否按键
PRIVATE BOOL Key_IsPushed(INT32 num)
{
DWORD pushed;
switch(num)
{
case 0:{
pushed=(IOPreg->GPFDAT &(1<<0)?FALSE:TRUE);
break;
}
case 1:{
pushed=(IOPreg->GPFDAT &(1<<2)?FALSE:TRUE);
break;
}
case 2:{
pushed=(IOPreg->GPFDAT &(1<<3)?FALSE:TRUE);
break;
}
case 3:{
pushed=(IOPreg->GPFDAT &(1<<4)?FALSE:TRUE);
break;
}
default:break;
}
return pushed;
}
//流驱动打开
DWORD MYK_Open(DWORD dwContext,DWORD AcessCode,DWORD ShareMode)
{
if(gOpenCount>0)
return 0;
gOpenCount++;
return gOpenCount;
}
//流驱动读
DWORD MYK_Read(DWORD Handle,LPVOID pBuffer,DWORD dwNumBytes)
{
DWORD ret;
uchar* pReadBuffer;
RETAILMSG(1,(TEXT("***MYK_read!!\r\n")));
if((pBuffer==NULL)||(dwNumBytes<=0))
return 0;
RETAILMSG(1,(TEXT("***MYK_read1!!\r\n")));
pReadBuffer=MapPtrToProcess(pBuffer,GetCallerProcess());
*pReadBuffer=0;
RETAILMSG(1,(TEXT("***MYK_read[%d]!!\r\n"),intnum));
ret=WaitForMultipleObjects(5,gReadKeyEvent,FALSE,INFINITE);
if(ret==WAIT_OBJECT_0)
{
ResetEvent(gReadKeyEvent[intnum]);
*pReadBuffer=1;
return 1;
RETAILMSG(1,(TEXT("ResetEvent(gReadKeyEvent[intnum])")));
}
else if(ret==(WAIT_OBJECT_0+1))
{
ResetEvent(gReadKeyEvent[1]);
*pReadBuffer=0;
RETAILMSG(1,(TEXT("ResetEvent(gReadKeyEvent[4])")));
return 1;
}
return 0;
}
//关闭流驱动
BOOL MYK_Close(DWORD dwOpen)
{
if(gOpenCount>0)
SetEvent(gReadKeyEvent[4]);
gOpenCount=0;
return TRUE;
}
17 个解决方案
#1
//卸载流驱动
BOOL MYK_Deinit(DWORD hDeviceContext)
{
SetEvent(gWaitEvent);
g_KillIST=TRUE;
Sleep(200);
InterruptDone(KeySysIntr[0]);
InterruptDisable(KeySysIntr[0]);
InterruptDone(KeySysIntr[1]);
InterruptDisable(KeySysIntr[1]);
InterruptDone(KeySysIntr[2]);
InterruptDisable(KeySysIntr[2]);
InterruptDone(KeySysIntr[3]);
InterruptDisable(KeySysIntr[3]);
IRQ=0;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=2;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=3;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=32;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
EINT_ConfigPinDefault();
if(IOPreg)
VirtualFree((PVOID)IOPreg,0,MEM_RELEASE);
gOpenCount=0;
CloseHandle(gReadKeyEvent[0]);
CloseHandle(gReadKeyEvent[1]);
CloseHandle(gReadKeyEvent[2]);
CloseHandle(gReadKeyEvent[3]);
CloseHandle(gReadKeyEvent[4]);
return TRUE;
}
PRIVATE VOID EINT_ConfigPinDefault(void)
{
IOPreg->GPFCON &=~(0X3<<8);
IOPreg->GPFCON &=~(0X3<<6);
IOPreg->GPFCON &=~(0X3<<4);
IOPreg->GPFCON &=~(0X3<<0);
}
DWORD MYK_Write(DWORD hOpenContext,LPVOID pBuffer,DWORD count)
{
return 0;
}
DWORD MYK_IOControl(DWORD hOpenContext,WORD a,PBYTE c,DWORD b,PBYTE d,DWORD h,PWORD m)
{
return 0;
}
DWORD MYK_Seek(DWORD hOpenContext,long Amount,DWORD Type)
{
RETAILMSG(1,(TEXT("****seek!\r\n")));
return 0;
}
BOOL MYK_Deinit(DWORD hDeviceContext)
{
SetEvent(gWaitEvent);
g_KillIST=TRUE;
Sleep(200);
InterruptDone(KeySysIntr[0]);
InterruptDisable(KeySysIntr[0]);
InterruptDone(KeySysIntr[1]);
InterruptDisable(KeySysIntr[1]);
InterruptDone(KeySysIntr[2]);
InterruptDisable(KeySysIntr[2]);
InterruptDone(KeySysIntr[3]);
InterruptDisable(KeySysIntr[3]);
IRQ=0;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=2;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=3;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=32;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
EINT_ConfigPinDefault();
if(IOPreg)
VirtualFree((PVOID)IOPreg,0,MEM_RELEASE);
gOpenCount=0;
CloseHandle(gReadKeyEvent[0]);
CloseHandle(gReadKeyEvent[1]);
CloseHandle(gReadKeyEvent[2]);
CloseHandle(gReadKeyEvent[3]);
CloseHandle(gReadKeyEvent[4]);
return TRUE;
}
PRIVATE VOID EINT_ConfigPinDefault(void)
{
IOPreg->GPFCON &=~(0X3<<8);
IOPreg->GPFCON &=~(0X3<<6);
IOPreg->GPFCON &=~(0X3<<4);
IOPreg->GPFCON &=~(0X3<<0);
}
DWORD MYK_Write(DWORD hOpenContext,LPVOID pBuffer,DWORD count)
{
return 0;
}
DWORD MYK_IOControl(DWORD hOpenContext,WORD a,PBYTE c,DWORD b,PBYTE d,DWORD h,PWORD m)
{
return 0;
}
DWORD MYK_Seek(DWORD hOpenContext,long Amount,DWORD Type)
{
RETAILMSG(1,(TEXT("****seek!\r\n")));
return 0;
}
#2
你没有在中断线程后面调用InterruptDone?
#3
调用了,我晕。看上去没有啥问题啊。
呵呵。你不会用驱动调试助手搞的吧?
那玩意最好别乱用哦。
#4
程序我没看,但是看你意思是想做连按功能了。就是按住一个键再按别的键,这个要看你硬件是怎么设计的吧?
#5
我没有用驱动调试助手。我就是想不明白为什么第一次按键有打印信息,以后就没有了。
而且打印信息显示按键以后也InterruptDone成功了
#6
不是,我的意思是按了这个键以后,松开。再按其他按键或这个键。一次只按一个键
#7
回头我发个程序给你吧
启明星
启明星
#8
谢谢你
#9
大侠帮帮忙啊,我都被这玩意折腾死了
#10
怎么没有进展了,
#11
楼主可以试着把EINTKey_IntrThread()的下面语句注释掉:
InterruptInitialize(KeySysIntr[intnum],gWaitEvent,NULL,0);
试一下。
InterruptInitialize(KeySysIntr[intnum],gWaitEvent,NULL,0);
试一下。
#12
以前没有的,因为不成功(问题如上)我就加上了,问题依然
#13
同意。。。没有中断进来。。。打印时王道,看看你的状态寄存器,是否来了,如果状态寄存器都没有变化,那么拿万用表来测你的GPIO是否有变化。一点点查,加打印
#14
[code=C/C++]DWORD EINTKey_IntrThread(PVOID pArg)
{
DWORD ret;
INT32 numb;
gWaitEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
if(gWaitEvent==NULL)
{
RETAILMSG(1,(TEXT("FRAILED CREATEEVENT!\r\n")));
return FALSE;
}
for(numb=0;numb<4;numb++)
{
if(!InterruptInitialize(KeySysIntr[numb],gWaitEvent,NULL,0))
{
RETAILMSG(1,(TEXT("ERROR:FAILED TO INITIALIZE USEKEY %d INTERRUPT EVENT\n\r"),numb));
CloseHandle(gWaitEvent);
return FALSE;
}
}
RETAILMSG(1,(TEXT("IST SUCCESS!\r\n")));
while(1)
{
ret=WaitForSingleObject(gWaitEvent,INFINITE);
if((ret==WAIT_OBJECT_0) && (g_KillIST==FALSE))
{
for(intnum=0;intnum<4;intnum++)
{
if(Key_IsPushed(intnum))
{
Sleep(20);//delay filter noise
if(Key_IsPushed(intnum))
{
SetEvent(gReadKeyEvent[0]);
RETAILMSG(1,(TEXT("***THE KEY[%d] PUSHED.***\r\n"),intnum));
InterruptDone(KeySysIntr[intnum]);
InterruptInitialize(KeySysIntr[intnum],gWaitEvent,NULL,0);
RETAILMSG(1,(TEXT("***THE KEY[%d] done.***\r\n"),intnum));
return intnum;
if(intnum==4)
{
intnum=0;
RETAILMSG(1,(TEXT("intnum=0!!\r\n")));
}
break;
}
}
}
}
else
{
CloseHandle(gWaitEvent);
RETAILMSG(1,(TEXT("***EINTKey_INTRThread EXIT!!\r\n")));
return 0;
}
InterruptDone(KeySysIntr[0]);
InterruptDone(KeySysIntr[1]);
InterruptDone(KeySysIntr[2]);
InterruptDone(KeySysIntr[3]);
RETAILMSG(1,(TEXT("***EINTKey interrupt done!!\r\n")));
}
return 1;
}
唉,看你的线程函数里用了什么? return intnum;!!!
有按键按下的话,EINTKey_IntrThread直接返回退出了!
{
DWORD ret;
INT32 numb;
gWaitEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
if(gWaitEvent==NULL)
{
RETAILMSG(1,(TEXT("FRAILED CREATEEVENT!\r\n")));
return FALSE;
}
for(numb=0;numb<4;numb++)
{
if(!InterruptInitialize(KeySysIntr[numb],gWaitEvent,NULL,0))
{
RETAILMSG(1,(TEXT("ERROR:FAILED TO INITIALIZE USEKEY %d INTERRUPT EVENT\n\r"),numb));
CloseHandle(gWaitEvent);
return FALSE;
}
}
RETAILMSG(1,(TEXT("IST SUCCESS!\r\n")));
while(1)
{
ret=WaitForSingleObject(gWaitEvent,INFINITE);
if((ret==WAIT_OBJECT_0) && (g_KillIST==FALSE))
{
for(intnum=0;intnum<4;intnum++)
{
if(Key_IsPushed(intnum))
{
Sleep(20);//delay filter noise
if(Key_IsPushed(intnum))
{
SetEvent(gReadKeyEvent[0]);
RETAILMSG(1,(TEXT("***THE KEY[%d] PUSHED.***\r\n"),intnum));
InterruptDone(KeySysIntr[intnum]);
InterruptInitialize(KeySysIntr[intnum],gWaitEvent,NULL,0);
RETAILMSG(1,(TEXT("***THE KEY[%d] done.***\r\n"),intnum));
return intnum;
if(intnum==4)
{
intnum=0;
RETAILMSG(1,(TEXT("intnum=0!!\r\n")));
}
break;
}
}
}
}
else
{
CloseHandle(gWaitEvent);
RETAILMSG(1,(TEXT("***EINTKey_INTRThread EXIT!!\r\n")));
return 0;
}
InterruptDone(KeySysIntr[0]);
InterruptDone(KeySysIntr[1]);
InterruptDone(KeySysIntr[2]);
InterruptDone(KeySysIntr[3]);
RETAILMSG(1,(TEXT("***EINTKey interrupt done!!\r\n")));
}
return 1;
}
唉,看你的线程函数里用了什么? return intnum;!!!
有按键按下的话,EINTKey_IntrThread直接返回退出了!
#15
没有啊,我加打印信息看了,他都能打印出来
#16
终于解决了,主要有两个错误
1.中断读事件太多,其实gReadKeyEvent[5];只需要两个就够了,一个读事件,一个读结束事件。
2,这是最知名的错误:
IRQ=0;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=2;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=3;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=32;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
这个地方应该是逻辑中断号KeySysIntr[],而不是物理中断号IRQ。
驱动在加载时调用IOCAL_HAL_REQUEST_SYSINTR将外部中断与一个逻辑中断关联,在卸载时虽然调用IOCTL_HAL_RELEASE_SYSINT将其关联取消,但是此处他只是别逻辑中断号。去哦是物理中断号,他不识别,相当于没有调用。
3.这个不知道是不是致命错误(呵呵,改了后没有单独测试!总之成功了):
SetEvent(gWaitEvent);
g_KillIST=TRUE;
Sleep(200);
SetEvent(gReadKeyEvent[1])//通知读函数事件结束。
结贴了!(欢迎各位大侠继续评点!)
1.中断读事件太多,其实gReadKeyEvent[5];只需要两个就够了,一个读事件,一个读结束事件。
2,这是最知名的错误:
IRQ=0;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=2;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=3;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=32;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
这个地方应该是逻辑中断号KeySysIntr[],而不是物理中断号IRQ。
驱动在加载时调用IOCAL_HAL_REQUEST_SYSINTR将外部中断与一个逻辑中断关联,在卸载时虽然调用IOCTL_HAL_RELEASE_SYSINT将其关联取消,但是此处他只是别逻辑中断号。去哦是物理中断号,他不识别,相当于没有调用。
3.这个不知道是不是致命错误(呵呵,改了后没有单独测试!总之成功了):
SetEvent(gWaitEvent);
g_KillIST=TRUE;
Sleep(200);
SetEvent(gReadKeyEvent[1])//通知读函数事件结束。
结贴了!(欢迎各位大侠继续评点!)
#17
#1
//卸载流驱动
BOOL MYK_Deinit(DWORD hDeviceContext)
{
SetEvent(gWaitEvent);
g_KillIST=TRUE;
Sleep(200);
InterruptDone(KeySysIntr[0]);
InterruptDisable(KeySysIntr[0]);
InterruptDone(KeySysIntr[1]);
InterruptDisable(KeySysIntr[1]);
InterruptDone(KeySysIntr[2]);
InterruptDisable(KeySysIntr[2]);
InterruptDone(KeySysIntr[3]);
InterruptDisable(KeySysIntr[3]);
IRQ=0;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=2;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=3;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=32;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
EINT_ConfigPinDefault();
if(IOPreg)
VirtualFree((PVOID)IOPreg,0,MEM_RELEASE);
gOpenCount=0;
CloseHandle(gReadKeyEvent[0]);
CloseHandle(gReadKeyEvent[1]);
CloseHandle(gReadKeyEvent[2]);
CloseHandle(gReadKeyEvent[3]);
CloseHandle(gReadKeyEvent[4]);
return TRUE;
}
PRIVATE VOID EINT_ConfigPinDefault(void)
{
IOPreg->GPFCON &=~(0X3<<8);
IOPreg->GPFCON &=~(0X3<<6);
IOPreg->GPFCON &=~(0X3<<4);
IOPreg->GPFCON &=~(0X3<<0);
}
DWORD MYK_Write(DWORD hOpenContext,LPVOID pBuffer,DWORD count)
{
return 0;
}
DWORD MYK_IOControl(DWORD hOpenContext,WORD a,PBYTE c,DWORD b,PBYTE d,DWORD h,PWORD m)
{
return 0;
}
DWORD MYK_Seek(DWORD hOpenContext,long Amount,DWORD Type)
{
RETAILMSG(1,(TEXT("****seek!\r\n")));
return 0;
}
BOOL MYK_Deinit(DWORD hDeviceContext)
{
SetEvent(gWaitEvent);
g_KillIST=TRUE;
Sleep(200);
InterruptDone(KeySysIntr[0]);
InterruptDisable(KeySysIntr[0]);
InterruptDone(KeySysIntr[1]);
InterruptDisable(KeySysIntr[1]);
InterruptDone(KeySysIntr[2]);
InterruptDisable(KeySysIntr[2]);
InterruptDone(KeySysIntr[3]);
InterruptDisable(KeySysIntr[3]);
IRQ=0;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=2;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=3;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=32;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&IRQ,sizeof(UINT32),NULL,0,NULL);
EINT_ConfigPinDefault();
if(IOPreg)
VirtualFree((PVOID)IOPreg,0,MEM_RELEASE);
gOpenCount=0;
CloseHandle(gReadKeyEvent[0]);
CloseHandle(gReadKeyEvent[1]);
CloseHandle(gReadKeyEvent[2]);
CloseHandle(gReadKeyEvent[3]);
CloseHandle(gReadKeyEvent[4]);
return TRUE;
}
PRIVATE VOID EINT_ConfigPinDefault(void)
{
IOPreg->GPFCON &=~(0X3<<8);
IOPreg->GPFCON &=~(0X3<<6);
IOPreg->GPFCON &=~(0X3<<4);
IOPreg->GPFCON &=~(0X3<<0);
}
DWORD MYK_Write(DWORD hOpenContext,LPVOID pBuffer,DWORD count)
{
return 0;
}
DWORD MYK_IOControl(DWORD hOpenContext,WORD a,PBYTE c,DWORD b,PBYTE d,DWORD h,PWORD m)
{
return 0;
}
DWORD MYK_Seek(DWORD hOpenContext,long Amount,DWORD Type)
{
RETAILMSG(1,(TEXT("****seek!\r\n")));
return 0;
}
#2
你没有在中断线程后面调用InterruptDone?
#3
调用了,我晕。看上去没有啥问题啊。
呵呵。你不会用驱动调试助手搞的吧?
那玩意最好别乱用哦。
#4
程序我没看,但是看你意思是想做连按功能了。就是按住一个键再按别的键,这个要看你硬件是怎么设计的吧?
#5
我没有用驱动调试助手。我就是想不明白为什么第一次按键有打印信息,以后就没有了。
而且打印信息显示按键以后也InterruptDone成功了
#6
不是,我的意思是按了这个键以后,松开。再按其他按键或这个键。一次只按一个键
#7
回头我发个程序给你吧
启明星
启明星
#8
谢谢你
#9
大侠帮帮忙啊,我都被这玩意折腾死了
#10
怎么没有进展了,
#11
楼主可以试着把EINTKey_IntrThread()的下面语句注释掉:
InterruptInitialize(KeySysIntr[intnum],gWaitEvent,NULL,0);
试一下。
InterruptInitialize(KeySysIntr[intnum],gWaitEvent,NULL,0);
试一下。
#12
以前没有的,因为不成功(问题如上)我就加上了,问题依然
#13
同意。。。没有中断进来。。。打印时王道,看看你的状态寄存器,是否来了,如果状态寄存器都没有变化,那么拿万用表来测你的GPIO是否有变化。一点点查,加打印
#14
[code=C/C++]DWORD EINTKey_IntrThread(PVOID pArg)
{
DWORD ret;
INT32 numb;
gWaitEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
if(gWaitEvent==NULL)
{
RETAILMSG(1,(TEXT("FRAILED CREATEEVENT!\r\n")));
return FALSE;
}
for(numb=0;numb<4;numb++)
{
if(!InterruptInitialize(KeySysIntr[numb],gWaitEvent,NULL,0))
{
RETAILMSG(1,(TEXT("ERROR:FAILED TO INITIALIZE USEKEY %d INTERRUPT EVENT\n\r"),numb));
CloseHandle(gWaitEvent);
return FALSE;
}
}
RETAILMSG(1,(TEXT("IST SUCCESS!\r\n")));
while(1)
{
ret=WaitForSingleObject(gWaitEvent,INFINITE);
if((ret==WAIT_OBJECT_0) && (g_KillIST==FALSE))
{
for(intnum=0;intnum<4;intnum++)
{
if(Key_IsPushed(intnum))
{
Sleep(20);//delay filter noise
if(Key_IsPushed(intnum))
{
SetEvent(gReadKeyEvent[0]);
RETAILMSG(1,(TEXT("***THE KEY[%d] PUSHED.***\r\n"),intnum));
InterruptDone(KeySysIntr[intnum]);
InterruptInitialize(KeySysIntr[intnum],gWaitEvent,NULL,0);
RETAILMSG(1,(TEXT("***THE KEY[%d] done.***\r\n"),intnum));
return intnum;
if(intnum==4)
{
intnum=0;
RETAILMSG(1,(TEXT("intnum=0!!\r\n")));
}
break;
}
}
}
}
else
{
CloseHandle(gWaitEvent);
RETAILMSG(1,(TEXT("***EINTKey_INTRThread EXIT!!\r\n")));
return 0;
}
InterruptDone(KeySysIntr[0]);
InterruptDone(KeySysIntr[1]);
InterruptDone(KeySysIntr[2]);
InterruptDone(KeySysIntr[3]);
RETAILMSG(1,(TEXT("***EINTKey interrupt done!!\r\n")));
}
return 1;
}
唉,看你的线程函数里用了什么? return intnum;!!!
有按键按下的话,EINTKey_IntrThread直接返回退出了!
{
DWORD ret;
INT32 numb;
gWaitEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
if(gWaitEvent==NULL)
{
RETAILMSG(1,(TEXT("FRAILED CREATEEVENT!\r\n")));
return FALSE;
}
for(numb=0;numb<4;numb++)
{
if(!InterruptInitialize(KeySysIntr[numb],gWaitEvent,NULL,0))
{
RETAILMSG(1,(TEXT("ERROR:FAILED TO INITIALIZE USEKEY %d INTERRUPT EVENT\n\r"),numb));
CloseHandle(gWaitEvent);
return FALSE;
}
}
RETAILMSG(1,(TEXT("IST SUCCESS!\r\n")));
while(1)
{
ret=WaitForSingleObject(gWaitEvent,INFINITE);
if((ret==WAIT_OBJECT_0) && (g_KillIST==FALSE))
{
for(intnum=0;intnum<4;intnum++)
{
if(Key_IsPushed(intnum))
{
Sleep(20);//delay filter noise
if(Key_IsPushed(intnum))
{
SetEvent(gReadKeyEvent[0]);
RETAILMSG(1,(TEXT("***THE KEY[%d] PUSHED.***\r\n"),intnum));
InterruptDone(KeySysIntr[intnum]);
InterruptInitialize(KeySysIntr[intnum],gWaitEvent,NULL,0);
RETAILMSG(1,(TEXT("***THE KEY[%d] done.***\r\n"),intnum));
return intnum;
if(intnum==4)
{
intnum=0;
RETAILMSG(1,(TEXT("intnum=0!!\r\n")));
}
break;
}
}
}
}
else
{
CloseHandle(gWaitEvent);
RETAILMSG(1,(TEXT("***EINTKey_INTRThread EXIT!!\r\n")));
return 0;
}
InterruptDone(KeySysIntr[0]);
InterruptDone(KeySysIntr[1]);
InterruptDone(KeySysIntr[2]);
InterruptDone(KeySysIntr[3]);
RETAILMSG(1,(TEXT("***EINTKey interrupt done!!\r\n")));
}
return 1;
}
唉,看你的线程函数里用了什么? return intnum;!!!
有按键按下的话,EINTKey_IntrThread直接返回退出了!
#15
没有啊,我加打印信息看了,他都能打印出来
#16
终于解决了,主要有两个错误
1.中断读事件太多,其实gReadKeyEvent[5];只需要两个就够了,一个读事件,一个读结束事件。
2,这是最知名的错误:
IRQ=0;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=2;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=3;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=32;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
这个地方应该是逻辑中断号KeySysIntr[],而不是物理中断号IRQ。
驱动在加载时调用IOCAL_HAL_REQUEST_SYSINTR将外部中断与一个逻辑中断关联,在卸载时虽然调用IOCTL_HAL_RELEASE_SYSINT将其关联取消,但是此处他只是别逻辑中断号。去哦是物理中断号,他不识别,相当于没有调用。
3.这个不知道是不是致命错误(呵呵,改了后没有单独测试!总之成功了):
SetEvent(gWaitEvent);
g_KillIST=TRUE;
Sleep(200);
SetEvent(gReadKeyEvent[1])//通知读函数事件结束。
结贴了!(欢迎各位大侠继续评点!)
1.中断读事件太多,其实gReadKeyEvent[5];只需要两个就够了,一个读事件,一个读结束事件。
2,这是最知名的错误:
IRQ=0;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=2;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=3;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
IRQ=32;
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR ,&IRQ,sizeof(UINT32),NULL,0,NULL);
这个地方应该是逻辑中断号KeySysIntr[],而不是物理中断号IRQ。
驱动在加载时调用IOCAL_HAL_REQUEST_SYSINTR将外部中断与一个逻辑中断关联,在卸载时虽然调用IOCTL_HAL_RELEASE_SYSINT将其关联取消,但是此处他只是别逻辑中断号。去哦是物理中断号,他不识别,相当于没有调用。
3.这个不知道是不是致命错误(呵呵,改了后没有单独测试!总之成功了):
SetEvent(gWaitEvent);
g_KillIST=TRUE;
Sleep(200);
SetEvent(gReadKeyEvent[1])//通知读函数事件结束。
结贴了!(欢迎各位大侠继续评点!)