1,ARM中断机制
1.1,中断硬件机制
1.2,中断过程
1.3,中断源
Exynos4412中断控制器包含160个中断控制源,分三类分别是: | |
用于CPU之间通信的SGI (Software Generated Interrupt) |
![]() |
专用于特定CPU核的PPI (Private Peripheral Interrupt) |
|
被多个CPU核共享的SPI (Shared Peripheral Interrupt) |
1.4,中断控制器
中断源分发给不同的CPU.
每个中断都有一个唯一对应的ID号,当中断发生时,该ID号会写入一个特定的寄存器。
中断处理程序可以读取该寄存器来决定该调用哪个具体的中断处理函数。
2,外部中断的配置
2.1,查看原理图
可以看到按键k2,挂载在GPX1_1引脚上,对应XEINT9
2.2,外部,配置芯片管脚工作模式
2.2.1,配置I/O口为中断模式
GPX1CON = (GPX1CON & ~(0x0f << 4) | (0x0f << 4)); // 设置管脚为中断模式
2.2.2,配置中断为下降沿触发
EXT_INT41_CON = (EXT_INT41_CON & ~(0X07 << 4)) | (0X02 << 4); //设置中断触发方式为下降沿
2.2.3,使能外部中断
EXT_INT41_MASK = (EXT_INT41_MASK & ~(0X01 << 1)) | (0X00 << 1); //管脚中断使能(一关)
2.3,内部,设置功能模块(中断控制模块 GIC)
2.3.1,查GIC中断表,找出对应的中断端口号和ID号
XEINT9对应的中断端口号是25,ID号是57
2.3.2,设置GIC中断使能
ICDISER1_CPU0 = ICDISER1_CPU0 | (0x01 << 25); //使能对应中断(二关)
2.3.3,分发配置
根据样例选用默认设置
//#define ICDIPTR17_CPU0 (*(volatile unsigned int *)0x10490844) //分发配置,根据样例选用默认设置
#define ICDIPTR14_CPU0 (*(volatile unsigned int *)0x10490838) //分发配置,根据样例选用默认设置
//ICDIPTR17_CPU0 = 0x01010101;
ICDIPTR14_CPU0 = 0x01010101;
ICDIPTR17_CPU0 = 0x01010101; //分发器中断使能 (三关),根据样例选用默认设置
2.3.4,分发总使能
ICDDCR = ICDDCR | 0X01; //分发器中断使能 (三关)
2.3.5,CPU外部中断借口使能
ICCICR_CPU0 = ICCICR_CPU0 | 0x01; //CPU接口中断使能(四关)
2.3.6,设置CPU的中断优先级门限值
ICCPMR_CPU0 = 0xff; //设置CPU的中断优先级门限值,当前为最低,所有的中断都可以处理
3,中断处理
3.1,协处理器指令修改异常向量表起始地址
- CPU规定的异常向量表的地址是从0x00开始的,其中中断异常的地址是0x18
- 但是想开发版中下载程序的时候我们会制定一个起始地址,这样异常向量表的起始地址就不是0x00了
- 所以,需要重新制定模拟的异常向量表的起始地址
MRC Pn,op1,Rd,CRn,CRm,op2 //mrc p15,0,r0,c1,c0,0 读入cp15的c1寄存器的内容到r0中
MCR Pn,op1,Rd,CRn,CRm,op2 //mcr p15,0,r0,c1,c0,0 写r0内容到cp15的c1寄存器中
通过协处理器设置异常向量表的起始地址为0x40008000
@ set Vector Base Address 为0x40008000
ldr r0,=0x40008000
mcr p15,0,r0,c12,c0,0
3.2,异常向量表
_start: b start_code
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word _undefined_instruction
_software_interrupt: .word _software_interrupt
_prefetch_abort: .word _prefetch_abort
_data_abort: .word _data_abort
_not_used: .word _not_used
_irq: .word irq_handler
_fiq: .word _fiq
irq_handler:
sub lr,lr,#4
stmfd sp!,{r0-r12,lr} @保护现场
bl do_irq
irq_handler_end:
ldmfd sp!,{r0-r12,pc}^ @恢复现场