深入理解裸机中断二

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mxgsgtc/article/details/72722034
  • 前言
    上篇介绍了中断的详细流程,接下来结合手册上的寄存器信息来分析2440中的中断结构
    arm9中断分成两个大类, 内部中断与外部中断
  • 中断结构
    这里写图片描述
    上图即arm9中断结构的分配(EINTPEND等是需要配置的寄存器), 由图可知:
  • 外部中断(中断由外部电路触发)
    外部中断共有24个, 即EINT0->EINT23, 其中EINT0->EINT7对应GPF0-GPF7, EINT8-EINT23对应GPG0-GPG15, 有同学可能会奇怪,图中外部中断EINT0-EINT3是一组,而且不需要经过EINTPEND, EINTMASK寄存器的配置, 原因很简单, EINTPEND寄存器位置不够了,所以分出去EINT0->EINT3分开
  • 外部中断源(EINT4-EINT23)举例
    比如我们要用这个EINT4这个中断,我们应该怎么把它使能呢?根据上图中的流程
    ■设置中断使能
    1.配置GPF4为EINT4(即中断模式)
    这里写图片描述
    2.配置EINT4的触发方式,这里用到的寄存器没有在图中所表示, EXTINT0-EXTINT2:三个寄存器设定EINT0-EINT23的触发方式。
    这里写图片描述
    3.EINTMASK寄存器配置(即是否屏蔽EINT4中断需要在这里设置)
    这里写图片描述
    这里讲EINT4中断使能
    4.INTMSK寄存器配置(是否屏蔽中断类型需要在这里配置, 最终觉得CPU是否处理中断源)
    这里写图片描述
    由上图我们可以看到, INTMSK第4位决定EINT4_7是否被屏蔽
    比如,我们要让INT4使能,INT5屏蔽, 我们需要设置:
    (1).INTMSK第4位为0, 使能EINT4->EINT7
    (2).EINTMASK第5位1, 屏蔽EINT5
    5.配置中断触发模式(是IRQ还是RIQ), INTMODE寄存器配置,默认值为IRQ
    中断使能的设置基本完成
    ■中断发生判断-中断的发生
    外部设备接入GPF4引发中断(低电平),首先介绍一下相关寄存器(上图中剩余寄存器)
    寄存器说明:
    SRCPND :当一个中断发生后,那么相应的位会被置1,表示一个或一类中断发生了。
    INTPND :中断发生后,SRCPND中会有位置1,可能好几个(因为同时可 能发生几个中断),这些中断会由优先级仲裁器(由PRIORITY设置优先级)选出一个最紧迫的,之后把INTPND中相应位置1,所以同一时间只有一位是1。也就是说前面的寄存器置1 是表示发生了,只有INTPND置1,CPU才会处理。
    INTOFFSET :用来表示INTPND中哪一位置1了,好让你查询,普通中断跳转时查询用。清除INTPND、SRCPND时自动清除。
    所以假设EINT4与EINT8都使能,但EINT4的优先级高,那么发生中断后, SRCPND中的两位至1, INTPND中的EINT4对应位至1, INTOFFSET寄存器会自动赋值为EINT4所表示的整数
    结束发生时的情况(EINT4与EINT8同时发生中断):
    中断发生:
    首先SRCPND 对应位置1(2位),之后查看EINTMASK是否被屏蔽, 接下来若没有被屏蔽, SRCPND对应位置1, INTMSK没有被屏蔽的话, 根据优先级(假设EINT4的优先级高), INTPND的EINT4-EINT7所在位被置1, INTOFFSET 寄存器中的值为20,当处理中断函数清除中断标志后(清除EINT4中的中断标志,但是EINT8没有被清除),所以INTPND中EINT8对应位被至1, INTOFFSET 寄存器中的值为21
    ■中断发生判断-中断判断
    EINT4与EINT8同时发生中断
    1.SRCPND
    这里写图片描述
    上图可知寄存器中的4,5位 置1
    2.INTPND
    这里写图片描述
    由于EINT4的优先级高,所以INTPND寄存器第4位 置1
    3.INTOFFSET
    这里写图片描述
    由于INTPND的第4位置1,所以INTOFFSET寄存器变为20这个整数(我们写中断程序可以利用此数进行跳转, 跳转4*20处即处理 INT4-INT7的函数中)
    4.EINTPEND
    上述中断的判断中,我们只知道是EINT4->EINT7来了中断,确认是EINT4的话就要用到EINTPEND这个寄存器了
    这里写图片描述
    5.处理中断结束后,需要清除中断, 所以需要往
    EINTPEND, SRCPND, INTPND对应位置写1, 而且顺序必须是EINTPEND->SRCPND->INTPND, 因为假设你先清除SRCPND对应位,但此时EINTPEND位没有清除,SRCPND对应位又变为1了
  • 内部中断源(带子中断)
    什么是子中断,其实了类似于UART一样,UART发生中断由3种情况(收,发,ERR),这三种情况都属于uart的子中断, 下述例子中以uart0为例子
    ■设置中断使能
    这里不考虑如何配置uart0(比如配置GPH2引脚为uart,这种配置在uart文章中会有讲解),只考虑与uart中断相关的配置
    1.配置INTSUBMSK寄存器,使中断使能
    这里写图片描述
    我们发现对于INTSUBMSK寄存器,初始化默认值为0xFFFF,也就是说刚开始中断都是被禁止的,所以这里针对于uart0,我想打开rx,tx,那么就的往寄存器0,1位置0
    2.INTMSK寄存器配置(同上面EINT4的例子)
    这里写图片描述
    比如,我们要让uart0的rx, tx使能,err屏蔽, 我们需要设置:
    (1).INTMSK第28位为0, 使能uart0
    (2).INTSUBMSK第2位1, 屏蔽uart0的子中断err0
    3.配置中断触发模式(是IRQ还是RIQ), INTMODE寄存器配置,默认值为IRQ
    中断使能的设置基本完成
    ■中断发生判断-中断的发生
    寄存器说明:
    SUBSRCPND:当一个中断发生后,那么相应的位会被置1,表示具体哪个中断发生了。
    中断发生:
    uart0接受数据 uart0_rx发生中断,此时SUBSRCPND中的uart_rx位置1, 其次,如果没有uart_rx中断没有在INTSUBMSK寄存器被屏蔽的话, SRCPND对应uart0位被置1,INTMSK没有被屏蔽的话, 对应的INTPND置1, 从而INTOFFSET变为值28
    ■中断发生判断-中断判断
    uart0_rx发生了,如果INTMSK没有屏蔽的话,在INTPND寄存器中uart0肯定被置1
    这里写图片描述
    通过INTOFFSET的值28, 我们可以对其偏移并调用uart0的中断函数,在中断函数中我们想知道uart0的哪个子中断发生中断的话,就得查询SUBSRCPND寄存器
    这里写图片描述
  • 内部中断源,不带子中断
    这种情况,比如定时器,具体细节请读者自行分析,这里只作为简单的声明
    要设置定时器0的中断
    ■设置中断使能->设置寄存器INTMSK
    这里写图片描述
    至于中断的判断不做陈述(上述2个例子如果明白的话分析定时器中断很容易)
  • 总结:
    1.中断的开启。
    a.如果是不带子中断的内部中断,只需设置INTMSK,让它不屏蔽中断就可以了。
    b 如果是带子中断的内部中断,需设置INTSUBMSK和INTMSK,让它门不屏蔽中断就可以了。
    c 如果是外部中断,对于EINT8-23需要设置EINTMASK和INTMSK。对于EINT0-EINT3只需设置INTMSK。
    2.中断的清除。
    a.如果是不带子中断的内部中断,只需清除SRCPND,INTPND, 注意清除需位置1。
    b 如果是带子中断的内部中断,需清除SRCPND,SUBSRCPND和INTPND,注意先清除SUBSRCPND,再清除SRCPND。因为,如果你先清除SRCPND的话,然后在清除SUBSRCPND的过程中,SRCPND会以为又有中断发生,又会置1。也就是说一次中断会响应两次。所以必须先掐断源头。
    c 如果是外部中断,对于EINT8-23需要清除EINTPEND,SRCPND和INTPND(同样注意顺序)。对于EINT0-EINT3只需清除SRCPND和INTPND。

猜你喜欢

转载自blog.csdn.net/mxgsgtc/article/details/72722034