两个外部中断 对应一个IST的问题。
在搞一个磁卡的驱动,磁卡的大致情况我介绍下:
主要有两个磁道,每个磁道由一根数据线和一根时钟线组成,原理很简单:就是当时钟线电平变低时,去读数据线的值就可以了。
一、编程思路是:
1、设置EINT8、EINT9分别对应两个磁道的时钟信号,下降沿触发中断。
2、两个中断绑定在一个Event上,然后在一个IST中WaitForSingleObject等待这个事件;
3、当事件来后,通过判断EINT8、EINT9分别对应的IO口的状态,判断是那个产生的中断,然后相应读数。
二、现在遇到的问题是:当中断产生几次后,就不再响应。而且相应的次数不一样——很奇怪,因为我每次都InterruptDone了啊。
三:相应代码如下:
1、中断和事件的绑定:
[code=C/C++][/code]dwSysIntr_Track3 = SYSINTR_NOP;
dwHwIntr[0] = -1;
dwHwIntr[1] = OAL_INTR_FORCE_STATIC;
dwHwIntr[2] = IRQ_EINT8;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwHwIntr, sizeof(dwHwIntr), &dwSysIntr_Track3, sizeof(DWORD), NULL))
{
RETAILMSG(MAG_DUG,(TEXT("[MAG] Failed to request dwSysIntr_Track3!\r\n")));
dwSysIntr_Track3 = SYSINTR_UNDEFINED;
return FALSE;
}
dwSysIntr_Track2 = SYSINTR_NOP;
dwHwIntr[0] = -1;
dwHwIntr[1] = OAL_INTR_FORCE_STATIC;
dwHwIntr[2] = IRQ_EINT9;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwHwIntr, sizeof(dwHwIntr), &dwSysIntr_Track2, sizeof(DWORD), NULL))
{
RETAILMSG(MAG_DUG,(TEXT("[MAG] Failed to request dwSysIntr_Track2!\r\n")));
dwSysIntr_Track2 = SYSINTR_UNDEFINED;
return FALSE ;
}
hEvent_DoubleTrack = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!InterruptInitialize(dwSysIntr_Track3, hEvent_DoubleTrack, NULL, 0))
{
RETAILMSG(MAG_DUG,(TEXT("[MAG] dwSysIntr_Track3 Interrupt Initialization failed!!!\n")));
bResult = FALSE;
}
if (!InterruptInitialize(dwSysIntr_Track2, hEvent_DoubleTrack, NULL, 0))
{
RETAILMSG(MAG_DUG,(TEXT("[MAG] dwSysIntr_Track2 Interrupt Initialization failed!!!\n")));
bResult = FALSE;
}
hThread_DoubleTrack = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadFor_DoubleTrack, 0, 0, (LPDWORD)&dwThreadId_DoubleTrack);
if (hThread_DoubleTrack == NULL)
{
RETAILMSG(MAG_DUG,(TEXT("[MAG] Thread of DoubleTrack creation error!!!\n")));
bResult = FALSE;
}
2、IST函数:
[code=C/C++][/code]while(1)
{
ret = WaitForSingleObject(hEvent_DoubleTrack, INFINITE);
if((ret==WAIT_OBJECT_0) && (g_KillDoubleThreadTrack==FALSE))
{
//RETAILMSG(MAG_DUG,(TEXT("ret==WAIT_OBJECT_0!!!\r\n")));
if (!(pGPIOregs->GPNDAT & IOSTAT_EINT8)) //EINT8 is active----->Track3
{
RETAILMSG(MAG_DUG,(TEXT("EINT8 is active----->Track3\r\n")));
if((!(pGPIOregs->GPKDAT & CP_LOW)) && (g_pBrushCard->primal_num_track3 < 1000))
{
g_pBrushCard->card_data_track3[g_pBrushCard->primal_num_track3++] = (char)(pGPIOregs->GPKDAT & TRACK3); //读出GPK2 bit
}
InterruptDone(dwSysIntr_Track3);
}
if (!(pGPIOregs->GPNDAT & IOSTAT_EINT9)) //EINT9 is active----->Track2
{
RETAILMSG(MAG_DUG,(TEXT("EINT9 is active----->Track2\r\n")));
if((!(pGPIOregs->GPKDAT & CP_LOW)) && (g_pBrushCard->primal_num_track2 < 300))
{
g_pBrushCard->card_data_track2[g_pBrushCard->primal_num_track2++] = (char)(pGPIOregs->GPKDAT & TRACK2); //读出GPK3 bit
}
InterruptDone(dwSysIntr_Track2);
}
}
}
四、曾经尝试过一个中断分别对应一个IST,但是因为两个IST之间的切换时间较长,达不到要求,才改成现在这样子,当时中断时能够正常响应的。现在不知为什么,中断进去几次后就突然不再能产生中断了。也就是“RETAILMSG(MAG_DUG,(TEXT("EINT9 is active----->Track2\r\n")));”不再打印输出了。
[解决办法]
是否会因为其它地方的代码导致的?
如果不好查可以另外建立一个线程,每过一段时间就输出一下相关寄存器的值,看下是否某些关于中断的寄存器被改了
[解决办法]
建议你先绑定一个中断分别测试,如果都没有问题,再绑定两个。如果绑定一个都有问题的话,建议先解决掉这个问题再说。
另外,贴代码时,需要将代码放在