7689|12

80

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

S3C6410——同一时刻来两个外部中断会怎么样? [复制链接]

发现一个很奇怪的问题:
S3C6410+WinCE6.0的系统,两个中断同一时刻来的时候,就出现丢数的现象。
详细情况是这样:做磁卡的驱动,有两个磁道:每个磁道有一个时钟线、一个数据线。
                磁卡驱动原理很简单,当时钟线下降沿触发中断时,就去读数据线上的电平就行。
                现在是:当只有一个磁道(禁止另一个时钟中断信号)时:读数正确;
                        当两个磁道同时打开时,两个磁道读数都错,出现丢数现象,偶尔有读对的时候,用示波器量,发
                        现有两个中断信号有统一时刻来的——很明显,这时候丢数了,只进入了一个ISR,另一个根本
                        没理。
请问,遇到这种情况S3C6410是怎么处理的?它干嘛要丢掉一个中断?另外,它俩在中断向量表VIC0里属于同一个中断源PHYIRQ_EINT1——我用的中断号是EINT10、EINT11.

最新回复

我的理解是,两个中断同时来的时候,没有丢一个中断,而是先处理了一个中断,而再处理另外一个中断。 “我记得S3C2410的中断和ARM7核的单片机中断处理机制有个SRCPND的寄存器,两个中断同时都来了,SRCPND中两个中断位都会同时置位,按照优先级一个先处理,另一个等先处理的处理完了总会处理。对吧?总之不会丢” 你的这个理解是对的啊,正因为如此才不会把另外一个中断给丢了, 如果你的读卡数据的时间比较长的话,且多于两倍的ISR处理的时间的话,应该是可以一前一后读到两个卡的数据,不会丢失的。  详情 回复 发表于 2010-5-16 02:30
点赞 关注

回复
举报

79

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
这个肯定是响应优先级高的了。
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
这个只能增加 isr ist的效率来做。
楼主可以参考我 做外部串口驱动的办法,博客有。
还有这两个中断线程要互斥。
 
 
 

回复

59

帖子

0

TA的资源

一粒金砂(初级)

4
 
回楼上:
    谢谢googoleman这么快就回复,谢谢!
    但我觉得问题没这么简单:
1、EINT10、EINT11都属于中断向量表VIC1的同一个物理中断PHYIRQ_EINT1,设置优先级只能针对    PHYIRQ_EINT1,所以它俩的优先级肯定一致;
2、因为从ISQ--->ISR--->IST的过程需要花费时间,另外两个IST切换的时间更长(1ms不止)如果我两个ISR分别对应一个IST的话那就更惨了,又因为怕进入IST再去读数据线上的电平就不是1ms以前的了,所以现在读电平的处理我放在了ISR中,只有ISR将所有的数据都处理完了(响应了N个中断),我才通知IST来处理,是通过共享内存来实现的。
3、所以问题应该还不是楼上说的。
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

5
 
我觉得读取电平确实应该放在ISR中,但是读取电平速度很快的,理论上不会影响ISR的效率。并且你不应该让ISR响应N个中断之后才通知ISR,而是响应一个ISR之后立刻通知IST处理。或者引入DMA来读取数据。
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

6
 
这个要学习一下 呵呵
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

7
 
这个和isr里面判断中断源有关.举个例子.
if(int10)
{}
else if(int11)
{}
这种代码,如果两个中断同时来了,INT11就丢了.

会不会有这种现象发生.要不同时来中断,应该都会有响应.
if(int10)
{}
if(int11)
{}
这样判断就不会丢.
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

8
 

  1. //*****************added by haiou for magcard driver in 2010-04-20*****************************
  2.     if(VirtualIRQ == IRQ_EINT10)                                      //Track3
  3.     {
  4.         //OALMSG(TRUE, (L"*********OEMInterruptHandler:IRQ_EINT8     haiou************\r\n"));       
  5.                 /*
  6.                 g_pMAGBuf->primal_num_track3 = 0;
  7.                 for(g_pMAGBuf->primal_num_track3; g_pMAGBuf->primal_num_track3primal_num_track3++)
  8.                 {
  9.                     g_pMAGBuf->card_data_track3[g_pMAGBuf->primal_num_track3] = g_pMAGBuf->primal_num_track3;
  10.                 }
  11.         g_pMAGBuf->primal_num_track3 = 0;               
  12.             g_pGPIOReg->EINT0MASK &= ~(0x1<<8);    // Enable EINT8
  13.                 g_pVIC0Reg->VICINTENABLE |= (0x1<
  14.                 */
  15.                 //OALMSG(TRUE, (L"*********OEMInterruptHandler:IRQ_EINT8     haiou************\r\n"));
  16.                 if(0x02 == (UCHAR)(g_pMAGBuf->trans_flag & BRUSH_END))       //只有IST允许,中断处理才能有效
  17.             {
  18.                 if((!(g_pGPIOReg->GPKDAT & CP_LOW)) && (g_pMAGBuf->primal_num_track3 < 1000))
  19.                 {
  20.                     g_pMAGBuf->card_data_track3[g_pMAGBuf->primal_num_track3++] = (char)(g_pGPIOReg->GPKDAT & TRACK3);  //读出GPK2 bit
  21.                 }
  22.                 g_pMAGBuf->trans_flag |= BRUSH_BEGIN;
  23.                     g_pGPIOReg->EINT0MASK &= ~(0x1<<10);    // Enable EINT8
  24.                                 g_pVIC0Reg->VICINTENABLE |= (0x1<
  25.         }
  26.             return SYSINTR_NOP;
  27.     }

  28.     if(VirtualIRQ == IRQ_EINT18)                                      //Track2
  29.     {
  30.                 //OALMSG(TRUE, (L"*********OEMInterruptHandler:IRQ_EINT9     haiou************\r\n"));
  31.                 if(0x02 == (UCHAR)(g_pMAGBuf->trans_flag & BRUSH_END))    //只有IST允许,中断处理才能有效
  32.             {
  33.                 if((!(g_pGPIOReg->GPKDAT & CP_LOW)) && (g_pMAGBuf->primal_num_track2 < 300))
  34.                 {
  35.                     g_pMAGBuf->card_data_track2[g_pMAGBuf->primal_num_track2++] = (char)(g_pGPIOReg->GPKDAT & TRACK2);  //读出GPK3 bit
  36.                 }
  37.             g_pMAGBuf->trans_flag |= BRUSH_BEGIN;
  38.                 g_pGPIOReg->EINT0MASK &= ~(0x1<<18);    // Enable EINT9
  39.                         g_pVIC1Reg->VICINTENABLE |= (0x1<<(PHYIRQ_EINT2-32));  //(IRQ_EINT4~IRQ_EINT11)
  40.         }
  41.             return SYSINTR_NOP;
  42.     }
  43. //*******************end of magcard driver***************************************************/
复制代码
引用 6 楼 paul85 的回复:
这个和isr里面判断中断源有关.举个例子.
if(int10)
{}
else if(int11)
{}
这种代码,如果两个中断同时来了,INT11就丢了.

会不会有这种现象发生.要不同时来中断,应该都会有响应.
if(int10)
{}
if(int11)
{}
这样判断就不会丢.
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

9
 
有道理,ISR响应N个中断后通知的方法不是 return sys_intr的方式,是设置了g_pMAGBuf->trans_flag |= BRUSH_BEGIN(所在的内存空间由ISR和IST共享);这个全局变量,IST端每隔100ms就去读这个变量,然后再等1.5ms处理_pMAGBuf->card_data_track3中的数。
引入DMA读取数据,还真不会,能否详细说明下方法?
引用 4 楼 domworldjohn 的回复:
我觉得读取电平确实应该放在ISR中,但是读取电平速度很快的,理论上不会影响ISR的效率。并且你不应该让ISR响应N个中断之后才通知ISR,而是响应一个ISR之后立刻通知IST处理。或者引入DMA来读取数据。
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

10
 
引用 8 楼 haiou_arm 的回复:
有道理,ISR响应N个中断后通知的方法不是 return sys_intr的方式,是设置了g_pMAGBuf->trans_flag |= BRUSH_BEGIN(所在的内存空间由ISR和IST共享);这个全局变量,IST端每隔100ms就去读这个变量,然后再等1.5ms处理_pMAGBuf->card_data_track3中的数。
引入DMA读取数据,还真不会,能否详细说明下方法?

引……

要使用DMA需要你的外部接口支持DMA,如果支持,那么你只需要将外部接口的中断方式设置为DMA处理即可。这样,到外部中断来的时候,DMA自动处理,不需要经过CPU
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

11
 
回楼上,明白了,谢谢!~这个作为优化方案,我后面做下。

我现在比较怀疑的是这个:
S3C6410有两个中断向量表VIC0、VIC1。共对应64个interrupt sources。
其中有五个分别是INT_EINT0、INT_EINT1、INT_EINT2、INT_EINT3、INT_EINT4。
以INT_EINT0、INT_EINT1举例如下:
INT_EINT0又分别对应IRQ_EINT0,IRQ_EINT1,IRQ_EINT2,IRQ_EINT3四个外部中断;
INT_EINT1对应IRQ_EINT4~IRQ_EINT11;

现在有两种情况:
     1、如果IRQ_EINT0和IRQ_EINT1同时都来了会丢一个吗?
     2、如果IRQ_EINT0和IRQ_EINT4同时都来了会丢一个吗?

我记得S3C2410的中断和ARM7核的单片机中断处理机制有个SRCPND的寄存器,两个中断同时都来了,SRCPND中两个中断位都会同时置位,按照优先级一个先处理,另一个等先处理的处理完了总会处理。对吧?总之不会丢

S3C6410也是这样吗?它也有EINT0PND寄存器,还一样吗?不知道我上面的理解对不对?

 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

12
 
引用 10 楼 haiou_arm 的回复:
回楼上,明白了,谢谢!~这个作为优化方案,我后面做下。

我现在比较怀疑的是这个:
S3C6410有两个中断向量表VIC0、VIC1。共对应64个interrupt sources。
其中有五个分别是INT_EINT0、INT_EINT1、INT_EINT2、INT_EINT3、INT_EINT4。
以INT_EINT0、INT_EINT1举例如下:
INT_EINT0又分别对应IRQ……


今天该结贴了,看来我这个理解是有问题的,我引用所存在的问题是对一级中断和二级中断的理解有误。
后来我做了这样一个实验:
1、一个开关同时对应两个中断,模拟两个终端同时产生;
2、得到的结果是:只能产生一个syetem_intr;
3、其实这个不难理解:仔细看OEMInterruptHandle这个函数就能明白;
4、因为磁卡肯定有两个终端同时来的情况,后来换成了别的思路解决了这个问题,才磁卡CS信号作为中断,然后扫描读取二、三磁道的值,读值过程中CPU是独占的,但因为这个时间不到1S,目前应用是能接受的。

    最终得出的结论是:WinCE当有两个外部中断同时产生时,只返回一个逻辑中断号,也就是我会丢掉一个!
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

13
 
引用 11 楼 haiou_arm 的回复:
引用 10 楼 haiou_arm 的回复:
回楼上,明白了,谢谢!~这个作为优化方案,我后面做下。

我现在比较怀疑的是这个:
S3C6410有两个中断向量表VIC0、VIC1。共对应64个interrupt sources。
其中有五个分别是INT_EINT0、INT_EINT1、INT_EINT2、INT_EINT3、INT_EINT4。
以INT_EINT0、INT_EINT1……


我的理解是,两个中断同时来的时候,没有丢一个中断,而是先处理了一个中断,而再处理另外一个中断。

“我记得S3C2410的中断和ARM7核的单片机中断处理机制有个SRCPND的寄存器,两个中断同时都来了,SRCPND中两个中断位都会同时置位,按照优先级一个先处理,另一个等先处理的处理完了总会处理。对吧?总之不会丢”

你的这个理解是对的啊,正因为如此才不会把另外一个中断给丢了,

如果你的读卡数据的时间比较长的话,且多于两倍的ISR处理的时间的话,应该是可以一前一后读到两个卡的数据,不会丢失的。
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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