ARM系统中断产生流程.docx

上传人:b****7 文档编号:9634449 上传时间:2023-02-05 格式:DOCX 页数:18 大小:128.06KB
下载 相关 举报
ARM系统中断产生流程.docx_第1页
第1页 / 共18页
ARM系统中断产生流程.docx_第2页
第2页 / 共18页
ARM系统中断产生流程.docx_第3页
第3页 / 共18页
ARM系统中断产生流程.docx_第4页
第4页 / 共18页
ARM系统中断产生流程.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

ARM系统中断产生流程.docx

《ARM系统中断产生流程.docx》由会员分享,可在线阅读,更多相关《ARM系统中断产生流程.docx(18页珍藏版)》请在冰豆网上搜索。

ARM系统中断产生流程.docx

ARM系统中断产生流程

ARM系统中断产生流程

中断源按照硬件位置分为外部中断源和内部中断源,外部中断源和内部中断源又包含子外部中断源和子内部中断源,如上图所示(画了一整天)。

1.子内部中断源的产生

以UART0接收数据产生INT_RXD0中断为例,INT_RXD0产生后进入SUBSRCPND子中断源暂存寄存器,设置INT_RXD0对应的中断位,中断信号经过INTSUBMSK子中断屏蔽寄存器,如果INT_RXD0信号对应位没有被置位(屏蔽掉),中断信号继续向前传递,经过子内部中断源聚合器,将INT_RXD0聚合成对应的中断源信号INT_UART0,设置SRCPND中断源暂存寄存器里INT_UART0位,经过INTMSK中断屏蔽寄存器,如果INT_UART0信号没有被屏蔽掉,中断信号进入INTMOD中断模式寄存器判断是否为快速中断,如果被编程为快速中断,直接打断ARM内核,进入中断处理,如果中断信号为一般中断,进入中断优先级仲裁器进入优先级仲裁,如果INT_UART0信号为最高优先级或只有INT_UART0中断信号产生,则该中断信号被记录到INTPND最高优先级中断暂存寄存器,同时设置INTOFFSET的值为中断号28,最终将中断信号打断ARM内核进行中断处理。

如果同时产生多个中断且INT_UART0不是最高优先级,则该中断信号不会被处理,等最高优先级信号处理完后,再次进行优先级仲裁,也就是说中断信号不消失,一直保存在SRCPND里,只到被处理为止。

2.内部中断源的产生

该过程在子内部中断处理过程中已经包含,中断信号产生后直接进入SRCPND里,然后经历上述子内部中断后期处理过程。

3.子外部中断的产生

外部中断源共有24个,其中EINT0~EINT3为外部中断源,EINT4_7,EINT8_23为复合中断源,他们包含有子外部中断源。

由于外部硬件直接挂接到I/OPorts(详见S3C2440A硬件手册第9章)上的,我们要想让外设硬件中断得到处理,要先从EINT0~EINT23里选择中断信号,我们以EINT11为例,介绍子外部中断处理过程。

通常CPU内部引出引脚都是复用的,也就是说一根CPU引脚可以有多种功能,可以设置其为输入信号线,输出信号线或中断信号线,要想让硬件产生中断,首先要对可以产生中断的引脚进行编程,设置该引脚为中断信号线。

EINT11中断信号对应CPU引脚为GPG3,通过设置GPGCON[7:

6]=0b10,可以设置该引脚为中断信号线。

表3-14GPGCON寄存器

 

设置了CPU管脚为中断信号线之后,还要通过设置EXTINT0寄存器来指定中断信号的触发方式:

高电平触发,低电平触发,电平上升沿,下除沿,双沿触发。

图3-9电平信号触发示意图

由于按键按下时让它产生中断,也就是从高电平变为低电平时产生(上节按键中断原理),因此我们设置EINT11中断信号的触发方式为下降沿触发,EXTINT1[14:

12]=0b01x

表3-15EXTINT1寄存器

 

设置完触发方式之后,当外设中断信号线上的电平达到触发条件时,通过外部中断产生器产生中断信号,然后将子外部中断暂存寄存器EINTPND中对应的EINT11位置1,中断信号再进入EINTMSK子外部中断屏蔽寄存器,如果EINT11中断源信号没有被屏蔽,则EINT11中断信号进入子外部中断聚合器,复合成EINT8_23中断信号,然后再经历与前面子内部中断信号一样的处理机制。

(1)EINTPEND外部中断暂存寄存器

表3-16外部中断暂存寄存器(EINTPEND)

寄存器名

地址

是否读写

描述

复位默认值

EINTPEND

0x560000A8

R/W

外部中断信号暂存寄存器

0:

没有中断请求信号

1:

中断请求信号产生

0x0000000

EINTPEND

描述

初始值

EINT23

[23]

0=未产生中断1=产生中断

0

EINT4

[4]

0=未产生中断1=产生中断

0

保留位

[3:

0]

0000

(2)EINTMASK外部中断屏蔽寄存器

表3-17外部中断屏蔽寄存器(EINTMASK)

寄存器名

地址

是否读写

描述

复位默认值

EINTMASK

0x560000A4

R/W

外部中断信号屏蔽寄存器

0:

未屏蔽,中断可用

1:

屏蔽中断信号

0x000FFFFF

EINTMASK

描述

初始值

EINT23

[23]

0=未屏蔽1=屏蔽中断

1

EINT4

[4]

0=未屏蔽1=屏蔽中断

1

保留位

[3:

0]

1111

4.外部中断源的产生

外部中断产生过程读者可以根据上面中断图自行分析。

按键控制LED灯实验

本实验分三个版本,分别针对三种开发板:

友善之臂QQ2440,友善之臂MINI2440,天嵌TQ2440。

每种开发板对应工程在:

“sys_irq_开发板名”目录下。

下面实验内容为针对MINI2440开发板。

head.s:

主要实现安装异常向量表,处理复位异常,初始化必要硬件,中断入口处理等功能。

;**********************************************************************

;系统中断实验(MINI2440)

;**********************************************************************

GPBCONEQU0x56000010

GPBDATEQU0x56000014

EXPORTSYS_IRQ

AREASYS_IRQ,CODE,READONLY

ENTRY

;**********************************************************************

;设置中断向量,除Reset和HandleIRQ外,其它异常都没有使用(如果不幸发生了,

;将导致死机)

;**********************************************************************

;0x00:

复位Reset异常

bReset

;0x04:

未定义异常(未处理)

HandleUndef

bHandleUndef

;0x08:

软件中断异常(未处理)

HandleSWI

bHandleSWI

;0x0c:

指令预取异常(未处理)

HandlePrefetchAbt

bHandlePrefetchAbt

;0x10:

数据访问中止异常(未处理)

HandleDataAbt

bHandleDataAbt

;0x14:

未使用异常(未处理)

HandleNotUsed

bHandleNotUsed

;0x18:

一般中断异常,跳往HandleIRQ

bHandleIRQ

;0x1c:

快速中断异常(未处理)

HandleFIQ

bHandleFIQ

Reset;复位异常处理入口

;关闭看门狗

ldrr0,=0x53000000

movr1,#0

strr1,[r0]

blinitmem

ldrsp,=0x32000000;设置管理模式栈指针

IMPORTuart_init

bluart_init;UART串口初始化

IMPORTirq_init

blirq_init;系统中断初始化

IMPORTkey_init

blkey_init;按键初始化

IMPORTled_init

blled_init;LED灯初始化

msrcpsr_cxsf,#0xd2;切换到中断模式下

ldrsp,=0x31000000;设置中断模式栈指针

msrcpsr_cxsf,#0x13;返回管理模式

ldrlr,=halt_loop;设置管理模式下返回地址

IMPORTmain

ldrpc,=main;跳入主函数main里执行

;***********************************************************************

;中断处理

;***********************************************************************

HandleIRQ

sublr,lr,#4;修正返回地址

stmdbsp!

{r0-r12,lr};保存程序执行现场

ldrlr,=int_return;设置中断处理程序返回地址

IMPORThandle_irq

ldrpc,=handle_irq;跳入中断处理程序

int_return;中断处理返回标签

ldmiasp!

{r0-r12,pc}^恢复程序执行现场,返回继续执行

halt_loop

bhalt_loop

initmem

ldrr0,=0x48000000

ldrr1,=0x48000034

;ldrr2,=memdata

adrr2,memdata

initmemloop

ldrr3,[r2],#4

strr3,[r0],#4

teqr0,r1

bneinitmemloop

movpc,lr

memdata

DCD0x22000000;BWSCON

DCD0x00000700;BANKCON0

DCD0x00000700;BANKCON1

DCD0x00000700;BANKCON2

DCD0x00000700;BANKCON3

DCD0x00000700;BANKCON4

DCD0x00000700;BANKCON5

DCD0x00018005;BANKCON6

DCD0x00018005;BANKCON7

DCD0x008e07a3;REFRESH

DCD0x000000b1;BANKSIZE

DCD0x00000030;MRSRB6

DCD0x00000030;MRSRB7

END;代码结束

该程序主要设置异常向量表,除了Reset异常和中断处理被处理以外,其它异常都未被处理,如果发生时,会产生死循环,Reset异常里主要实现了硬件的基本初始化,如:

按键,LED灯等,设置栈指针,用于执行C程序,最后跳入C程序的main函数。

在中断处理异常处理中首先修正返回地址,保存用户执行现场,跳入到中断处理例程中执行。

sys_init.c:

硬件初始化文件,里面包含LED,KEY的初始化函数。

#include"register.h"

#include"comm_fun.h"

#defineTXD0READY(1<<2)//发送数据状态OK

#defineRXD0READY

(1)//接收数据状态OK

/*UART串口初始化*/

voiduart_init()

{

GPHCON|=0xa0;//GPH2,GPH3usedasTXD0,RXD0

GPHUP=0x0;//GPH2,GPH3内部上拉

ULCON0=0x03;//8N1

UCON0=0x05;//查询方式为轮询或中断;时钟选择为PCLK

UFCON0=0x00;//不使用FIFO

UMCON0=0x00;//不使用流控

UBRDIV0=12;//波特率为57600,PCLK=12Mhz

}

/*UART串口单个字符打印函数*/

externvoidputc(unsignedcharc)

{

while(!

(UTRSTAT0&TXD0READY));

UTXH0=c;

}

/*UART串口接受单个字符函数*/

externunsignedchargetc(void)

{

while(!

(UTRSTAT0&RXD0READY));

returnURXH0;

}

/*UART串口字符串打印函数*/

externintprintk(constchar*str)

{

inti=0;

while(str[i]){

utc((unsignedchar)str[i++]);

}

returni;

}

/*按键初始化*/

intkey_init()

{

//设置K1,K2,K3,K4,K5,K6对应控制寄存器为中断模式

GPGCON=(2<<0)|(2<<6)|(2<<10)|(2<<12)|(2<<14)|(2<<22);

/*

01xfallingedgetriggered下降沿触发

10xRisingedgetriggered上升沿触发

11xBothedgetriggered双沿触发

*/

//设置K1,K2,K3,K4,K5按键中断触发方式为上升沿触发

EXTINT1=(3<<0)|(3<<12)|(3<<20)|(3<<24)|(3<<28);

EXTINT2=(3<<12);//设置K6按键中断触发方式为上升沿触

printk("按键初始化OK/r/n");

return0;

}

/*Led1~Led4初始化*/

#defineLED1(1<<5)//LED1GPBDAT[5]

#defineLED2(1<<6)//LED2GPBDAT[6]

#defineLED3(1<<7)//LED3GPBDAT[7]

#defineLED4(1<<8)//LED4GPBDAT[8]

/*点亮对应num号led灯*/

externintled_on(intnum)

{

switch(num)

{

case1:

GPBDAT=GPBDAT&~LED1;break;

case2:

GPBDAT=GPBDAT&~LED2;break;

case3:

GPBDAT=GPBDAT&~LED3;break;

case4:

GPBDAT=GPBDAT&~LED4;break;

default:

return0;

}

returnnum;

}

/*关闭num号led灯*/

externintled_off(intnum)

{

switch(num)

{

case1:

GPBDAT=GPBDAT|LED1;break;

case2:

GPBDAT=GPBDAT|LED2;break;

case3:

GPBDAT=GPBDAT|LED3;break;

case4:

GPBDAT=GPBDAT|LED4;break;

default:

return0;

}

returnnum;

}

/*关闭全部led灯*/

externintall_led_off(void)

{

GPBDAT=GPBDAT|LED1|LED2|LED3|LED4;

return0;

}

/*led灯初始化*/

intled_init(void)

{

GPBCON=0x15400;//设置GPB7为输出口

all_led_off();

printk("led初始化OK/r/n");

return0;

}

/*中断初始化*/

voidirq_init(void)

{

//打开KEY1~KEY6的屏蔽位

INTMSK&=~(1<<5);

EINTMASK&=~((1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19));

printk("中断初始化OK/r/n");

}

该文件是相关硬件初始化程序,主要包含了看门狗驱动,按键驱动,系统中断驱动,LED驱动。

handle_irq.c:

中断处理函数,查出中断源,中断处理,清除中断源。

#include"register.h"

#include"comm_fun.h"

#defineEINT_Key_REQUEST5//Key中断源中断号(6个按键全部使用外部子中断)

#defineK1_EINT_BIT(1<<8)//K1外部子中断位

#defineK2_EINT_BIT(1<<11)//K2外部子中断位

#defineK3_EINT_BIT(1<<13)//K3外部子中断位

#defineK4_EINT_BIT(1<<14)//K4外部子中断位

#defineK5_EINT_BIT(1<<15)//K5外部子中断位

#defineK6_EINT_BIT(1<<19)//K6外部子中断位

/*系统中断处理函数*/

voidhandle_irq()

{

unsignedlongirqOffSet=INTOFFSET;//取得中断号

all_led_off();//关闭全部Led灯

if(EINT_Key_REQUEST==irqOffSet){//Key中断产生(6个按键使用一个总中断号)

if(K1_EINT_BIT&EINTPEND){

led_on

(1);//点亮Led1

printk("Key1pressed/r/n");

EINTPEND&=K1_EINT_BIT;//清除外部子中断源

}elseif(K2_EINT_BIT&EINTPEND){

led_on

(2);//点亮Led2

printk("Key2pressed/r/n");

EINTPEND&=K2_EINT_BIT;//清除外部子中断源

}elseif(K3_EINT_BIT&EINTPEND){

led_on(3);//点亮Led3

printk("Key3pressed/r/n");

EINTPEND&=K3_EINT_BIT;//清除外部子中断源

}elseif(K4_EINT_BIT&EINTPEND){

led_on(4);//点亮Led4

printk("Key4pressed/r/n");

EINTPEND&=K4_EINT_BIT;//清除外部子中断源

}elseif(K5_EINT_BIT&EINTPEND){

all_led_off

(1);//熄灭全部Led

printk("Key5pressed/r/n");

EINTPEND&=K5_EINT_BIT;//清除外部子中断源

}elseif(K6_EINT_BIT&EINTPEND){

all_led_on();//点亮全部Led

printk("Key6pressed/r/n");

EINTPEND&=K6_EINT_BIT;//清除外部子中断源

}

}

SRCPND&=(1<

INTPND=INTPND;//清除中断结果

}

main.c:

包含主函数和延时函数,主要实现字符串的循环打印。

#include"register.h"

#include"comm_fun.h"

/*延时*/

voiddelay(intmsec)

{

inti,j;

for(i=1000;i>0;i--)

for(j=msec*10;j>0;j--)

/*donothing*/;

}

/*主函数*/

intmain()

{

while

(1)

{

printk("main函数在运行.../r/n");

delay(5);//delay

}

return0;

}

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

当前位置:首页 > 成人教育 > 自考

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

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