第七章EINT外部中断.docx
- 文档编号:29348836
- 上传时间:2023-07-22
- 格式:DOCX
- 页数:15
- 大小:1.15MB
第七章EINT外部中断.docx
《第七章EINT外部中断.docx》由会员分享,可在线阅读,更多相关《第七章EINT外部中断.docx(15页珍藏版)》请在冰豆网上搜索。
第七章EINT外部中断
EINT外部中断
1、ARM异常中断
IRQ(一般中断)和FIQ(快速中断)不是具体的中断源,而是中断的类型。
我们是可以将一个中断源的类型设置成FIQ也可以设置成IRQ。
在使用FIQ响应的时间比IRQ要短,其他方面没有什么区别。
但是一般情况下,在一个平台内,我们只能将一个中断源设置成FIQ。
2、S5PV210的中断源
1、总共有93个,其中外部中断有32个。
2、93个中断源分成了4个中断控制器(VIC)
3、具体中断源(210手册p1-5)
注意:
所有的中断源产生的中断最终都有VIC0中断控制器提交给S5PV210内核,所以,在中断服务函数中做清除中断处理时,要将4个的VICADDRESS寄存器都要做写操作。
3、外部中断设计流程
中断控制:
1)程序状态寄存器CPSR的F位和I位
2)中断模式
4、S5PV210中断控制器的特点
•Supports93vectoredIRQinterrupts
•Fixedhardwareinterruptsprioritylevels
•Programmableinterruptprioritylevels
•SupportsHardwareinterruptprioritylevelmasking
•Programmableinterruptprioritylevelmasking
•GeneratesIRQandFIQ
•GeneratesSoftwareinterrupt
•Testregisters
•Rawinterruptstatus
•Interruptrequeststatus
•SupportsPrivilegedmodeforrestrictedaccess
5、分析GEC210平台的原理图
EINT16是一个二级中断,对应的一级入口是EINT16_31。
6、中断的初始化(设置SFR)
1、将GPH2_0设置成EINT16
2、设置EINT16的触发方式
3、设置外部中断的滤波器
4、外部中断pending(判断/清除寄存器)
5、外部中断的开关(屏蔽)寄存器
6、设置中断类型
EINT16----->VIC0INTSELECT
7、中断向量地址寄存器
1)VIC0ADDRESS
读:
该寄存器放置的是正在响应的入口中断处理程序的入口地址。
该入口地址是在对应中断源向量地址寄存器(VIC0VECTADDRn)中初始化的。
写:
向该寄存器写0,用来清除中断。
2)VIC0VECTADDRn
在中断初始化的时候,将中断处理程序的入口地址保存到该寄存器。
8、中断的开关寄存器
7、程序的设计
1、程序入口(start.S)
.global_start
.globalIRQ_handle
_start:
ldrsp,=0x40000000@初始化栈,stack放在DDR2
movr0,#0x53
msrCPSR_cxsf,r0@ARM进入管理模式,并关闭FIQ、打开IRQ
blclock_init@初始化210的系统时钟
bmain@调用了main,进入中断初始化
IRQ_handle:
@IRQ中断的处理程序,在ARM响应IRQ中断时,会进入该程序
ldrsp,=0xD0037F80@初始化IRQ模式的stack
sublr,lr,#4@修正返回地址
stmfdsp!
{r0-r12,lr}@保存现场,入栈
blIrq_Isr@调用C环境的程序,去处理IRQ中断,在Irq_Isr函数中,确定中断源。
ldmfdsp!
{r0-r12,pc}@退出现场,并实现中断的返回
2、main函数
voidisr_key(void)//EINT16中断处理程序
{
GPJ2DAT^=(1<<0);//toggleled
intc_clearvectaddr();//clearVIC0ADDRESS
EXT_INT_2_PEND|=1<<0;//clearpendingbit
}
intmain(void)
{
//GPJ2CON[3:
0]=0001;GPJ2_0--->output
GPJ2CON&=~(0xf<<0);
GPJ2CON|=(1<<0);
//interruptcontrollerinit
int_init();
GPH2CON|=0xF;//GPH2_0-->EXT_INT[16]
//EXT_INT[16]:
Fallingedgetriggered
EXT_INT_2_CON&=~(7<0);
EXT_INT_2_CON|=(2<<0);
//initializevectorinterruptaddresswithnumofinitandisr.
intc_setvectaddr(NUM_EINT16_31,isr_key);//EINT16中断处理程序的安装
EXT_INT_2_MASK&=~(1<<0);//unmaskedEINT16
intc_enable(NUM_EINT16_31);//enableEINT16_31
while
(1);//等待中断
}
3、IRQ中断初始化函数
//exceptionandinterruptinitialize
voidint_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
//interruptcontrollerinit
//DisablesInterruptinVICxINTENABLERegister
VIC0INTENCLEAR=0xffffffff;
VIC1INTENCLEAR=0xffffffff;
VIC2INTENCLEAR=0xffffffff;
VIC3INTENCLEAR=0xffffffff;
//Selectsinterrupttypeforinterruptrequest(IRQ)
VIC0INTSELECT=0x0;
VIC1INTSELECT=0x0;
VIC2INTSELECT=0x0;
VIC3INTSELECT=0x0;
/*ContainstheaddressofthecurrentlyactiveISR,withresetvalue0x00000000.
AreadofthisregisterreturnstheaddressoftheISRandsetsthecurrentinterruptasbeingserviced.
Areadmustbeperformedwhilethereisanactiveinterrupt.
Awriteofanyvaluetothisregisterclearsthecurrentinterrupt.
Awritemustonlybeperformedattheendofaninterruptserviceroutine.*/
VIC0ADDRESS=0;
VIC1ADDRESS=0;
VIC2ADDRESS=0;
VIC3ADDRESS=0;
}
4、具体中断源的ISR安装函数
voidintc_setvectaddr(unsignedlongintnum,void(*handler)(void))
{
//VIC0
if(intnum<32)
{
*((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;
}
8、中断响应过程
1)异常中断的向量地址
当ARM接收到IRQ中断后,PC就会指向0x0000_0018。
一般在0x0000_0018上放一个跳转到IRQ中断处理的函数位置。
2)S5PV210的BL0
BL0是一个启动加载程序,存放在210的IROM,用户是不能改写的。
BL0的作用:
3)中断的响应过程(EINT16)
1、当ARM接收到EINT16(IRQ)时,PC=0x0000_0018,IROM中BL0会将PC由0x0000_0018跳到IRAM中0xD003_7418。
我们在int.h文件中定义如下:
#definepExceptionIRQ(*((volatileunsignedlong*)(0xD0037400+0x18))
2、PC=pExceptionIRQ
我们在int.c文件的voidint_init(void)函数做了下面工作:
pExceptionIRQ=(unsignedlong)IRQ_handle;//IRQ
3、PC=IRQ_handle
我们在start.s中,由如下代码:
IRQ_handle:
ldrsp,=0xD0037F80
sublr,lr,#4
stmfdsp!
{r0-r12,lr}//入栈,现场保存,和返回地址
blIrq_Isr
ldmfdsp!
{r0-r12,pc}//出栈,现场恢复,PC=lr
4、PC=Irq_Isr
我们在int.c源文件中定义了函数Irq_Isr()
voidIrq_Isr(void)
{
inti;
unsignedlongvicaddr[4]={VIC0ADDRESS,VIC1ADDRESS,VIC2ADDRESS,VIC3ADDRESS};
void(*isr)(void)=(void*)0;
for(i=0;i<4;i++)
{
if(intc_getvicirqstatus(i)!
=0)
{
isr=(void(*)(void))vicaddr[i];
break;
}
}
(*isr)();
5、PC-->VIC0ADDRESS
当EINT16有效的时候,VIC0ADDRESS=VIC0VECTADDR16
6、PC-->VIC0VECTADDR16
我们在main.c里面调用函数intc_setvectaddr(NUM_EINT16_31,isr_key);,下一步分析ntc_setvectaddr(),该函数定义在int.c。
7、PC=(unsigned)isr_key。
这样就找到了EINT16的中断处理程序isr_key()。
9、总结
1、ARM异常中断
2、S5pv210的中断源(一级中断和二级中断)
3、理解210中的VIC和寄存器
4、了解中断的响应过程。
注意:
中断控制器一般和ARM芯片的相关性比较强,不同的ARM芯片中断处理过程有很大的差异。
Linux中断的驱动,非常简单,一般只需要知道中断号即可。
10、作业
1)K2~K5按键控制D1~D4四个LED灯,用IRQ实现。
2)将EINT16设置为FIQ,分析FIQ的响应过程。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第七 EINT 外部 中断