嵌入式知识-ARM裸机-学习笔记(7):SoC系统中断与按键触发外部中断

嵌入式知识-ARM裸机-学习笔记(7):SoC系统中断与按键触发外部中断

一、SoC中断体系

1. 中断的基本概念

什么是中断?
中断的发明是用来解决宏观上的并行需要的。 宏观就是从整体上来看,并行就是能够完成多件事情。微观就是从每件事情来看,也就是指的真正的并行,精确到每一秒甚至每一刻,多个事情都是在同时进行的。宏观上面的并行并不等于围观的并行,有时候宏观上是并行的,微观上是串行的。
举个例子:一个人在看电影,快递来了暂停电影跑去收快递,收完快递继续回来看电影,这个例子就是宏观上的并行和微观上的串行。例子中一个人等同于SoC中1个CPU(也就是单核CPU),从宏观角度来看,这个人即完成了看电影又完成了取快递,也就是实现了两个任务(并行)。但是从微观角度来,这个人看电影就不能收快递,收快递就不能看电影(也就是说不能真正的并行,而是串行)。单核心CPU在微观角度是串行的,但是因为CPU很快,所以在宏观看来可以并行。

中断过程分析
一个程序在执行常规时,可能会因为一个中断源的产生而去处理中断,处理完之后再回到原始的状态继续执行程序。
对应到上面的例子:上例中大部分时间在看电影,中间少量时间去收快递,那么类比于CPU来说,看电影就应该是CPU的常规任务,而收快递则应该是中断例程。也就是说CPU平时一直在进行看电影任务,等快递来了(中断发生了)快递员(中断源)会打电话叫人去收快递(中断源会触发中断通知CPU去处理中断),人收到电话(CPU收到中断信号)后会暂定电影(CPU保存常规任务的现场)跑去收快递(CPU去执行中断处理程序ISR处理中断),收完快递(执行完ISR)回来继续看电影(CPU恢复常规任务的现场,继续执行常规任务)。
注:ISR(Interrupt Service Routines)中断服务程序,也就是发生中断后该执行的程序。

异常向量表
异常向量表是CPU中某些特定地址的特定定义。当中断发生的时候,中断要想办法通知CPU去处理中断,怎么做到?这就要靠异常向量表。
在CPU设计时,就事先定义了CPU中一些特定地址作为特定异常的入口地址。例如定义0x00000000地址为复位异常向量地址,则发生复位异常时CPU会自动跳转到0x00000000地址去执行指令。
以上讲的是CPU硬件设计时对异常向量表的支持,但是需要软件的支持。硬件已经决定了发生什么异常CPU自动跳转PC到哪个地址去执行,软件需要做的就是把处理这个异常的代码的首地址填入这个异常向量地址。

异常和中断的区别和联系
针对SoC来说,发生复位、软中断、中断、快速中断、取指令异常、数据异常等,我们都统一叫异常。所以说:中断其实是异常的一种
异常的定义就是突发事件,打断了CPU的正常常规业务,CPU不得不跳转到异常向量表中去执行异常处理程序;中断是异常的一种,一般特指SoC内的内部外设产生的打断SoC常规业务,或者外部中断(SoC的GPIO引脚传回来的中断)。

为什么中断要在汇编中进行?
中断处理要注意保护现场(中断从SVC模式来,则保存SVC模式下的必要寄存器的值)和恢复现场(中断处理完成后,准备返回SVC模式前,要将保存的SVC模式下的必要寄存器的值恢复回去,不然到了SVC模式后寄存器的值乱了,SVC模式下原来正在进行的常规任务就被弄乱了)。
保存现场包括:第一:设置IRQ栈;第二,保存LR;第三,保存R0~R12
为什么要保存LR寄存器?要考虑中断ISR执行完后如何返回SVC模式下去接着执行原来的代码。中断返回其实取决于我们进入中断时如何保存现场。中断返回时关键的2个寄存器就是PC和CPSR。所以我们在进入IRQ模式时,应该将SVC模式下的下一句指令的地址(中断返回地址)和CPSR保存起来,将来恢复时才可以将中断返回地址给PC,将保存的CPSR给CPSR中断返回地址就保存在LR中,而CPSR(自动)保存在(IRQ模式下的)SPSR中。
总结:
(1)保现场关键是保存:中断处理程序的返回地址,r0-r12(cpsr是自动保存的)。
(2)恢复现场主要是恢复:r0-r12,pc,cpsr。

2. 中断的基本过程

中断处理一般分为两个阶段。

阶段一:异常向量表阶段
第一个阶段之所以能够进行,主要依赖于CPU设计时提供的异常向量表机制。第一个阶段的主要任务是从异常发生到响应异常并且保存/恢复现场、跳转到真正的异常处理程序处。
阶段二:处理中断阶段
第二个阶段的目的是识别多个中断源中究竟哪一个发生了中断,然后调用相应的中断处理程序来处理这个中断。
小阶段1:查询中断状态寄存器来确定在哪里发生了中断。
小阶段2:通过ISR函数指针来执行对应的中断响应。

二、S5PV210中断代码详解

1. 中断处理时要用到的寄存器

(1)VICINTENABLE和VICINTENCLEAR
在这里插入图片描述
VICINTENABLE 对应interrupt enable,负责相应的中断的使能,当我们想使能(意思就是启用这个中断,意思就是当硬件产生中断时CPU能接收的到)某个中断时,只要在这个中断编号对应的VICnINTENABLE的相应bit位写1即可(注意这个位写1其他位写0对其他位没有影响)。
VICINTENCLEAR对应interrupt enable clear,负责相应的中断的禁止,如果我们想禁止某个中断源时,只要向VICnINTENCLEAR中相应的位写1即可。

(2)VICINTSELECT
在这里插入图片描述
设置各个中断的模式为irq还是fiq,一般都设置成irq。
IRQ和FIQ究竟有何区别?210中支持2种中断,irq和fiq。irq是普通中断,fiq是快速中断。快速中断提供一种更快响应处理的中断通道,用于对实时性要求很高的中断源。fiq在CPU设计时预先提供了一些机制保证fiq可以被快速处理,从而保证实时性。fiq的限制就是只能有一个中断源被设置为fiq,其他都是irq。
CPU如何保证fiq比irq快?有2个原因:第一,fiq模式有专用的r8r12,因此在fiq的isr中可以直接使用r8r12而不用保存,这就能节省时间;第二,异常向量表中fiq是最后一个异常向量入口。因此fiq的isr不需要跳转,可以直接写在原地,这样就比其他异常少跳转一次,省了些时间。

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

(4)VICVECTPRIORITY0~VICVECTPRIORITY31
在这里插入图片描述
中断优先级设置寄存器,设置多个中断同时发生时先处理谁后处理谁的问题。一般来说高优先级的中断可以打断低优先级的中断,从而嵌套处理中断。当然了有些硬件/软件可以设置不支持中断嵌套。

(5)VICVECTADDR0~VICVECTADDR31、VICADDR
在这里插入图片描述
在这里插入图片描述
这几个寄存器和210中断处理第二阶段的第二阶段有关。
VICnVECTADDR0到31这32个寄存器分别用来存放真正的各个中断对应的isr的函数地址。相当于每一个中断源都有一个VECTADDR寄存器,程序员在设置中断的时候,把这个中断的isr地址直接放入这个中断对应的VECTADDR寄存器即可。
S5PV210中因为支持的中断源很多,所以直接设计了4个中断寄存器(也就是VICVECTADDR),每个32位,每位对应一个中断源。(理论上210最多支持128个中断,实际支持不足128个,有些位是空的);210没有子中断寄存器,每个中断源都是并列的。当中断发生时,在irq_handler中依次去查询4个中断源寄存器,看哪一个的哪一位被置1,则这个位对应的寄存器就发生了中断,即找到了中断编号。

VICnADDR这个寄存器是只需要读的,它里面的内容是由硬件自动设置的。当发生了相应中断时,硬件会自动识别中断编号,并且会自动找到这个中断的VECTADDR寄存器,然后将其读出复制到VICnADDR中,供我们使用 。 这样的设计避免了软件查找中断源和isr,节省了时间,提高了210的中断响应速度。
210开拓了一种全新的寻找ISR的机制:210提供了很多寄存器来解决每个中断源对应ISR的寻找问题,当发生相应中断时,硬件会自动的将相应ISR推入一定的寄存器中(也就是VICADDR),我们软件只要去这个寄存器中执行函数就行了。

2. 中断处理函数解析

(1)int.c文件
绑定中断异常向量表
在这里插入图片描述
初始化中断控制寄存器
在这里插入图片描述
绑定ISR到VICnVECTADDR寄存器

在这里插入图片描述
使能中断
在这里插入图片描述
禁止中断的原理与使能中断的原理相同,只是给VICINTENABLE寄存器写数据变为了给VICINTENCLEAR写寄存器。

中断处理函数
在这里插入图片描述
这里需要搞清楚2个寄存器的区别:VICnVECTADDR和VICnADDR
VICVECTADDR寄存器一共有4×32个,每个中断源都有一个VECTADDR寄存器,我们应该将自己为这个中断源写的ISR地址丢到这个中断源对应的VECTADDR寄存器中即可。
当发生中断时,硬件会自动把相应中断源的ISR地址从VICnVECTADDR寄存器中推入VICnADDR寄存器中,所以我们第二阶段的第二阶段isr_handler中,只需要到相应的VICnADDR中去拿出ISR地址,调用执行即可。
这里绑定ISR地址到VICnVECTADDR和中断发生时第二阶段的第二阶段如何获取ISR地址,这两步是相关的。 这两个的结合技术,就是我们一直在说的210的硬件自动寻找ISR的机制。

handler是真正的中断处理程序,这里只考虑中断处理,不考虑保护现场/恢复现场。
handle中做现场保护。

(2)int.h文件
在这里插入图片描述
(3)start.S文件
在这里插入图片描述

整个中断的流程梳理:
整个中断的工作分为2部分:
第一部分是我们为中断响应而做的预备工作:
1. 初始化中断控制器
2. 绑定写好的isr到中断控制器
3. 相应中断的所有条件使能
第二部分是当硬件产生中断后如何自动执行isr:
1. 第一步,经过异常向量表跳转入IRQ/FIQ的入口
2. 第二步,做中断现场保护(在start.S中),然后跳入isr_handler(第二阶段)
3. 第三步,在isr_handler中先去搞清楚是哪个VIC中断了,然后直接去这个VIC的ADDR寄存器中取isr来执行即可。
4. 第四步,isr执行完,中断现场恢复,直接返回继续做常规任务。

二、S5PV210外部中断过程详解

1. 外部中断

SoC支持的中断类型中有一类叫外部中断。内部中断就是指的中断源来自于SoC内部(一般是内部外设),譬如串口、定时器等部件产生的中断;外部中断是SoC外部的设备,通过外部中断对应的GPIO引脚产生的中断。
按键在SoC中就使用外部中断来实现。具体实现方法是:将按键电路接在外部中断的GPIO上,然后将GPIO配置为外部中断模式。 此时人通过按按键改变按键电路的电压高低,这个电压高低会触发GPIO对应的外部中断,通过引脚传进去给CPU处理。

本实验采用S5PV210板卡上的按键来触发外部中断,选用板卡上的LEFT、DOWN、RIGHT按键作为触发源。通过调试可得,该3个按键对应的寄存器为GPH0_2、GPH0_3、GPH2_1。

2. 配置按键为外部中断触发模式

首先通过GPIO来初始化外部按键,包括GPIO模式设置,中断触发模式设置,中断允许,清挂起:
在这里插入图片描述
编写ISR程序:
在这里插入图片描述

3. 中断发生以及处理的过程

第一步:产生中断
当我们按下按键时,对应的GPIO口的电平会发生变化,根据原理图可得,当按下时信号电平又高变低,相当于产生了一个下降沿。此时GPIO口的模式已经配置为EXT模式(外部中断),并且中断触发模式也设置为了下降沿触发,这时CPU则会检测到一个中断信号。假设我们按下的按键时LEFT,对应的GPIO接口为GPHO_2,因此CPU则会知道这个GPIO接口产生了一个下降沿。

第二步:查找异常向量表
在CPU发生中断后,由于设置为了IRQ模式,因此CPU会自动执行IRQ模式下的一系列操作,包括设置栈,保存LR、R0-R12、CPSR(相当于保存当前执行进度)。
在这里插入图片描述
第三步:查找对应中断的VIC
在这里插入图片描述
由于之前已经将中断位置与中断物理标号进行了绑定,因此CPU会根据中断的物理编号去判断是哪个VIC上发生了中断,并使能该VIC。由于开始已经将ISR函数的地址与对应的VERTADDR进行了绑定,当发生相应中断时,硬件会自动的将相应ISR推入到VICADDR寄存器中,我们软件只要去这个寄存器中执行函数就行了。
第四步:执行中断处理程序
在这里插入图片描述
通过VICADDR寄存器,CPU访问到了ISR函数,然后执行对应的中断处理程序。执行完程序之后,恢复现场,使得程序继续正常运行,并清理掉挂起,以防对下次发生中断时造成影响。

在这里插入图片描述

发布了65 篇原创文章 · 获赞 83 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_42826337/article/details/104658743