当前位置:文档之家› ARM中的中断

ARM中的中断

一、S5PV210中中断的特点1、特点• Supports 93 vectored IRQ interrupts• Fixed hardware interrupts priority levels• Programmable interrupt priority levels• Supports Hardware interrupt priority level masking• Programmable interrupt priority level masking• Generates IRQ and FIQ• Generates Software interrupt2、FIQ与IRQ的区别1)FIQ和IRQ并不是中断源,而是中断的类型,我们可以将一个中断源设置成FIQ也可以设置成IRQ。

2)FIQ是快速中断,IRQ是一般中断,FIQ的响应时间比IRQ短。

3)FIQ的优先级高于IRQ。

4)FIQ的分组寄存器(R8~R14)比IRQ(R13~R14)多。

当在FIQ产生的时候,R8~R14不需要保存,响应的速度会快。

3、S5PV210的中断源二、原理图分析三、如何以中断的方式来检测按键:GPH2_2(EINT18) 、GPH2_3(EINT19) 按键的检测:轮询:将GPIO配置成输入…….中断:将GPIO配置成外部中断…….1、GPIO的配置,将一个GPIO配置成外部中断2、外部中断的触发方式(高电平、低电平、上升沿、下降沿)3、外部中断的开关寄存器0 = Enables Interrupt 打开中断1 = Masked 关闭中断4、外部中断判断寄存器0 = Not occur 外部中断没有发生1 = Occur interrupt 触发了中断该寄存器的作用:1)读该寄存器,可以知道对应的中断源是否触发。

2)写该寄存器,可以实现清除中断,如果一个中断不清除,CPU就会认为该中断还是存在的,就会再次触发该中断,形成循环。

所以我们在中断处理程序中,需要清除中断。

清中断的方法:如果一个中断已经触发,该寄存器的相应位会自动置1,我们需要向该位写个“1”,就可以将该位清0,写“0”无效。

这是PEND寄存器的特点例如:清EINT18EXT_INT_2_PEND |= (1<<2);5、IRQ的状态寄存器通过该寄存器,可以得到某个IRQ类型中断源是否发生的状态。

6、中断类型设置寄存器7、打开中断的寄存器例:打开EINT18和EINT19VIC0INTENABLE |= (1<<16);EXT_INT_2_MASK &= ~(0x3<<2);8、关闭中断的寄存器例:关闭EINT18和EINT19VIC0INTENCLEAR |= (1<<16);EXT_INT_2_MASK |= (0x3<<2);9、VIC向量地址寄存器ISR ----- Interrupt Service Routine 中断处理程序该寄存器的内容是当前正在响应的中断服务程序的入口地址,我们可以通过该地址去调用中断服务程序。

向该寄存器写任何值,都可以清除中断,一般情况下,中断的清除都是在ISR的结束位置。

10、每个中断源的向量地址寄存器注意:该每个VIC(共有4个)有32个这样的寄存器,当我们在做中断初始化的时候,需要安装中断,安装中断的时候,要将中断服务程序的入口地址,写到对应的向量地址寄存器中。

例:void eint18_19_isr(void){//点灯//清中断}如何实现中断向量的安装???VIC0VECTADDR16 = (unsigned int)eint18_19_isr;EINT16~EINT31的向量地址寄存器= 中断服务程序的入口地址四、中断的响应过程。

以外部中断EINT18为例,分析中断的响应过程。

1、start.S_start:ldr sp, =0x40000000 //初始化管理模式的stack,stack在DDR2中mov r0, #0x53msr CPSR, r0 //对CPSR[7:0] = 010 10011,管理模式,arm状态、关闭FIQ、IRQ打开b main //进入C环境2、当一个IRQ中断发生的时候,首先进入IRQ中断的入口地址:PC = 0x00000018, 分析0x18地址上是什么内容???0x18地址是s5pv210内容iROM中的BL0,samsung固化。

3、在iRom的0x18地址有一个跳转指令,跳转到iRAM中异常中断向量表中。

PC = 0xD0037418 ???4、异常中断向量的安装int_init(void) //中断初始化的时候调用{//vector table of exception initializepExceptionUNDEF = (unsigned long)exceptionundef;//undefinepExceptionSWI = (unsigned long)exceptionswi;//software interruptpExceptionPABORT = (unsigned long)exceptionpabort;//pabortpExceptionDABORT = (unsigned long)exceptiondabort;//data abort pExceptionIRQ = (unsigned long)IRQ_handle;//IRQpExceptionFIQ = (unsigned long)FIQ_handle;//FIQ………………………………………….}分析异常中断向量表的安装:1)pExceptionIRQ#define pExceptionIRQ ( *((volatile unsigned long *)(_Exception_Vector + 0x18)) )#define _Exception_Vector 0xD0037400总结:pExceptionIRQ是0xD0037418地址下的内容,该地址是IRQ异常中断映射后的入口地址2)(unsigned long)IRQ_handle;IRQ_handle: @CPSR会由硬件自动保存到SPSR_irqldr sp, =0xD0037F80 //初始化IRQ模式的stacksub lr, lr, #4 //返回地址的修正,原因:IRQ中断的返回地址是LR-4,与流水线相关stmfd sp!, {r0-r12, lr} //将R0~R12及LR入栈保存,相当于保护现场bl Irq_Isrldmfd sp!, {r0-r12, pc}^ @将SPSR_irq恢复给CPSRLR的值为什么要修正:总结:IRQ_handle子程序的入口地址PC = IRQ_handle5、执行IRQ_handle子程序IRQ_handle: @CPSR会由硬件自动保存到SPSR_irqldr sp, =0xD0037F80sub lr, lr, #4stmfd sp!, {r0-r12, lr}bl Irq_Isrldmfd sp!, {r0-r12, pc}^ @将SPSR_irq恢复给CPSR6、现场保护后,执行Irq_Isrvoid Irq_Isr(void){int i;//VIC的向量地址寄存器unsigned long vicaddr[4] = {VIC0ADDRESS,VIC1ADDRESS,VIC2ADDRESS,VIC3ADDRESS};void (*isr)(void) = (void *)0; //定义一个函数指针,指向0地址for(i=0; i<4; i++){if(intc_getvicirqstatus(i) != 0){isr = (void (*)(void)) vicaddr[i]; //i = 0; isr=((void)(*)(void)) VIC0ADDRESSbreak;}}(*isr)(); //调用前面定义的函数}//查看中断的状态,当某个中断发生,VICIRQSTA TUS的相应的位就会为1,例:EINT18有效:VIC0IRQSTA TUS[16] =1unsigned long intc_getvicirqstatus(unsigned long ucontroller){if(ucontroller == 0)return VIC0IRQSTA TUS;else if(ucontroller == 1)return VIC1IRQSTA TUS;else if(ucontroller == 2)return VIC2IRQSTA TUS;else if(ucontroller == 3)return VIC3IRQSTA TUS;else{}return 0;}分析:isr=((void)(*)(void)) VIC0ADDRESS1)isr 函数指针2)((void)(*)(void)) VIC0ADDRESS当EINT18有效的时候,EINT18对应向量地址寄存器(VIC0VECTADDR16)中的内容会由硬件自动的拷贝到VIC0ADDRESS寄存器中。

总结:isr函数指令,是指向VIC0ADDRESS的内容,在这个位置又是一个isr函数的调用。

PC=VIC0ADDRESS= VIC0VECTADDR16,CPU就开始执行VIC0ADDRESS下的内容。

7、ARM开始执行VIC0VECTADDR16地址下的函数在中断初始化的时候://initialize vector interrupt address with num of init and isr.//中断的安装NUM_EINT16_31---中断号:16// EINT16_31_ISR---中断处理程序//将EINT16_31_ISR的入口地址写入到VEC0VECTADDR16intc_setvectaddr(NUM_EINT16_31, EINT16_31_ISR);分析://the address resigster of vector interrupt initialize//num of int, isr of int//intc_setvectaddr(NUM_EINT16_31, EINT16_31_ISR);该函数的作用:将一个中断服务程序的入口地址,写到该中断对应的向量地址寄存器中。

void intc_setvectaddr(unsigned long intnum, void (*handler)(void)){//VIC0if(intnum<32){//*( (volatile unsigned long *)(0xF2000000+0x100+0x40)=(unsigned int)EINT16_31_ISR得到EINT16_31_ISR的入口地址//VIC0VECTADDR16=EINT16_31_ISR的入口地址*( (volatile unsigned long *)(VIC0VECTADDR + 4*intnum) ) = (unsigned)handler;}//VIC1else if(intnum<64){*( (volatile unsigned long *)(VIC1VECTADDR + 4*(intnum-32)) ) = (unsigned)handler;}//VIC2else if(intnum<96){*( (volatile unsigned long *)(VIC2VECTADDR + 4*(intnum-64)) ) = (unsigned)handler;}//VIC3else{*( (volatile unsigned long *)(VIC3VECTADDR + 4*(intnum-96)) ) = (unsigned)handler;}return;}总结:PC= VIC0VECTADDR16 = (unsigned int ) EINT16_31_ISR;8、执行中断服务程序EINT16_31_ISR外部中断EINT16_31的中断服务程序,在该中断服务中,在去判断子中断EINT18、EINT19void EINT16_31_ISR(void) //EINT18/EINT19{if(EXT_INT_2_PEND & (1<<2))//EINT18发生{GPJ2DAT ^= (1<<0); //toggle D1// clear pending bitEXT_INT_2_PEND = 1<<2;// clear VIC0ADDRESS//VIC0ADDRESS = 0;intc_clearvectaddr();}if(EXT_INT_2_PEND & (1<<3))//EINT19反生{GPJ2DAT ^= (1<<1); //toggle D2// clear pending bitEXT_INT_2_PEND = 1<<3;// clear VIC0ADDRESSintc_clearvectaddr();}}9、中断返回IRQ_handle: @CPSR会由硬件自动保存到SPSR_irq ldr sp, =0xD0037F80sub lr, lr, #4stmfd sp!, {r0-r12, lr}bl Irq_Isrldmfd sp!, {r0-r12, pc}^ @将SPSR_irq恢复给CPSRldmfd sp!, {r0-r12, pc}^分析:1)将R0~R12出栈2)将LR出栈给PC,中断的返回3)将SPSR_irq恢复给CPSR。

相关主题