s5pv210开发板学习笔记(7)——CPU中断

中断体系介绍
  • 什么是中断?

中断的发明是用来解决宏观上的并行需要的。宏观就是从整体上来看,并行就是多件事情都完成了。

并行:微观上的并行,就是指的真正的并行,就是精确每一刻,多个事情都是在同时进行的。宏观上面的并行并不等于微观的并行,有时候宏观上是并行的,微观上是串行的,称为并发。
  • 为什么需要中断?

因为单核CPU实际无法并行的,但是通过中断机制,可以实现假并行(宏观上的并行,微观上实际还是串行的)。

  • SoC对中断的实现机制:异常向量表

  1. 异常向量表是CPU中某些特定地址的特定定义。当中断发生的时候,中断要想办法通知CPU去处理中断,怎么做到?这就要靠异常向量表。

  1. 在CPU设计时,就事先定义了CPU中一些特定地址作为特定异常的入口地址(比如定义0x00000000地址为复位异常向量地址,则发生复位异常时CPU会自动跳转到0x00000000地址去执行指令。又比如外部中断对应的异常向量地址为0x30000008,则发生外部中断后,CPU会硬件自动跳转到0x30000008地址去执行指令。)如

  1. 以上讲的是CPU硬件设计时对异常向量表的支持,下来就需要软件支持了。硬件已经决定了发生什么异常CPU自动跳转PC到哪个地址去执行,软件需要做的就是把处理这个异常的代码的首地址填入这个异常向量地址。

  • S5PV210的异常向量表

  1. 异常向量表中各个向量的相对位置是固定的,但是他们的起始地址是不固定的,各种SoC可以不一样,而且复杂ARM中还可以让用户来软件设置这个异常向量表的基地址。

  1. 扩展到所有架构的CPU中:所有架构(比如51单片机、PIC单片机)的CPU实现中断都是通过异常向量表实现的,这个机制是不变的;但是不同CPU异常向量表的构造和位置是不同的。

  • 异常和中断的区别和联系

  1. 针对SoC来说,发生复位、软中断、中断、快速中断、取指令异常、数据异常等,我们都统一叫异常。所以说:中断其实是异常的一种。

  1. 异常的定义就是突发事件,打断了CPU的正常常规业务,CPU不得不跳转到异常向量表中去执行异常处理程序;中断是异常的一种,一般特指SoC内的内部外设产生的打断SoC常规业务,或者外部中断(SoC的GPIO引脚传回来的中断)。

异常向量表的编程处理
  • 像内存一样去访问异常向量表

  1. S5PV210的异常向量表可以改变(在CP15协处理器中),以适应操作系统的需求。但是目前系统刚启动时,此时DRAM尚未初始化,程序都在SRAM中运行。210在iRAM中设置了异常向量表,供暂时性使用。

  1. 查210的iROM application note文档中iRAM的地址分配,可知,iRAM中的异常向量表起始地址为0xD0037400。知道了异常向量表的起始地址后,各个异常对应的入口就很好知道了。

  • 函数名的实质就是函数的首地址

  1. 函数名在C语言中的理解方法和变量名其实没区别。编译器会把这个函数的函数体对应的代码段和这个函数的函数名(实质是符号)对应起来,等我们在使用这个函数名符号时,编译器会将函数的函数体实际上做替换。因为函数体都不止4字节,而函数名这个符号只能对应1个地址,所以实际对应的是函数体那一个代码段的首地址。

  1. 拿C语言中的语法来讲,函数名就是这个函数的函数指针。

总结:当我们将异常处理程序的首地址和异常向量表绑定起来后,异常处理初步阶段就完成了。到目前可以保证相应异常发生后,硬件自动跳转到对应异常向量表入口去执行时,可以执行到我们事先绑定的函数。

  • 为什么中断处理要先在汇编中进行

  1. 中断处理要注意保护现场(中断从SVC模式来,则保存SVC模式下的必要寄存器的值)和恢复现场(中断处理完成后,准备返回SVC模式前,要将保存的SVC模式下的必要寄存器的值恢复回去,不然到了SVC模式后寄存器的值乱了,SVC模式下原来正在进行的常规任务就被你搞坏了)

  1. 保存现场包括:第一:设置IRQ栈;第二,保存LR;第三,保存R0~R12

  1. 为什么要保存LR寄存器?要考虑中断返回的问题。中断ISR执行完后如何返回SVC模式下去接着执行原来的代码。中断返回其实取决于我们进入中断时如何保存现场。中断返回时关键的2个寄存器就是PC和CPSR。所以我们在进入IRQ模式时,应该将SVC模式下的下一句指令的地址(中断返回地址)和CPSR保存起来,将来恢复时才可以将中断返回地址给PC,将保存的CPSR给CPSR。

  1. 中断返回地址就保存在LR中,而CPSR(自动)保存在(IRQ模式下的)SPSR中。

  • 汇编保存现场和恢复现场

  1. 保护现场关键是保存:中断处理程序的返回地址,r0-r12(cpsr是自动保存的)

  1. 恢复现场主要是恢复:r0-r12,pc,cpsr

示例代码

IRQ_handle:
    ldr sp, =IRQ_STACK    // 保存栈地址到IRQ模式下的栈中
    sub lr, lr, #4       // 当中断发生时,系统会自动把pc值存入lr中,所以此时lr中已经存放的是当前的pc值,但是当前pc值为当前执行指令的地址+8(因为指令流水线),而真正应该保存的指令地址应该为下一条指令的地址,即当前执行指令的地址+8,因此应该将lr-4。
    stmfd sp!, {r0-r12, lr}    // 这一条指令中,将r0-r12,lr这14个寄存器依次压入栈中,!的意思就是sp会在压栈中变化,同时cpsr会自动保存,这一条指令实现了保存现场。
    bl irq_handler       // 跳转到真正的中断处理函数
    ldmfd sp!, {r0-r12, pc}^    // 依次将栈中的值弹出,放入pc、r0-r12中,同时^的意思是将spsr的值恢复到cpsr中,这一条指令实现了恢复现场。
  • S5PV210的向量中断控制器

  1. 异常处理的2个阶段:

  1. 异常向量表跳转。

  1. 进入真正的异常处理程序irq_handler之后的部分。

  1. 回顾:中断处理的第一阶段(异常向量表阶段)处理。

  1. 第一个阶段之所以能够进行,主要依赖于CPU设计时提供的异常向量表机制。第一个阶段的主要任务是从异常发生到响应异常并且保存/恢复现场、跳转到真正的异常处理程序处。

  1. 第二个阶段的目的是识别多个中断源中究竟哪一个发生了中断,然后调用相应的中断处理程序来处理这个中断。

  • S5PV210的第二阶段处理过程

  1. 第一个问题,怎么找到具体是哪个中断:S5PV210中因为支持的中断源很多,所以直接设计了4个中断寄存器,每个32位,每位对应一个中断源。(理论上210最多支持128个中断,实际支持不足128个,有些位是空的);210没有子中断寄存器,每个中断源都是并列的。当中断发生时,在irq_handler中依次去查询4个中断源寄存器,看哪一个的哪一位被置1,则这个位对应的寄存器就发生了中断,即找到了中断编号。

  1. 第二个问题,怎么找到对应的isr的问题:210中支持的中断源多了很多,如果还使用2440的那一套来寻找isr地址就太慢了,太影响实时性了。于是210开拓了一种全新的寻找isr的机制。210提供了很多寄存器来解决每个中断源对应isr的寻找问题,实现的效果是当发生相应中断时,硬件会自动的将相应isr推入一定的寄存器中,软件只要去这个寄存器中执行函数就行了。

S5PV210中断处理的主要寄存器
  • VICnINTENABLE和VICnINTENCLEAR

  1. VICnINTENABLE 对应interrupt enable,INTENCLEAR对应interrupt enable clear

  1. INTENABLE寄存器负责相应的中断的使能,INTENCLEAR寄存器负责相应的中断的禁止。

  1. 当我们想使能(意思就是启用这个中断,意思就是当硬件产生中断时CPU能接收的到)某个中断时,只要在这个中断编号对应的VICnINTENABLE的相应bit位写1即可(注意这个位写1其他位写0对其他位没有影响);如果我们想禁止某个中断源时,只要向VICnINTENCLEAR中相应的位写1即可。

注意:这里的设计一共有2种:有些CPU是中断使能和禁止是一个寄存器位,写1就使能写0就禁止(或者反过来写1就禁止写0就使能),这样的中断使能设计就要非常小心,要使用我们之前说过的读改写三部曲来操作;另一种就是使能和禁止分开为2个寄存器,要使能就写使能寄存器,要禁止就写禁止寄存器。这样的好处是我们使能/禁止操作时不需要读改写,直接写即可。

  • VICnINTSELECT

  1. 设置各个中断的模式为irq还是fiq。一般都设置成irq

  1. IRQ和FIQ究竟有何区别。210中支持2种中断,irq和fiq。irq是普通中断,fiq是快速中断。快速中断提供一种更快响应处理的中断通道,用于对实时性要求很高的中断源。fiq在CPU设计时预先提供了一些机制保证fiq可以被快速处理,从而保证实时性。fiq的限制就是只能有一个中断源被设置为fiq,其他都是irq。

  1. CPU如何保证fiq比irq快?

  1. 第一,fiq模式有专用的r8~r12,因此在fiq的isr中可以直接使用r8-r12而不用保存,这就能节省时间;

  1. 第二,异常向量表中fiq是最后一个异常向量入口。因此fiq的isr不需要跳转,可以直接写在原地,这样就比其他异常少跳转一次,省了些时间。

  • VICnIRQSTATUS和VICnFIQSTATUS

中断状态寄存器,是只读的。当发生了中断时,硬件会自动将该寄存器的对应位置为1,表示中断发生了。软件在处理中断第二阶段的第一阶段,就是靠查询这个寄存器来得到中断编号的。

  • VICnVECTPRIORITY0~VICnVECTPRIORITY31

中断优先级设置寄存器,设置多个中断同时发生时先处理谁后处理谁的问题。一般来说高优先级的中断可以打断低优先级的中断,从而嵌套处理中断。当然了有些硬件/软件可以设置不支持中断嵌套。

  • VICnVECTADDR0~VICnVECTADDR31、VICnADDR

  1. VICnVECTADDR0~31这32个寄存器分别用来存放真正的各个中断对应的isr的函数地址。相当于每一个中断源都有一个VECTADDR寄存器,程序员在设置中断的时候,把这个中断的isr地址直接放入这个中断对应的VECTADDR寄存器即可。

  1. VICnADDR这个寄存器是只需要读的,它里面的内容是由硬件自动设置的。当发生了相应中断时,硬件会自动识别中断编号,并且会自动找到这个中断的VECTADDR寄存器,然后将其读出复制到VICnADDR中,供我们使用。这样的设计避免了软件查找中断源和isr,节省了时间,提高了210的中断响应速度。

整个中断的流程梳理:

整个中断的工作分为2部分:

  • 第一部分是我们为中断响应而做的预备工作:

1. 初始化中断控制器

2. 绑定写好的isr到中断控制器

3. 相应中断的所有条件使能

  • 第二部分是当硬件产生中断后如何自动执行isr:

1. 第一步,经过异常向量表跳转入IRQ/FIQ的入口

2. 第二步,做中断现场保护(在start.S中),然后跳入isr_handler

3. 第三步,在isr_handler中先去搞清楚是哪个VIC中断了,然后直接去这个VIC的ADDR

寄存器中取isr来执行即可。

4. 第四步,isr执行完,中断现场恢复,直接返回继续做常规任务。

外部中断
  • 什么是外部中断?数据手册在哪里?

  1. SoC支持的中断类型中有一类叫外部中断。内部中断就是指的中断源来自于SoC内部(一般是内部外设),譬如串口、定时器等部件产生的中断;外部中断是SoC外部的设备,通过外部中断对应的GPIO引脚产生的中断。

  1. 按键在SoC中就使用外部中断来实现。具体实现方法是:将按键电路接在外部中断的GPIO上,然后将GPIO配置为外部中断模式。此时人通过按按键改变按键电路的电压高低,这个电压高低会触发GPIO对应的外部中断,通过引脚传进去给CPU处理。

  • 外部中断的触发模式主要有2种:电平触发和边沿触发:

  1. 电平触发就是说GPIO上的电平只要满足条件,就会不停触发中断。电平触发分为高电平触发和低电平触发。电平触发的特点是,只要电平满足条件就会不停触发中断。

  1. 边沿触发分为上升沿触发、下降沿触发和双边沿触发三种。边沿触发不关心电平常规状态,只关心电平变化的瞬间(边沿触发不关心电平本身是高还是低,只关心变化是从高到低还是从低到高的这个过程)。

分析按键的工作:如果我们关注的是按键按下和弹起这两个事件本身,那么应该用边沿触发来处理按键;如果我们关心的是按键按下/弹起的那一段时间,那么应该用电平触发。

  • 关键寄存器:CON、PEND、MASK

  1. 外部中断的主要配置寄存器有3个:EXT_CON、EXT_PEND、EXT_MASK

  1. EXT_CON配置外部中断的触发方式。触发方式就是说外部电平怎么变化就能触发中断,也就是说这个外部中断产生的条件是什么

  1. EXT_PEND寄存器是中断挂起寄存器。这个寄存器中每一位对应一个外部中断,平时没有中断时值为0。当发生了中断后,硬件会自动将这个寄存器中该中断对应的位置1,我们去处理完这个中断后应该手工将该位置0。这个PEND寄存器的位就相当于是一个标志,如果发生了中断但是我们暂时忙来不及去处理时,这个位一直是1(这就是挂起),直到我有空了去处理了这个中断才会手工清除(写代码清除)这个挂起位表示这个中断被我处理了。

  1. EXT_MASK寄存器就是各个外部中断的使能/禁止开关。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值