ARM中的中断.docx
- 文档编号:8890938
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:18
- 大小:1.95MB
ARM中的中断.docx
《ARM中的中断.docx》由会员分享,可在线阅读,更多相关《ARM中的中断.docx(18页珍藏版)》请在冰豆网上搜索。
ARM中的中断
一、S5PV210中中断的特点
1、特点
•Supports93vectoredIRQinterrupts
•Fixedhardwareinterruptsprioritylevels
•Programmableinterruptprioritylevels
•SupportsHardwareinterruptprioritylevelmasking
•Programmableinterruptprioritylevelmasking
•GeneratesIRQandFIQ
•GeneratesSoftwareinterrupt
2、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=EnablesInterrupt打开中断
1=Masked关闭中断
4、外部中断判断寄存器
0=Notoccur外部中断没有发生
1=Occurinterrupt触发了中断
该寄存器的作用:
1)读该寄存器,可以知道对应的中断源是否触发。
2)写该寄存器,可以实现清除中断,如果一个中断不清除,CPU就会认为该中断还是存在的,就会再次触发该中断,形成循环。
所以我们在中断处理程序中,需要清除中断。
清中断的方法:
如果一个中断已经触发,该寄存器的相应位会自动置1,我们需要向该位写个“1”,就可以将该位清0,写“0”无效。
这是PEND寄存器的特点
例如:
清EINT18
EXT_INT_2_PEND|=(1<<2);
5、IRQ的状态寄存器
通过该寄存器,可以得到某个IRQ类型中断源是否发生的状态。
6、中断类型设置寄存器
7、打开中断的寄存器
例:
打开EINT18和EINT19
VIC0INTENABLE|=(1<<16);
EXT_INT_2_MASK&=~(0x3<<2);
8、关闭中断的寄存器
例:
关闭EINT18和EINT19
VIC0INTENCLEAR|=(1<<16);
EXT_INT_2_MASK|=(0x3<<2);
9、VIC向量地址寄存器
ISR-----InterruptServiceRoutine中断处理程序
该寄存器的内容是当前正在响应的中断服务程序的入口地址,我们可以通过该地址去调用中断服务程序。
向该寄存器写任何值,都可以清除中断,一般情况下,中断的清除都是在ISR的结束位置。
10、每个中断源的向量地址寄存器
注意:
该每个VIC(共有4个)有32个这样的寄存器,当我们在做中断初始化的时候,需要安装中断,安装中断的时候,要将中断服务程序的入口地址,写到对应的向量地址寄存器中。
例:
voideint18_19_isr(void)
{
//点灯
//清中断
}
如何实现中断向量的安装?
?
?
VIC0VECTADDR16=(unsignedint)eint18_19_isr;
EINT16~EINT31的向量地址寄存器=中断服务程序的入口地址
四、中断的响应过程。
以外部中断EINT18为例,分析中断的响应过程。
1、start.S
_start:
ldrsp,=0x40000000//初始化管理模式的stack,stack在DDR2中
movr0,#0x53
msrCPSR,r0//对CPSR[7:
0]=01010011,管理模式,arm状态、关闭FIQ、IRQ打开
bmain//进入C环境
2、当一个IRQ中断发生的时候,首先进入IRQ中断的入口地址:
PC=0x00000018,分析0x18地址上是什么内容?
?
?
0x18地址是s5pv210内容iROM中的BL0,samsung固化。
3、在iRom的0x18地址有一个跳转指令,跳转到iRAM中异常中断向量表中。
PC=0xD0037418?
?
?
4、异常中断向量的安装
int_init(void)//中断初始化的时候调用
{
//vectortableofexceptioninitialize
pExceptionUNDEF=(unsignedlong)exceptionundef;//undefine
pExceptionSWI=(unsignedlong)exceptionswi;//softwareinterrupt
pExceptionPABORT=(unsignedlong)exceptionpabort;//pabort
pExceptionDABORT=(unsignedlong)exceptiondabort;//dataabort
pExceptionIRQ=(unsignedlong)IRQ_handle;//IRQ
pExceptionFIQ=(unsignedlong)FIQ_handle;//FIQ
………………………………………….
}
分析
异常中断向量表的安装:
1)pExceptionIRQ
#definepExceptionIRQ(*((volatileunsignedlong*)(_Exception_Vector+0x18)))
#define_Exception_Vector0xD0037400
总结:
pExceptionIRQ是0xD0037418地址下的内容,该地址是IRQ异常中断映射后的入口地址
2)(unsignedlong)IRQ_handle;
IRQ_handle:
@CPSR会由硬件自动保存到SPSR_irq
ldrsp,=0xD0037F80//初始化IRQ模式的stack
sublr,lr,#4//返回地址的修正,原因:
IRQ中断的返回地址是LR-4,与流水线相关
stmfdsp!
{r0-r12,lr}//将R0~R12及LR入栈保存,相当于保护现场
blIrq_Isr
ldmfdsp!
{r0-r12,pc}^@将SPSR_irq恢复给CPSR
LR的值为什么要修正:
总结:
IRQ_handle子程序的入口地址
PC=IRQ_handle
5、执行IRQ_handle子程序
IRQ_handle:
@CPSR会由硬件自动保存到SPSR_irq
ldrsp,=0xD0037F80
sublr,lr,#4
stmfdsp!
{r0-r12,lr}
blIrq_Isr
ldmfdsp!
{r0-r12,pc}^@将SPSR_irq恢复给CPSR
6、现场保护后,执行Irq_Isr
voidIrq_Isr(void)
{
inti;
//VIC的向量地址寄存器
unsignedlongvicaddr[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))VIC0ADDRESS
break;
}
}
(*isr)();//调用前面定义的函数
}
//查看中断的状态,当某个中断发生,VICIRQSTATUS的相应的位就会为1,
例:
EINT18有效:
VIC0IRQSTATUS[16]=1
unsignedlongintc_getvicirqstatus(unsignedlongucontroller)
{
if(ucontroller==0)
returnVIC0IRQSTATUS;
elseif(ucontroller==1)
returnVIC1IRQSTATUS;
elseif(ucontroller==2)
returnVIC2IRQSTATUS;
elseif(ucontroller==3)
returnVIC3IRQSTATUS;
else
{}
return0;
}
分析:
isr=((void)(*)(void))VIC0ADDRESS
1)isr函数指针
2)((void)(*)(void))VIC0ADDRESS
当EINT18有效的时候,EINT18对应向量地址寄存器(VIC0VECTADDR16)中的内容会由硬件自动的拷贝到VIC0ADDRESS寄存器中。
总结:
isr函数指令,是指向VIC0ADDRESS的内容,在这个位置又是一个isr函数的调用。
PC=VIC0ADDRESS=VIC0VECTADDR16,CPU就开始执行VIC0ADDRESS下的内容。
7、ARM开始执行VIC0VECTADDR16地址下的函数
在中断初始化的时候:
//initializevectorinterruptaddresswithnumofinitandisr.
//中断的安装NUM_EINT16_31---中断号:
16
//EINT16_31_ISR---中断处理程序
//将EINT16_31_ISR的入口地址写入到VEC0VECTADDR16
intc_setvectaddr(NUM_EINT16_31,EINT16_31_ISR);
分析:
//theaddressresigsterofvectorinterruptinitialize
//numofint,isrofint
//intc_setvectaddr(NUM_EINT16_31,EINT16_31_ISR);
该函数的作用:
将一个中断服务程序的入口地址,写到该中断对应的向量地址寄存器中。
voidintc_setvectaddr(unsignedlongintnum,void(*handler)(void))
{
//VIC0
if(intnum<32)
{
//*((volatileunsignedlong*)(0xF2000000+0x100+0x40)=(unsignedint)EINT16_31_ISR得到EINT16_31_ISR的入口地址
//VIC0VECTADDR16=EINT16_31_ISR的入口地址
*((volatileunsignedlong*)(VIC0VECTADDR+4*intnum))=(unsigned)handler;
}
//VIC1
elseif(intnum<64)
{
*((volatileunsignedlong*)(VIC1VECTADDR+4*(intnum-32)))=(unsigned)handler;
}
//VIC2
elseif(intnum<96)
{
*((volatileunsignedlong*)(VIC2VECTADDR+4*(intnum-64)))=(unsigned)handler;
}
//VIC3
else
{
*((volatileunsignedlong*)(VIC3VECTADDR+4*(intnum-96)))=(unsigned)handler;
}
return;
}
总结:
PC=VIC0VECTADDR16=(unsignedint)EINT16_31_ISR;
8、执行中断服务程序EINT16_31_ISR
外部中断EINT16_31的中断服务程序,在该中断服务中,在去判断子中断EINT18、EINT19
voidEINT16_31_ISR(void)//EINT18/EINT19
{
if(EXT_INT_2_PEND&(1<<2))//EINT18发生
{
GPJ2DAT^=(1<<0);//toggleD1
//clearpendingbit
EXT_INT_2_PEND=1<<2;
//clearVIC0ADDRESS
//VIC0ADDRESS=0;
intc_clearvectaddr();
}
if(EXT_INT_2_PEND&(1<<3))//EINT19反生
{
GPJ2DAT^=(1<<1);//toggleD2
//clearpendingbit
EXT_INT_2_PEND=1<<3;
//clearVIC0ADDRESS
intc_clearvectaddr();
}
}
9、中断返回
IRQ_handle:
@CPSR会由硬件自动保存到SPSR_irq
ldrsp,=0xD0037F80
sublr,lr,#4
stmfdsp!
{r0-r12,lr}
blIrq_Isr
ldmfdsp!
{r0-r12,pc}^@将SPSR_irq恢复给CPSR
ldmfdsp!
{r0-r12,pc}^
分析:
1)将R0~R12出栈
2)将LR出栈给PC,中断的返回
3)将SPSR_irq恢复给CPSR
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ARM 中的 中断