IMX6ULL裸机篇之中断实验-通用中断驱动说明一

一.  通用中断驱动

  本文针对 IMX6ULL裸机篇:中断实验。重点针对 C 语言编写通用中断驱动框架。启动文件 start.S 在这里不做详细的介绍(因为是汇编实现部分),汇编代码理解实现原理即可。

二.   启动文件 start.s

1.  start.s 中IRQ服务函数调用 system_irqhandler

start.S 文件中,我们在中断服务函数 IRQ_Handler 中调用了 system_irqhandler 来处
理具体的中断。而 system_irqhandler() 函数的实现是 C 语言负责实现。
start.S 文件调用部分如下:
/* IRQ中断!重点!!!!! */

IRQ_Handler:
	push {lr}					/* 保存lr地址 */
	push {r0-r3, r12}			/* 保存r0-r3,r12寄存器 */
	mrs r0, spsr				/* 读取spsr寄存器 */
	push {r0}					/* 保存spsr寄存器 */
	mrc p15, 4, r1, c15, c0, 0 /* 从CP15的C0寄存器内的值到R1寄存器中
								* 参考文档ARM Cortex-A(armV7)编程手册V4.0.pdf P49
								* Cortex-A7 Technical ReferenceManua.pdf P68 P138
								*/							
	add r1, r1, #0X2000			/* GIC基地址加0X2000,也就是GIC的CPU接口端基地址 */
	ldr r0, [r1, #0XC]			/* GIC的CPU接口端基地址加0X0C就是GICC_IAR寄存器,
								 * GICC_IAR寄存器保存这当前发生中断的中断号,我们要根据
								 * 这个中断号来绝对调用哪个中断服务函数
								 */
	push {r0, r1}				/* 保存r0,r1 */
	cps #0x13					/* 进入SVC模式,允许其他中断再次进去 */
	push {lr}					/* 保存SVC模式的lr寄存器 */
	ldr r2, =system_irqhandler	/* 加载C语言中断处理函数到r2寄存器中*/
	blx r2						/* 运行C语言中断处理函数,带有一个参数,保存在R0寄存器中 */
	pop {lr}					/* 执行完C语言中断服务函数,lr出栈 */
	cps #0x12					/* 进入IRQ模式 */
	pop {r0, r1}				
	str r0, [r1, #0X10]			/* 中断执行完成,写EOIR */
	pop {r0}					
	msr spsr_cxsf, r0			/* 恢复spsr */
	pop {r0-r3, r12}			/* r0-r3,r12出栈 */
	pop {lr}					/* lr出栈 */
	subs pc, lr, #4				/* 将lr-4赋给pc */

这里只摘出启动文件 start.S 文件 IRQ中断服务函数部分,汇编代码没有全部列出。

2.   屏蔽汇编设置中断向量偏移

之前的实验中,通过汇编(即 start.S文件中)设置中断向量偏移。本次实验通过 C语言设置中断向量偏移。

注意:设置中断向量偏移这个操作,也可以在 C语言中进行设置。只要在中断发生之前设置好就可以。

之前是在启动文件 start.S 中设置的,设置代码如下:

	/* 汇编版本设置中断向量表偏移 */
	ldr r0, =0X87800000
	dsb
	isb
	mcr p15, 0, r0, c12, c0, 0
	dsb
	isb

现在如果要在 C 语言中设置中断向量偏移,则以上启动文件中的汇编设置可以屏蔽掉。可使用如下宏进行屏蔽:

#if   0
	ldr r0, =0X87800000
	dsb
	isb
	mcr p15, 0, r0, c12, c0, 0
	dsb
	isb
#endif

下一篇文章来介绍 C语言实现设置中断向量偏移,以及通用中断驱动实现。

你可能感兴趣的:(linux,arm开发)