ARM中断向量表与响应流程

发布者:自由思想最新更新时间:2018-06-04 来源: eefocus关键字:ARM  中断向量表  响应流程 手机看文章 扫描二维码
随时随地手机看文章

一首先中断向量表定义在哪里?如何加载?

 二 中断向量表与中断服务程序

三处理流程

////////////////////////////////////////////////////////////////////////////////////////////////////

一首先中断向量表定义在哪里?__vectors_start

首先中断向量表定义的是什么?定义的就是中断服务程序的跳转指令,因为每个中断向量在向量表中只有一个字节的存储空间,只能存放一条指令,所以通常存放跳转指令,使程序跳转到存储器的其他地方,再执行中断处理。这里cpu就可以找中断服务程序,跳转指令如例如:

LDRPC, =ISR_HANDLER;

或者

指令与不同的cpu平台有关系。

 

1.1 vector表定义的方式:往往是变量地址:

如 .

 .globl      __vectors_start  定义__vectors_start符号,这样外部程序可以访问到。entry-armv.S

__vectors_start:

       swi  SYS_ERROR0

       b    vector_und + stubs_offset

       ldr  pc, .LCvswi + stubs_offset

       b    vector_pabt + stubs_offset

       b    vector_dabt + stubs_offset

       b    vector_addrexcptn + stubs_offset

       b    vector_irq + stubs_offset

       b     vector_fiq + stubs_offset

ARM的异常处理向量表在entry-armv.S文件中:

1.2 中断向量表 类型


                   From ARM

 

       .globl      __vectors_start  定义__vectors_start符号,这样外部程序可以访问到。

__vectors_start:定义异常(地址逻辑自上而下0x00----0x1c)跟具体的cpu特性有关

 ARM(        swi        SYS_ERROR0        )向量0:reset,但是这里被修改了,如果是cpu跑到了0地址,用软件中断SYS_ERROR0来处理.

 THUMB(        svc        #0                )向量1

 THUMB(        nop                        )向量2

W(b)        vector_und+ stubs_offset  向量3 #未定义指令异常

W(ldr)        pc,.LCvswi + stubs_offset  向量4#软中断

W(b)        vector_pabt+ stubs_offset  #向量5指令预取异常中断(Prefetch Abort)

W(b)        vector_dabt+ stubs_offset   #向量6数据中止

W(b)        vector_addrexcptn+ stubs_offset  #向量7地址异常Thesearen't too critical.

W(b)        vector_irq+ stubs_offset  #向量8.IRQ(一般中断)

W(b)        vector_fiq+ stubs_offset  #向量9  FIQ(快速中断)

 

 

/*关于.globl指令:

    .global/.globl 命令

 

    .global symbol

 

    .global 使得连接程序(ld)能够识别symbl

    声明symbol是全局可见的。标号_start是GNU链接器用来指定第一个要执行指令所必须的,同样的是全局可见的(并且只能出现在一个模块中)

 

    例如:

        .global_start    #定义_start为外部程序可以访问的标签

 

__vectors_start符号,又存放在哪里呢?

有不同的方式,可以指定加载的ram地址,如\kernel\arch\c6x\kernel平台

SECTIONS

{

/*

 * Start kernel read only segment

 */

READONLY_SEGMENT_START

 

.vectors :

{

_vectors_start =.;

*(.vectors)

. = ALIGN(0x400);

_vectors_end = .;

}

指定好了vector在内核镜像加载到内存后的地址0x400;

 

但是arm就不指定,如下,在启动之后存放的地址:

//中断服务处理程序

    c000b500 T__kuser_helper_start

    c000b500 t__kuser_memory_barrier

    c000b520 t__kuser_cmpxchg

    c000b540 t__kuser_get_tls

    c000b55c t__kuser_helper_version

    c000b560 T__kuser_helper_end

    c000b560 T __stubs_start //中断服务处理程序

    c000b560 tvector_irq

    c000b5e0 tvector_dabt

    c000b660 tvector_pabt

    c000b6e0 tvector_und

    c000b760 tvector_fiq

    c000b764 tvector_addrexcptn

    c000b784 T__stubs_end

   c000b784 T __vectors_start中断向量表的起始地址 32字节

    c000b7a4 T__vectors_end

 

 

2.其次 向量表在系统bootup的时候被链接在哪里?

/out/target/product/huaqin82_cwet_kk/obj/KERNEL_OBJ/arch/arm/kernel/entry-armv.o  打包成build-in.o

 

3,最后内核建立向量表vector的拷贝

__trap_init函数填充后的向量表如下:

虚拟地址

异常

 处理汇编代码

0xffff0000

reset swi

SYS_ERROR0

0xffff0004

 undefined

b __real_stubs_start + (vector_undefinstr - __stubs_start)

0xffff0008

软件中断

ldr pc, __real_stubs_start + (.LCvswi - __stubs_start)

0xffff000c

取指令异常

b __real_stubs_start + (vector_prefetch - __stubs_start)

0xffff0010

数据异常

b __real_stubs_start + (vector_data - __stubs_start)

0xffff0014

 reserved

 b __real_stubs_start + (vector_addrexcptn - __stubs_start)

0xffff0018

irq

b __real_stubs_start + (vector_IRQ - __stubs_start)

0xffff001c

Fiq

 b __real_stubs_start + (vector_FIQ - __stubs_start)

 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

 二 中断向量表与中断服务程序

总的来说对于中断向量表的定义和存放(加载)和处理流程如下:

首先理解相关概念:

 

中断控制器

负责(1)屏蔽和过滤中断信号(2)唤醒cpu。

分为向量中断模式和非向量中断模式:

---向量中断模式用于RESET、NMI、异常处理。当向量中断产生时,控制器直接将PC赋值,如IRQ异常 跳到0x0000000d处,而在0x0000000d地址处通常放置ISR服务程序地址LDR PC, =ISR_HANDLER。

 

---非向量中断模式,有一个寄存器标识位,跳转到统一的函数地址,此函数通过判别寄存器标识位和优先级关系进行中断-处理。

跳转指令:

我分为两种:

 1是中断控制器的跳转指令(实际上编译好的机器码):为何需要?

因为当cpu在中断发生的时候,cpu如何知道把pc指针执行哪里去执行指令呢。所以通过中断控制器的跳转指令帮助把cpu的执行指针pc,执行相应的中断向量表。  

 

2是cpu相关的跳转指令,如arm处理器:b   bl ,ldr等:完成跳转到不同的中断服务处理程序。

 



 

1)中断服务程序 定义在哪里?如arm的dataabort异常处理程序:

首先跳转指令:b  vector_dabt + stubs_offset  ---->这个地址的指令定义也在entry-armv.S:

       vector_stub     dabt, ABT_MODE,8

----》__dabt_svc (内核模式发生dataabort) 或者 __dabt_usr(用户模式发生dataabort)

-----》dabt_helper是一个宏--->bl        CPU_DABORT_HANDLER

 

2)存放(加载)的地址?中断向量表定义好了之后,存放了ram的哪里呢?也就是__vectors_start存在内存什么地址?

 

答案:可以定在你需要的任何可访问ram地址(这里指的虚拟地址,不是物理ram地址)。

 

例子1 :单片机

非向量中断模式

假定非向量中断表定义在0x00400000开始的外部RAM空间:

                                  引用网络 图2  中断解析示例流程 

 

图2中实线表示的流程都用ARM汇编语言编写,一般作为boot代码的一部分放在系统的底层模块中。

填写向量表的操作可以在上层应用程序中方便地实现,比如在C语言中: *( int *(0x00400018)) = (int) ISR_IRQ;

这样就将IRQ中断的服务程序入口地址(0x00300260)填写到中断向量表中的固定地址0x00400018开始的4字节空间了。 

 

简单说就是:

在0x00000018的地址的跳转指令是:B0x00000600 ;

而0x00000600存放的指令是:ldr r0 =0x004000018;

 而0x004000018 存放的是0x00300260:=中断的服务程序ISR_IRQ的入口地址(0x00300260)

 

 

例子2:

ARM 的vector表是存放在

    c000b500 T__kuser_helper_start

    c000b500 t__kuser_memory_barrier

    c000b520 t__kuser_cmpxchg

    c000b540 t__kuser_get_tls

    c000b55c t__kuser_helper_version

    c000b560 T__kuser_helper_end

   c000b560 T __stubs_start

    c000b560 tvector_irq

    c000b5e0 tvector_dabt

    c000b660 tvector_pabt

    c000b6e0 tvector_und

    c000b760 tvector_fiq

    c000b764 tvector_addrexcptn

    c000b784 T__stubs_end

   c000b784 T __vectors_start中断向量表的起始地址

   c000b7a4 T __vectors_end

内核建立vector的拷贝

__trap_init函数填充后的向量表如下:

虚拟地址

异常

 处理汇编代码

0xffff0000

reset swi

SYS_ERROR0

0xffff0004

 undefined

b __real_stubs_start + (vector_undefinstr - __stubs_start)

0xffff0008

软件中断

ldr pc, __real_stubs_start + (.LCvswi - __stubs_start)

0xffff000c

取指令异常

b __real_stubs_start + (vector_prefetch - __stubs_start)

0xffff0010

数据异常

b __real_stubs_start + (vector_data - __stubs_start)

0xffff0014

 reserved

 b __real_stubs_start + (vector_addrexcptn - __stubs_start)

0xffff0018

irq

b __real_stubs_start + (vector_IRQ - __stubs_start)

0xffff001c

Fiq

 b __real_stubs_start + (vector_FIQ - __stubs_start)

---为何内核要拷贝到0xffff0000?这个是arm cpu的规定:对于ARMv4及其以上的版本,异常向量表的起始位置由协处理器15(cp15)的控制寄存器(c1)里的V位(bit13)有关,当V=0时,异常向量表的起始位置在0x00000000,而当V=1时,异常向量表就起始于0xffff0000位置。当有异常发生时,处理器会跳转到对应的0xffff0000起始的向量处取指令,然后,通过b指令散转到异常处理代码.因为ARM中b指令是相对跳转,而且只有+/-32MB的寻址范围,所以把__stubs_start~__stubs_end之间的异常处理代码复制到了0xffff0200起始处.这里可直接用b指令跳转过去,这样比使用绝对跳转(ldr)效率高。

 

三处理流程?cpu发生中断的时候,PC指针如何知道到0x000000-0x0000001c(linux内核copy到0xffff0000)的 地址(也就是到中断向量表vector中哪一种异常:swi,数据异常,irq等)去执行中断跳转指令呢?

答案是:中断控制器完成。如下:

                                                                                          上图(来自网络ppt)

向量中断模式用于RESET、NMI、异常处理。当向量中断产生时,控制器直接将PC赋值,如跳到0x0000000d处,而在0x0000000d地址处通常放置ISR服务程序地址。

 

处理流程分为两部分:如下

 

1。硬件部分:EINT orIRQ硬件信号-----》中断控制器跳转---到对应的异常----(硬件do it)-----》改变pc指针的地址------》

2。软件部分:中断向量表跳转指令(如b __real_stubs_start)-------》对应的中断处理程序,比如一般的irq流程 ---》entry-armv.S@  -----》vector_stub        irq,IRQ_MODE, 4

-).macrovector_stub, name, mode, correction=0(完成中断现场保护,CPU异常模式切换)

-) 根据进入中断前的工作模式不同,程序下一步将跳转到_irq_usr、或__irq_svc等位置

.long        __irq_usr                        @  0 (USR_26 / USR_32)

.long        __irq_invalid                        @  1 (FIQ_26 / FIQ_32)

.long        __irq_invalid                        @  2 (IRQ_26 / IRQ_32)

.long        __irq_svc                        @  3 (SVC_26 / SVC_32)

 

 ----》__irq_usr定义如下:

__irq_usr:

usr_entry

kuser_cmpxchg_check

irq_handler

get_thread_infotsk

mov        why,#0

b        ret_to_user_from_irq

 UNWIND(.fnend                )

ENDPROC(__irq_usr)

 

          -----》irq_handler定义如下:

.macro        irq_handler

#ifdefCONFIG_MULTI_IRQ_HANDLER

ldr        r1,=handle_arch_irq

mov        r0,sp

adr        lr,BSYM(9997f)

ldr        pc,[r1]

#else

arch_irq_handler_default

#endif

 

----》arm/include/asm/entry-macro-multi.S:6:@        .macro        arch_irq_handler_default:

.macro        arch_irq_handler_default

get_irqnr_preambler6, lr

1:        get_irqnr_and_base r0, r2, r6, lr

#get_irqnr_and_base函数完成获取IRQ中断号(irq number),依赖不同的soc的中断控制器

movne        r1,sp

@

@ routine calledwith r0 = irq number, r1 = struct pt_regs *

@

adrne        lr,BSYM(1b)

bne        asm_do_IRQ

 

/*get_irqnr_and_base实现是依赖具体的硬件的,对于pxa270 cpu,其实现如下:

.macro get_irqnr_and_base, irqnr, irqstat, base, tmp

mov /base,#io_p2v(0x40000000) @ IIR Ctl = 0x40d00000

add /base, /base,#0x00d00000

ldr /irqstat,[/base, #0] @ ICIP

ldr /irqnr,[/base, #4] @ ICMR

ands /irqstat,/irqstat, /irqnr

beq 1001f /* 没找到中断,跳转*/

rsb /irqnr,/irqstat, #0

and /irqstat,/irqstat, /irqnr

clz /irqnr,/irqstat

rsb /irqnr,/irqnr, #(31 - PXA_IRQ_SKIP)

#ifdefCONFIG_CPU_BULVERDE

b 1002f

#endif

1001:

1002:

.endm

.macroirq_prio_table

.endm

*/

 

接着---》asm_do_IRQ:-->handle_IRQ()------>执行request_irq()注册的中断。

 

补充,EINT 是共享一个IRQ,所以要到对应的IRQ handle里面,再处理不同的EINT handler,,如MTK

void mt_eint_registration(unsignedint eint_num, unsigned int flag,#eint注册到IRQ:MT_EINT_IRQ_ID

              void(EINT_FUNC_PTR) (void), unsigned int is_auto_umask)

{

。。。。。。

       EINT_FUNC.eint_func[eint_num] = EINT_FUNC_PTR;

       spin_unlock(&eint_lock);

       EINT_FUNC.eint_auto_umask[eint_num] = is_auto_umask;

       mt_eint_ack(eint_num);

 

mt_eint_isr(){

...

...        

if(EINT_FUNC.eint_func[index]) {

                   EINT_FUNC.eint_func[index] ();

 


关键字:ARM  中断向量表  响应流程 引用地址:ARM中断向量表与响应流程

上一篇:S3C2440之看门狗
下一篇:ARM异常、中断以及他们的向量表分析

推荐阅读最新更新时间:2024-03-16 16:04

康佳特全新SMARC模块,搭载基于ARM架构的NXP i.MX 8M Nano处理器
标准化与定制嵌入式计算机载板与模块的领先供应商德国康佳特推出新款SMARC 2.0计算机模块,搭载基于ARM Cortex-A53架构的NXP i.MX 8M Nano处理器。这款conga-SMX8-Nano处理器定义了SMARC标准的全新入门性能级别。借助超低功耗的图形处理能力和数量有限且严格筛选过的I/O,这款兼容NXP i.MX 8M Mini的NXP i.MX 8M Nano新处理器是针对以前未曾触及的低成本应用领域。采用它的移动掌上设备耗电功率不超过2瓦。工程师还可以借此将一个布满各种机械式按钮的复杂医用界面改造成一个简便直观的触控界面,或为工业设备安装一个互动式屏幕(这在此前花费甚高)。所有这些,甚至是采用了IEEE
[手机便携]
康佳特全新SMARC模块,搭载基于<font color='red'>ARM</font>架构的NXP i.MX 8M Nano处理器
ARM技术在智能电表上应用的论证与设计
引言: 随着国民经济的快速发展,电力已然成为国家最重要的能源。就民用电力来说,由于人民物质生活的极大丰富,生活质量迅速提高,对电力的需求也越来越大。但是,当前居民用电的管理过于落后,用电管理收费多年来一直采用先用电、后抄表、再付费的传统作业方式,电量值计算方面也无法实现更高的精确度,偏差较大。为了适应社会的需要,保证用户安全、合理、方便地用电,对传统的电表和用电的进行重新设计,使之符合社会发展的需要就显得很有必要。 1、智能电表的发展前景: 第一阶段 2000-2007 逐步以电子计量表取代传统机电式电表;在美国和欧洲着手推广单向通信网络; 第二阶段 2008-2012 全球范围内正在淘汰机电式电表;在欧美及中国大规模推广
[单片机]
<font color='red'>ARM</font>技术在智能电表上应用的论证与设计
ARM汇编中B跳转指令和LDR跳转的区别
B跳转指令是代码位置无关的,经过汇编后会替换为当前PC值加(减)一个修正值,不管这条指令是在哪一个地址执行,都能跳转到指定的位置。 B只能在当前PC的32M范围内跳转,LDR只能在当前PC的4KB(0xfff范围)跳转。 LDR PC,=xxx指令将向PC直接装载一个标号xxx的值,但标号经过编译后将被替换为一个与RO相对应的值,这样无论指令在何处执行都能跳转到一个指定的位置。 以AT91SAM9260 的启动代码片段为例,0x10000000为Flash基址,0x20000000为SDRAM基址: 其中ENTRY为起点,也就是说这条代码的偏移为0.设
[单片机]
ARM嵌入式系统中断向量表的动态配置
摘要:通常32位ARM嵌入式系统的中断向量表是在程序编译前设置好的,每次编写中断程序都要改C程序的汇编启动代码,相当繁琐。本文给出一种配置ARM中断向量表新方法。该方法比通常方法仅增加一条指令执行时间,简便高效,功能完备,向量表在运行时动态生成,C程序可以使用固定向量表的启动代码,并可隐藏起来。 关键词:动态配置 嵌入式系统 ARM 中断向量表 一般32位ARM嵌入式系统的中断向量表是程序编译前设置好的。在编写32位ARM嵌入式系统的中断服务程序、设置和修改ARM体系结构的中断向量表时,常感到相当麻烦,不得不修改汇编代码,对不喜欢使用汇编代码编程的程序员尤其如此。当需要在程序运行过程中动态修改中断向量的程序时会感到更为不便,
[应用]
测试ARM9的外部中断功能
/******************************************* * 文件名称:EINT.c * 实现功能:测试外部中断的操作 * 作者:jianqi * 版本:1.0 **********************************************/ #include 2440addr.h //包含2440相关寄存器的设置 #include def.h #define LED1 5 #define LED2 6 #define LED3 7 #define LED4 8 #define KEY1 1 #define KEY2 4 #def
[单片机]
高通反诉ARM:以诉讼作为谈判筹码 违反协议是无稽之谈
据报道,高通公司在10月27日反诉ARM称,ARM之前指控高通违反授权协议和商标并无合法依据。    法庭文件显示,高通希望特拉华州的联邦法官认定,作为高通以14亿美元收购芯片初创公司Nuvia的一部分,该公司并未违反ARM的许可合同。    双方争论的焦点集中在ARM与Nuvia之间的芯片设计授权。上个月,ARM对高通和Nuvia发起诉讼,指控这两家公司违反与ARM签订的授权许可协议。Nuvia是高通去年以14亿美元收购的初创公司,主要设计基于Arm技术的芯片。 ARM要求高通销毁根据Nuvia与Arm许可协议而开发的设计。ARM还称,即使经过数月的谈判,高通也没有获得这一许可。而且,高通还在未经许可的情况下,将Nuvia的
[半导体设计/制造]
Arm®v7-M 架构的 STM32 如何启用 DWT进行计数
01 前言 客户在使用 STM32H7 的时候,想要使用 DWT 计数来测量代码执行时间,评估执行效率。客户发现在重新上电或 reset 后,无法启用 DWT 进行计数。 02 调研 在 ARMv7-M 架构中有个 DEMCR 寄存器,这个寄存器可以控制 DWT 的使能。在power-on reset 后这个寄存器所有位的值都为 0。而当 bit 为 0 时,DWT 和 ITM 模块都是 disabled 的。所以为了启用 DWT 模块,必须将 DEMCR 的 bit 置为 1。如图 1 所示: 图1.DEMCR 寄存器 03 启用 DWT 进行计数 STM32H7 基于 Arm Cortex-M7 内核
[单片机]
<font color='red'>Arm</font>®v7-M 架构的 STM32 如何启用 DWT进行计数
Nordic Semiconductor 与 Arm 扩展合作关系
签署最新低功耗处理器设计、软件平台和安全 IP 许可协议 Nordic签署 Arm Total Access 授权许可协议,确保其现有和未来的多协议、Wi-Fi、蜂窝物联网和DECT NR+ 产品具备业界领先的处理器和安全技术 挪威奥斯陆 – 2024年2月20日 – Nordic Semiconductor宣布与世界领先的半导体设计和软件平台企业Arm签署一项多年期Arm Total Access (ATA)授权许可协议 。ATA 保证为Nordic当前和未来的产品 (包括多协议、Wi-Fi、蜂窝物联网和 DECT NR+ 解决方案) 提供广泛的Arm® IP、工具、支持和培训。 两家企业的合作始于 2012
[物联网]
Nordic Semiconductor 与 <font color='red'>Arm</font> 扩展合作关系
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved