ARM中断机制

ARM中断机制

当事件发生时,通过一种机制告诉CPU现在发生什么事件,CPU停下现在所做的工作进行处理。中断处理流程:中断控制器汇集各类外设发出的中断信号,经过一段处理,选出一个信号,然后通知CPUCPU保存当前运行环境,然后调用中断服务程序(ISR)处理中断;在ISR中通过读取相关寄存器的外设判断中断类型,并进行相应的处理。清除中断:通过读写相关中断寄存器和外设相关寄存器实现;恢复被中断程序的执行环境,继续执行被中断程序。

S3c2440支持60个中断源,当外设产生中断后,中断控制器进行经过相应的一些处理,选出一个最适合的中断信号告诉CPU


非子中断源走下面,子中断源走上面,下面第一个寄存器SUBSRCPNO寄存器,SUBSRCPNO用来标识子中断是否发生,s3c244015个子中断,SUBSRCPNO每一位代表一个子中断,当这些子中断发生时,相应的位置。第二个寄存器INTSUBMASK用来屏蔽SUBSRCPN产生的中断信号,中断申请立刻拒绝,INTSUBMASK中某位置1时相应的子中断被屏蔽,设为0时被允许。寄存器SRCPND,每位用来标明中断是否发生,每个中断源都有相应的位与之匹配,INTMASK寄存器,用来屏蔽SRCPND产生的一类中断,某位被置1相应的中断被屏蔽,只能屏蔽IRQ中断。mode寄存器,某位被设置为1所对应的中断源被设置为FIQ模式,此中断发生时会进入快中断模式,IRQ模式下,中断处理程序需要自己保存r8r12寄存器,退出中断时需要自己恢复寄存器值,而FIR这几个寄存器都有back寄存器(fir_r8......),模式切换时CPU自动保存这些值到back寄存器,退出时自动恢复。FRQIRQ快,有较高优先级。INTMOD设置中断源是IRQ还是FRQ。经过模式设置后,如果是FRQ就直接处理,IRQ经过优先级排序。

优先级选择:选择出最高级中断处理,首先把32个中断划分成6个组,有6arbiter(仲裁器)仲裁谁的优先级最高,比如arbiter0, 外部中断0,1,2,3,在同一个仲裁器内优先级,由ARB_SEL决定


还有ARM_MODE,如果为0ARB_SEL不会自动改变,如果设置为1ARB_SEL就会自动改变


REQ0REQ5不会改变,REQ1,2,3,4交换,当REQ1正在服务时,ARB_SEL自动切换到01bREQ1放在最后.........................

经过层层删选最后选择出要执行的中断在INTPND寄存器体现,经过中断优先级仲裁器选出优先级高的中断后,这个中断在INTPND相应的寄存器置1,随后CPU进入中断模式处理,同一时间内此寄存器只有一位置

按键控制程序设计


Mini2440使用6个按键分别对应的外部中断,当按键按下时形成低电平触发中断,按键还对应了GPIO资源,GPIO作为输入,通过按键获取到相应的值。


下列使用轮询方式(CPU不断查询状态)设计,按一次点亮一个LED。
int Wait_key(void);
void key_init(void);
void Led1_init(void);
void Led1_run (void);
void main (void){
	LED1_init();
	while(1)	{
		if(Wait_key())
			Led1_run();	//点亮LED
	}
}
void key_init (){
	rGPGCON &= ~(3<<0);		//设置为输入模式
}
void Led1_init (){
	rGBCON &= ~(3<<10);
	rGBCON |= (1<<10);	//设置GPB5管脚为输出模式
}
void Led1_run (){
	rGPBDAT &=~ (1<<5);	//灯亮
	delay(1000);
	rGPBDAT |=~ (1<<5);	//灯灭
	delay(1000);
}
int Wait_key (void){
	if(!(rGPGDAT & 0x01)) 
 //如果rGPGDAT 最后一位为0,GPGDAT & 0x01为0,按键按下,反之为1
		delay(200);
	if(!(rGPGDAT & 0x01))	{
		while(!(rGPGDAT & 0x01))	//按下后后等待按键松开
			return 1;	//有按键按下
	}
	else
		return 0; 	//无按键按下
}

按键控制程序设计下面以中断方式设计

void key_init(void);
static void __irq key_handler(void);
void Led1_init(void);
void Led1_run(void);

void delay(int times)
{
    int i,j;
    for(i=0;i<times;i++)
       for(j=0;j<400;j++);
}

void Main(void)
{	
   Led1_init();
   MMU_Init();
   key_init();
   while(1);
	
}	

void key_init(void)
{
    rGPGCON &= ~(0x3<<0);     /*set eint8 as interrupt*/
    rGPGCON |=  (0x2<<0);
    
    rEXTINT1 &= ~(0xf<<0);   /*set eint8 with low level*/
    rEINTPEND |= (1<<8);
    rEINTMASK &= ~(1<<8);
    
    /*设置ISR*/
    pISR_EINT8_23=(U32)key_handler;
    EnableIrq(BIT_EINT8_23);
}    

static void __irq key_handler(void)
{
	/*判断是否是按键K1产生的中断*/
    if(rINTPND==BIT_EINT8_23) 
    {
		ClearPending(BIT_EINT8_23);
		if(rEINTPEND&(1<<8)) 
		{
			rEINTPEND |= 1<< 8;
			Led1_run();
		}
	}
}

void Led1_init(void)
{
    rGBCON &= ~(3<<10);
	rGBCON |= (1<<10);	//设置GPB5管脚为输出模式

}
/*************************************************
Function name: Led1_run()
Parameter    : void
Description	 : 运行Led
Return		 : void
Argument     : void
Autor & date : Daniel
**************************************************/
void Led1_run(void)
{
  rGPBDAT &=~ (1<<5);	//灯亮
	delay(1000);
	rGPBDAT |=~ (1<<5);	//灯灭
	delay(1000);
}


### ARM架构下中断机制的原理与实现 #### 中断机制概述 ARM架构下的中断机制是一种用于响应外部事件或内部错误的核心功能。它允许处理器暂停当前执行的任务,转向处理特定的异常情况或中断请求,完成后返回原任务继续运行[^1]。 #### 异常分类及其作用 在ARM架构中,异常被划分为多种类型,其中包括未定义指令(Undefined Instruction)、快速中断请求(FIQ)、普通中断请求(IRQ)以及系统调用(SWI)。每种类型的异常都有其独特的用途和优先级设置。例如,当遇到无法识别的指令时,会产生未定义指令异常,这有助于调试和错误检测[^2]。 #### S5PV210芯片中的中断处理流程 以S5PV210为例,在该芯片上实现了复杂的多源中断管理方案。当中断发生时,首先通过硬件自动跳转至预设地址——即异常向量表位置处开始执行相应的中断服务程序。典型的IRQ处理过程包括以下几个环节:保存上下文环境以便后续能够正确恢复;依据具体逻辑判断究竟是哪个设备触发了此次中断;随后调用匹配的具体中断服务例程完成实际工作负载;最后再还原之前的状态并退出中断状态回到正常任务流之中[^3]。 #### 软件层面的支持 - Linux内核中的映射机制 为了简化开发复杂度并增强可移植性,在Linux操作系统环境下引入了一套专门用来把底层物理层面上来自不同控制器所产生的众多独立编号转换成统一全局唯一表示形式的方法论体系结构设计思路–即将所有的硬中断号映射成为一个连续范围内的软中断号集合。这种做法使得即使面对着可能变化莫测的实际连接布局情况下也能保持高层应用接口不变从而减少维护成本提高效率[^4]。 ```c // 示例代码展示如何注册一个简单的中断处理函数 #include <linux/interrupt.h> static irqreturn_t my_interrupt_handler(int irq, void *dev_id) { // 处理中断逻辑... return IRQ_HANDLED; } int request_my_irq(unsigned int irq_number){ return request_irq(irq_number, my_interrupt_handler, 0, "my_device", NULL); } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值