第七章EINT外部中断.docx

上传人:b****5 文档编号:29348836 上传时间:2023-07-22 格式:DOCX 页数:15 大小:1.15MB
下载 相关 举报
第七章EINT外部中断.docx_第1页
第1页 / 共15页
第七章EINT外部中断.docx_第2页
第2页 / 共15页
第七章EINT外部中断.docx_第3页
第3页 / 共15页
第七章EINT外部中断.docx_第4页
第4页 / 共15页
第七章EINT外部中断.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

第七章EINT外部中断.docx

《第七章EINT外部中断.docx》由会员分享,可在线阅读,更多相关《第七章EINT外部中断.docx(15页珍藏版)》请在冰豆网上搜索。

第七章EINT外部中断.docx

第七章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的响应过程。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 公共行政管理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1