异常及中断处理.docx

上传人:b****8 文档编号:9258387 上传时间:2023-05-17 格式:DOCX 页数:26 大小:355.11KB
下载 相关 举报
异常及中断处理.docx_第1页
第1页 / 共26页
异常及中断处理.docx_第2页
第2页 / 共26页
异常及中断处理.docx_第3页
第3页 / 共26页
异常及中断处理.docx_第4页
第4页 / 共26页
异常及中断处理.docx_第5页
第5页 / 共26页
异常及中断处理.docx_第6页
第6页 / 共26页
异常及中断处理.docx_第7页
第7页 / 共26页
异常及中断处理.docx_第8页
第8页 / 共26页
异常及中断处理.docx_第9页
第9页 / 共26页
异常及中断处理.docx_第10页
第10页 / 共26页
异常及中断处理.docx_第11页
第11页 / 共26页
异常及中断处理.docx_第12页
第12页 / 共26页
异常及中断处理.docx_第13页
第13页 / 共26页
异常及中断处理.docx_第14页
第14页 / 共26页
异常及中断处理.docx_第15页
第15页 / 共26页
异常及中断处理.docx_第16页
第16页 / 共26页
异常及中断处理.docx_第17页
第17页 / 共26页
异常及中断处理.docx_第18页
第18页 / 共26页
异常及中断处理.docx_第19页
第19页 / 共26页
异常及中断处理.docx_第20页
第20页 / 共26页
亲,该文档总共26页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

异常及中断处理.docx

《异常及中断处理.docx》由会员分享,可在线阅读,更多相关《异常及中断处理.docx(26页珍藏版)》请在冰点文库上搜索。

异常及中断处理.docx

异常及中断处理

一.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_恢复CPSR

从LR_恢复PC

Note:

这些操作只能在ARM态执行.

当异常发生时,分组寄存器r14和SPSR用于保存处理器状态,操作伪指令如下。

R14_=returnlink

SPSR_=CPSR

CPSR[4∶0]=exceptionmodenumber

CPSR[5]=0/*进入ARM状态*/

If==resetorFIQthen

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=A

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

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2