3079|4

68

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

两个外部中断 对应一个IST的问题。 [复制链接]

在搞一个磁卡的驱动,磁卡的大致情况我介绍下:
主要有两个磁道,每个磁道由一根数据线和一根时钟线组成,原理很简单:就是当时钟线电平变低时,去读数据线的值就可以了。

一、编程思路是:
    1、设置EINT8、EINT9分别对应两个磁道的时钟信号,下降沿触发中断。
    2、两个中断绑定在一个Event上,然后在一个IST中WaitForSingleObject等待这个事件;
    3、当事件来后,通过判断EINT8、EINT9分别对应的IO口的状态,判断是那个产生的中断,然后相应读数。

二、现在遇到的问题是:当中断产生几次后,就不再响应。而且相应的次数不一样——很奇怪,因为我每次都InterruptDone了啊。

三:相应代码如下:
    1、中断和事件的绑定:
[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]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")));”不再打印输出了。

最新回复

感谢楼上两位前辈的指点,都是很好的找问题的办法!~ 但还没等我试,发现了更为奇怪的问题:                 pGPIOregs->GPNCON    &= ~((0x3  详情 回复 发表于 2010-4-24 18:38
点赞 关注

回复
举报

66

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
代码怎么贴成这样子,再试试:
[code][///Track3 CLK eint8
        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;
    }  
   
        //Track2 CLK eint9
        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 ;
    }

        /*if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, dwHwIntr, sizeof(dwHwIntr), &dwSysIntr_DoubleTrack, sizeof(DWORD), NULL))
    {
        RETAILMSG(MAG_DUG,(TEXT("[MAG] Failed to request the EINT8、ENT9 sysintr for Doubletrack.\n")));
        dwSysIntr_DoubleTrack = SYSINTR_UNDEFINED;
        bResult = 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;
    }]

IST如下:
[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);
                        }
                }
        }]
 
 

回复

87

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
是否会因为其它地方的代码导致的?
如果不好查可以另外建立一个线程,每过一段时间就输出一下相关寄存器的值,看下是否某些关于中断的寄存器被改了
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

4
 
建议你先绑定一个中断分别测试,如果都没有问题,再绑定两个。如果绑定一个都有问题的话,建议先解决掉这个问题再说。

另外,贴代码时,需要将代码放在[code]的中间,如下,
[code]
 
 
 

回复

116

帖子

0

TA的资源

一粒金砂(中级)

5
 
感谢楼上两位前辈的指点,都是很好的找问题的办法!~

但还没等我试,发现了更为奇怪的问题:
  1.        
  2.         pGPIOregs->GPNCON    &= ~((0x3<<20) | (0x3<<28));
  3.         pGPIOregs->GPNCON    |=  ((0x2<<20) | (0x2<<28));
复制代码

上面的两句有什么问题吗?
1、第二天早上系统启动开始初始化IO,跑到上面程序第一句时,系统死机(我是一句句打印找到这的)。
2、没办法,将第一句屏蔽掉OK了,光有第二句设置中断也能用——但这个问题着实让我摸不着脑袋!~

后来我将IST处理的程序移到了ISR中直接实现——主要是因为考虑到ISR到IST需要过程时间,1ms以上吧,这时候再去读数据线上的电平就晚了。所以上面的代码基本全部删掉了,因为计时两个ISR对应一个IST,但也有其它IST会切换它。所以……    两位别骂我啊!~

3、但是后来更奇怪的问题又出现了,我和提供磁卡模块的厂家越好,让帮我调试。我带着板子到了人家那里,再其系统又死了,死的地方还是刚才那,这时候 只剩下面这一句了:
  1. pGPIOregs->GPNCON    |=  ((0x2<<20) | (0x2<<28));
复制代码

把它删掉就能正常启动,但这时候中断不起作用了,当然。
4、现在都怀疑S3C6410的这两个中断脚有bug了。GPN8、GPN9.
5、关于磁卡驱动的问题,我又开了一篇帖子《S3C6410——同一时刻来两个外部中断会怎么样?》先节这个贴了。


 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表