异常及中断处理汇总.docx
- 文档编号:8498155
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:22
- 大小:356.01KB
异常及中断处理汇总.docx
《异常及中断处理汇总.docx》由会员分享,可在线阅读,更多相关《异常及中断处理汇总.docx(22页珍藏版)》请在冰豆网上搜索。
异常及中断处理汇总
一.ARM异常中断处理概述
1、中断的概念
中断是一个过程,是CPU在执行当前程序的过程中因硬件或软件的原因插入了另一段程序运行的过程。
因硬件原因引起的中断过程的出现是不可预测的,即随机的,而软中断是事先安排的。
2、中断源的概念
我们把可以引起中断的信号源称之为中断源。
3、中断优先级的概念
ARM处理器中有7种类型的异常,按优先级从高到低的排列如下:
复位异常(Reset)、数据异常(DataAbort)、快速中断异常(FIQ)、外部中断异常(IRQ)、预取异常(PrefetchAbort)、软件中断(SWI)和未定义指令异常(Undefinedinstruction)
二.ARM体系异常种类
下面是ARM的7种异常
当异常发生时,处理器会把PC设置为一个特定的存储器地址。
这一地址放在被称为向量表(vectortable)的特定地址范围内。
向量表的入口是一些跳转指令,跳转到专门处理某个异常或中断的子程序。
当异常产生时,ARMcore:
拷贝CPSR到SPSR_
设置适当的CPSR位:
改变处理器状态进入ARM状态
改变处理器模式进入相应的异常模式
设置中断禁止位禁止相应中断(如果需要)
保存返回地址到LR_
设置PC为相应的异常向量
返回时,异常处理需要:
从SPSR_
从LR_
Note:
这些操作只能在ARM态执行.
当异常发生时,分组寄存器r14和SPSR用于保存处理器状态,操作伪指令如下。
R14_
SPSR_
CPSR[4∶0]=exceptionmodenumber
CPSR[5]=0/*进入ARM状态*/
If
CPSR[6]=1/*屏蔽快速中断FIQ*/
CPSR[7]=1/*屏蔽外部中断IRQ*/
PC=exceptionvectoraddress
异常返回时,SPSR内容恢复到CPSR,
连接寄存器r14的内容恢复到程序计数器PC。
注:
cortex-A8系统中支持通过设置CP15的c12寄存器将异常向量表的首地址设置在任意地址。
例如:
mcrp15,0,r0,c12,c0,0
1.复位异常
当处理器的复位引脚有效时,系统产生复位异常中断,程序跳转到复位异常中断处理程序处执行。
复位异常中断通常用在下面两种情况下。
系统上电。
系统复位。
当复位异常时,系统执行下列伪操作:
R14_svc=UNPREDICTABLEvalue
SPSR_svc=UNPREDICTABLEvalue
CPSR[4∶0]=0b10011/*进入特权模式*/
CPSR[5]=0/*处理器进入ARM状态*/
CPSR[6]=1/*禁止快速中断*/
CPSR[7]=1/*禁止外设中断*/
Ifhighvectorsconfiguredthen
PC=0xffff0000
Else
PC=0x00000000
复位异常中断处理程序的主要功能:
设置异常中断向量表。
初始化数据栈和寄存器。
初始化存储系统,如系统中的MMU等。
初始化关键的I/O设备。
使能中断。
处理器切换到合适的模式。
初始化C变量,跳转到应用程序执行。
2.未定义指令异常
当ARM处理器执行协处理器指令时,它必须等待一个外部协处理器应答后,才能真正执行这条指令。
若协处理器没有相应,则发生未定义指令异常
当未定义异常发生时,系统执行下列的伪操作:
r14_und=addressofnextinstructionaftertheundefinedinstruction
SPSR_und=CPSR
CPSR[4∶0]=0b11011/*进入未定义指令模式*/
CPSR[5]=0/*处理器进入ARM状态*/
/*CPSR[6]保持不变*/
CPSR[7]=1/*禁止外设中断*/
Ifhighvectorsconfiguredthen
PC=0xffff0004
Else
PC=0x00000004
3.软中断SWI
软中断异常发生时,处理器进入特权模式,执行一些特权模式下的操作系统功能。
软中断异常发生时,处理器执行下列伪操作。
r14_svc=addressofnextinstructionaftertheSWIinstruction
SPSR_und=CPSR
CPSR[4∶0]=0b10011/*进入特权模式*/
CPSR[5]=0/*处理器进入ARM状态*/
/*CPSR[6]保持不变*/
CPSR[7]=1/*禁止外设中断*/
Ifhighvectorsconfiguredthen
PC=0xffff0008
Else
PC=0x00000008
4.预取指令异常
预取指令异常是由系统存储器报告的。
当处理器试图去取一条被标记为预取无效的指令时,发生预取异常。
如果系统中不包含MMU时,指令预取异常中断处理程序只是简单地报告错误并退出。
若包含MMU,引起异常的指令的物理地址被存储到内存中。
预取异常发生时,处理器执行下列伪操作:
r14_svc=addressoftheabortedinstruction+4
SPSR_und=CPSR
CPSR[4∶0]=0b10111/*进入特权模式*/
CPSR[5]=0/*处理器进入ARM状态*/
/*CPSR[6]保持不变*/
CPSR[7]=1/*禁止外设中断*/
Ifhighvectorsconfiguredthen
PC=0xffff000C
Else
PC=0x0000000C
5.数据访问中止异常
数据访问中止异常是由存储器发出数据中止信号,它由存储器访问指令Load/Store产生。
当数据访问指令的目标地址不存在或者该地址不允许当前指令访问时,处理器产生数据访问中止异常。
当数据访问中止异常发生时,处理器执行下列伪操作。
r14_abt=addressoftheabortedinstruction+8
SPSR_abt=CPSR
CPSR[4∶0]=0b10111
CPSR[5]=0
/*CPSR[6]保持不变*/
CPSR[7]=1/*禁止外设中断*/
Ifhighvectorsconfiguredthen
PC=0xffff000C10
Else
PC=0x00000010
当数据访问中止异常发生时,寄存器的值将根据以下规则进行修改:
①返回地址寄存器r14的值只与发生数据异常的指令地址有关,与PC值无关
②如果指令中没有指定基址寄存器回写,则基址寄存器的值不变
③如果指令中指定了基址寄存器回写,则寄存器的值和具体芯片的AbortModels有关,由芯片的生产商指定
④如果指令只加载一个通用寄存器的值,则通用寄存器的值不变
⑤如果是批量加载指令,则寄存器中的值是不可预知的值
⑥如果指令加载协处理器寄存器的值,则被加载寄存器的值不可预知
6.外部中断IRQ
当处理器的外部中断请求引脚有效,而且CPSR寄存器的I控制位被清除时,处理器产生外部中断IRQ异常。
系统中各外部设备通常通过该异常中断请求处理器服务。
当外部中断IRQ发生时,处理器执行下列伪操作。
r14_irq=addressofnextinstructiontobeexecuted+4
SPSR_irq=CPSR
CPSR[4∶0]=0b10010/*进入特权模式*/
CPSR[5]=0/*处理器进入ARM状态*/
/*CPSR[6]保持不变*/
CPSR[7]=1/*禁止外设中断*/
Ifhighvectorsconfiguredthen
PC=0xffff0018
Else
PC=0x00000018
7.快速中断FIQ
当处理器的快速中断请求引脚有效且CPSR寄存器的F控制位被清除时,处理器产生快速中断请求FIQ异常。
当快速中断异常发生时,处理器执行下列伪操作。
r14_fiq=addressofnextinstructiontobeexecuted+4
SPSR_fiq=CPSR
CPSR[4∶0]=0b10001/*进入FIQ模式*/
CPSR[5]=0
CPSR[6]=1
CPSR[7]=1
Ifhighvectorsconfiguredthen
PC=0xffff001c
Else
PC=0x0000001c
三.ARM异常的优先级
四.ARM处理器模式和异常
ARM处理器异常及其对应的模式:
每一种异常都会导致内核进入一种特定的模式。
也可以通过编程改变CPSR,进入任何一种ARM处理器模式。
注:
用户模式和系统模式是仅有的不可以通过异常进入的两种模式,也就是说,要进入这两张模式必须通过编程改变CPSR
五.ARM异常响应和处理程序返回
1.中断响应的概念
中断响应大致可以分为以下几个步骤:
1、保护断点,即保存下一将要执行的指令的地址,就是把这个地址送入堆栈。
Sublr,lr,#4
Stmfdsp!
{r0-r12,lr}
2、寻找中断入口,根据不同的中断源所产生的中断,查找不同的入口地址。
Blc_irq_handler
3、执行中断处理程序。
可以写在main函数中
4、中断返回:
执行完中断指令后,就从中断处返回到主程序,继续执行。
Ldmfdsp!
{r0-r12,pc}^
2.ARM异常响应流程
1.判断处理状态
2.向量表
跳转指令B的跳转范围为±32MB,但很多情况下不能保证所有的异常处理函数都定位在向量的32MB范围内,需要更大范围的跳转,而且由于向量表空间的限制,只能由一条指令完成。
具体实现方法有下面两种。
(1)MOVPC,#imme_value这种办法将目标地址直接赋值给PC。
但这种方法受格式限制不能处理任意立即数。
这个立即数由一个8位数值循环右移偶数位得到。
(2)LDRPC,[PC+offset]把目标地址先存储在某一个合适的地址空间,然后把这个存储器单元的32位数据传送给PC来实现跳转。
这种方法对目标地址值没有要求。
但是存储目标地址的存储器单元必须在当前指令的±4KB空间范围内。
注意:
在计算指令中引用offset数值的时候,要考虑处理器流水线中指令预取对PC值的影响。
3.从异常处理程序中返回
1.恢复被中断程序的处理器状态
PC和CPSR的恢复可以通过一条指令来实现,下面是3个例子。
MOVSPC,LR
SUBSPC,LR,#4
LDMFDSP!
,{PC}^
这几条指令是普通的数据处理指令,特殊之处在于它们把程序计数器寄存器PC作为目标寄存器,并且带了特殊的后缀“S”或“^”。
其中“S”或“^”的作用就是使指令在执行时,同时完成从SPSR到CPSR的拷贝,达到恢复状态寄存器的目的。
2.异常的返回地址
六.S5PC100中断相关的寄存器
如果你要想通过VIC(中断控制器)控制一个外设,首先查下面的中断源表,找到其中断号,然后去看中断控制器中的寄存器对应哪位来控制这个中断。
如果你需要在片外连接一个外设,并且这个外设也需要申请中断怎么办呢?
对了,用外部中断管脚。
也就是上图对应的从0号到16号中断源,其中需要注意到是有16根中断管脚共用一根中断请求线,怎么共用呢?
我们看下图外部中断管理模块,从SOC共有32个管脚引出来,这些管脚是复用的,可以配置成通用输入/输出IO,也可以配置成唤醒中断的模式(及内部会连接到中断控制器电路)。
GPIO模块内部有三个寄存器对这32根管线的中断功能进行管理。
(1).功能寄存器如图,对管脚的电平激发方式进行管理,可以配置成高电平激发中断,低电平、上升沿、下降沿、双边沿等。
相关寄存器如下:
WKUP_INT0_7_CON
WKUP_INT8_15_CON
WKUP_INT16_24_CON
WKUP_INT25_31_CON
图为中断控制器
(2)Mask寄存器外部管脚EINT16到EINT31共16根线共用一根线EINT(16-31)连接到中断控制器,也就是共用一个中断号(中断号16),可能需要在某一个时刻只能有一根管脚线的信号通过模块顺利进入中断控制器,这个时候就需要将其余的管脚信号屏蔽起来,如何屏蔽呢?
就是设置mask里的对应位。
相关寄存器如下:
WKUP_INT0_7_MASK
WKUP_INT8_15_MASK
WKUP_INT16_24_MASK
WKUP_INT25_31_MASK
(3)Pend寄存器记录中断信号标志。
如果信号通过了前面的关口,送入了VIC,就是将对应线上的pend寄存器的对应位值1,如果在某一时刻,中断控制器来不起处理当前信号线上的中断请求,那么pend位会一直保持着这个请求,哪怕硬件中断线上的中断激发状态已经过去。
同样,需要注意是,如果当前线上的中断已经处理,这个pend位也不会自动清零,需要人为的清零。
相关寄存器如下:
WKUP_INT0_7_PEND
WKUP_INT8_15_PEND
WKUP_INT16_24_PEND
WKUP_INT25_31_PEND
中断信号请求的流程是:
1使外设有中断激发的功能(如果为外部中断,设置电平激发方式)。
2设置子模块下的mask寄存器,让需要监控的中断信号能通过,而不需要监控的则被屏蔽。
3开启中断控制器中对应每个中断源的使能位。
1.S5PC100的中断相关的寄存器
中断状态寄存器VIC0IRQSTATUS
中断源模式选择寄存器VIC0INTSELECT
中断源使能寄存器VIC0INTENABLE
中断源向量地址寄存器VIC0VECTADDR0...VIC0VECTADDR31
中断源入口地址寄存器VIC0ADDRESS
一.ARM的SWI异常中断处理程序设计
汇编:
_start:
breset_handler
nop
bswi_handler
nop
nop
nop
nop
swi_handler:
stmfdsp!
{r0-r12,lr}
ldrr0,[lr,-4]
bicr0,r0,#0xff000000@获取软中断的中断号
blc_swi_handler
ldmfdsp!
{r0-r12,pc}^@SPSR->CPSR并出栈
c_swi_handler:
stmfdsp!
{r0-r12,lr}
cmpr0,#5
bleqsys_open
cmpr0,#6
bleqsys_close
ldmfdsp!
{r0-r12,pc}
二.ARM的IRQ异常中断处理程序设计
汇编:
_start:
breset_handler@reset异常
nop
nop
nop
nop
nop
birq_handler@中断异常
nop
irq_handler:
sublr,lr,#4@调整返回地址
stmfdsp!
{r0-r12,lr}@压栈保存寄存器
blc_irq_handler@跳转到C中中断处理函数执行执行完返回
ldmfdsp!
{r0-r12,pc}^@出栈并回复cpsr
reset_handler:
/****将异常向量表搬到20008000****/
ldrr0,=0x20008000
mcrp15,0,r0,c12,c0,0
/****初始化svc栈顶指针****/
ldrr0,=0x30000000
movsp,r0
subr0,r0,#0x1000
/****到irq模式下初始化irq模式栈顶指针,开irqfiq****/
msrcpsr_c,#0x12
movsp,r0
subr0,r0,#0x100
/****到user模式并且初始化user的栈顶指针****/
msrcpsr_c,#0x10
movsp,r0
/****清bss段****/
clear_bss:
movr2,#0
ldrr0,=__bss_start
ldrr1,=__bss_end
bss_loop:
cmpr0,r1
strner2,[r0],#4
bnebss_loop
/****跳转到****/
bmain
.end
(一)key中断
/*****key_IRQ*****/
voidc_irq_handler(void)
{
void(*pfunc)(void);
pfunc=(void*)VIC0ADDRESS;
pfunc();
printf("c_irq_handler!
!
!
!
!
!
!
!
!
\r\n");
VIC0ADDRESS=0;
VIC1ADDRESS=0;
VIC2ADDRESS=0;
}
voidkey1_irq_init(void)
{
//设置IO为激发中断功能
GPH0.GPH0CON=GPH0.GPH0CON&~(0xf<<4)|(0x2<<4);
//设置外部中断管脚为下降沿激发方式
WU_INT0_7_CON=WU_INT0_7_CON&~(0x7<<4)|(0x2<<4);
//enablemask位
WU_INT0_7_MASK=WU_INT0_7_MASK&~(1<<1);
//注册中断处理函数因为按键1链接的为EINT1所以将处理函数放在对应第0组第一个地址寄存器里
VIC0VECTADDR.VIC0VECTADDR1=(unsignedint)key1_down;
//enable中断控制器中对应中断源的使能位
VIC0INTERRUPT.VIC0INTENABLE=VIC0INTERRUPT.VIC0INTENABLE|(1<<1);
}
voidkey2_irq_init(void)
{
GPH0.GPH0CON=GPH0.GPH0CON&~(0xf<<8)|(0x2<<8);
WU_INT0_7_CON=WU_INT0_7_CON&~(0x7<<8)|(0x2<<8);
WU_INT0_7_MASK=WU_INT0_7_MASK&~(1<<2);
VIC0VECTADDR.VIC0VECTADDR2=(unsignedint)key2_down;VIC0INTERRUPT.VIC0INTENABLE=VIC0INTERRUPT.VIC0INTENABLE|(1<<2);
}
voidkey1_down(void)
{
printf("*****key1_down*******\r\n");
WU_INT0_7_PEND=(1<<1);
}
voidkey2_down(void)
{
printf("*****key2_down*******\r\n");
WU_INT0_7_PEND=(1<<2);
}
voidmain(void)
{
uart0_init();
key1_irq_init();
key2_irq_init();
uart0_sendstring("hellofarsight!
!
\n\r");
inta=100;
printf("a=%d\n\r",a);
while
(1);
}
(二)UART中断
/*****uart0_IRQ*****/
voidc_irq_handler(void)
{
void(*pfunc)(void);
pfunc=(void*)VIC0ADDRESS;
pfunc();
uart0_sendstring("c_irq_handler!
!
!
!
!
!
!
!
!
\r\n");
VIC0ADDRESS=0;
VIC1ADDRESS=0;
VIC2ADDRESS=0;
}
voiduart0_recvchar_irq(void)
{
uart0_sendchar(UART0.URXH0);
//清标志位写1清0
UART0.UINTP0=UART0.UINTP0;
UART0.UINTSP0=UART0.UINTSP0;
}
voidmain(void)
{
uart0_init();
uart0_sendstring("hellofarsight!
!
\n\r");
//注册中断处理函数
UART0.UINTM0=~0x1;
VIC1VECTADDR.VIC1VECTADDR10=(unsignedint)uart0_recvchar_irq;
VIC1INTERRUPT.VIC1INTENABLE=VIC1INTERRUPT.VIC1INTENABLE|(1<<10);
while
(1);
}
(三)ADC中断
/*****ADC_IRQ*****/
voidc_irq_handler(void)
{
void(*pfunc)(void);
pfunc=(void*)VIC0ADDRESS;
pfunc();
uart0_sendstring("c_irq_handler!
!
!
!
!
!
!
!
!
\r\n");
VIC0ADDRESS=0;
VIC1ADDRESS=0;
VIC2ADDRESS=0;
}
voidadc_init(void)
{
//精度12位|开启分频|分频得1M|读转换
//ADC.ADCCON=(1<<16)|(1<<14)|(65<<6)|(1<<1);
ADC.ADCCON=(1<<16)|(1<<14)|(65<<6)|
(1);//手动开启转换
ADC.ADCMUX=0;//选择第0通道
}
voidadc_read_handler(void)
{
adc_val=ADC.ADCDA
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 异常 中断 处理 汇总
![提示](https://static.bdocx.com/images/bang_tan.gif)