datasheet

ARM中断向量表的简单分析

2019-04-26来源: eefocus关键字:ARM  中断向量表  简单分析

一般编写arm的裸机程序的时候,创建中断向量表就把它放在0x00000000~0x0000001c中,一般都放在这个位置上。但是中断向量表也可以放在0xffff0000~0xffff001c中,知道这是怎么设置的么?开始看到的时候真的有点奇怪,因为在学习arm的时候,根本没去看arm中的协处理器CP15中的c1控制寄存器中的v位来控制,我们一般都使用默认的值0,则必须将中断向量表放在0x00000000~0x0000001c中。 


在看Linux内核对arm中的中断的初始化的时候,就一直对0xffff0000的地址有点怀疑,果然在网上发现这个地址不是随便写的,当我看到arm的协处理器进行控制,中断向量表的地址的时候,真的是哭笑不得啊!! 


有人肯定会问?v位是什么时候设置的呢?其实仔细的朋友就知道在head.S中,在创建完页表的时候,如add pc,r10,#PROCINFO_INITFUNC 


别急,r10保存在前面设置的procinfo的地址,但是很多人就觉得PROCINFO_INITFUNC的宏定义就不知道在哪找了,在include/asm/asm-offset.h中有定义。 


这些搞懂了,首先必须将中断向量表拷贝到0xffff0000的地址上去,把中断处理函数也拷贝到0xffff0200的地址上去,那么在中断向量表进行跳转的时候,如b vector_irq+stubs_offset,但是stubs_offset的偏移怎么设置呢?如果用b vector_irq的话,它就会跳转到原先的中断处理函数中去,因为它也拷贝到了0xffff0200的地址上去,所以将__vector_start-_stubs_start+0x200的话就转移到拷贝后的地址上去执行了。 


很多人应该会有点疑问吧,vector_irq好像找不到,别急,细心点,就在宏定义.macro vector_stubs,name,mode,correction中对各种处理函数有定义,所以很快就将中断向量表创建好了。


Linux Version : 2.6.29

1. start_kernel-->setup_arch-->early_trap_init

   1:  

    memcpy((void

 *)vectors, __vectors_start, __vectors_end - __vectors_start);

   2:  

    memcpy((void

 *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);

   3:  

    memcpy((void

 *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);



对于第一行: 

__vectors_start 和 __vectors_end 定义在 arch/arm/kernel/entry-armv.S , 它们之间保存了中断向量表。


   1:  

    .globl    __vectors_start

   2:  

__vectors_start:

   3:  

    swi    SYS_ERROR0   

   4:  

    b    vector_und + stubs_offset

   5:  

    ldr    pc, .LCvswi + stubs_offset

   6:  

    b    vector_pabt + stubs_offset

   7:  

    b    vector_dabt + stubs_offset

   8:  

    b    vector_addrexcptn + stubs_offset

   9:  

    b    vector_irq + stubs_offset

  10:  

    b    vector_fiq + stubs_offset

  11:  


  12:  

    .globl    __vectors_end

  13:  

__vectors_end:


vectors 的地址为CONFIG_VECTORS_BASE , 在.config中定义为0xffff0000 

所以 第1行就是把中断向量表拷贝到0xffff0000 

对于第二行: 

vector_stub是一个带参数的宏,第一个是name,第二个是arm excepiton mode,第三个是为了得到返回地址,lr需要减去的偏移


  1:  

    .macro    vector_stub, name, mode, correction=0

   2:  

    .align    5

   3:  


   4:  

vector_/name:

   5:  

    .if

 /correction

   6:  

    sub    lr, lr, #/correction          @得到正确的返回地址

   7:  

    .endif

   8:  


   9:  

    @

  10:  

    @ Save r0, lr_

  11:  

    @ (parent CPSR)

  12:  

    @

  13:  

    stmia    sp, {r0, lr}        @ save r0, lr

  14:  

    mrs    lr, spsr

  15:  

    str    lr, [sp, #8]        @ save spsr

  16:  


  17:  

    @

  18:  

    @ Prepare for

 SVC32 mode.  IRQs remain disabled.

  19:  

    @ 

  20:  

    mrs    r0, cpsr

  21:  

    eor    r0, r0, #(/mode ^ SVC_MODE) @把cpsr内容与(mode^SVC_mode)异或,即r0里为SVC_MODE      

  22:  

    msr    spsr_cxsf, r0  @把r0的值写入整个spsr寄存器(cxsf表示要往哪个字节写入)

  23:  


  24:  

    @

  25:  

    @ the branch table must immediately follow this

 code

  26:  

    @

  27:  

    and    lr, lr, #0x0f  @lr为spsr_

  28:  

    mov    r0, sp         @ 

  29:  

    ldr    lr, [pc, lr, lsl #2] @lr=pc+mode*4,其中pc为紧接着30的指令,即vector_stub后的第一条指令

  30:  

    movs    pc, lr            @ movs会把spsr的值赋给cpsr,所以branch to handler in

 SVC mode

  31:  

ENDPROC(vector_/name)

  32:  

    .endm


再来看下vector 跳转表


   1:  

    .long

    __irq_usr            @  0  (USR_26 / USR_32)

   2:  

    .long

    __irq_invalid            @  1  (FIQ_26 / FIQ_32)

   3:  

    .long

    __irq_invalid            @  2  (IRQ_26 / IRQ_32)

   4:  

    .long

    __irq_svc            @  3  (SVC_26 / SVC_32)

   5:  

    .long

    __irq_invalid            @  4

   6:  

    .long

    __irq_invalid            @  5

   7:  

    .long

    __irq_invalid            @  6

   8:  

    .long

    __irq_invalid            @  7

   9:  

    .long

    __irq_invalid            @  8

  10:  

    .long

    __irq_invalid            @  9

  11:  

    .long

    __irq_invalid            @  a

  12:  

    .long

    __irq_invalid            @  b

  13:  

    .long

    __irq_invalid            @  c

  14:  

    .long

    __irq_invalid            @  d

  15:  

    .long

    __irq_invalid            @  e

  16:  

    .long

    __irq_invalid            @  f


这里只有usr 和svc 有入口,而其他都是invalid ,是因为linux只会从usr(application) 和svc(kernel)两种mode跳转到exception来 

__stubs_start 和 __stubs_end 之间的代码简化后为:


   1:  

__stubs_start:

   2:  

   vector_irq:    @vector_stub    irq, IRQ_MODE, 4

   3:  

   vector_dabt:   @vector_stub    dabt, ABT_MODE, 8

   4:  

   vector_pabt:   @vector_stub    pabt, ABT_MODE, 4

   5:  

   vector_und:    @vector_stub    und, UND_MODE

   6:  

   vector_fiq:

   7:  

   vector_addrexcptn:

   8:  

   .LCvswi:

   9:  

__stubs_end:


由此可以知道 __stubs_start 和 __stubs_end 之间定义了各种异常的入口 

我们再来看为什么异常入口是“b vector_und + stubs_offset”, 同时为什么stubs_offset 的定义如下 

.equ stubs_offset, __vectors_start + 0x200 - __stubs_start 

arm 的跳转指令b 是跳转到相对于PC的一个偏移地址( offset ),汇编器在编译时会对label 减去PC 得到offset,同时vector 拷贝后是如下排列的


__vectors_start




B vector_




__vectors_end



+0x200

__stubs_start




vector_




__stubs_end


因此,”b vector_” 的label –PC = offset, 而offset 为 b 指令与vector的offset,即


                         vector_

                       = vector_

1

2

所以异常入口为“b vector_und + stubs_offset”, 同时stubs_offset= __vectors_start + 0x200 – __stubs_start 

我们可以通过objdump反汇编来验证:


00000060

    .globl    __stubs_start 

__stubs_start: 

/* 

* Interrupt

[1] [2] [3] [4] [5] [6]

关键字:ARM  中断向量表  简单分析

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/ic459913.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:2440裸板程序之时钟初始化
下一篇:2440裸板程序之inline关键字

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

借助周易平台,Arm中国打通AIoT落地的最后一公里

在2018年第五届世界互联网大会上,Arm中国全新人工智能平台“周易”首次公开亮相,并获得第五届世界互联网大会“世界互联网领先科技成果”。半年时间过去,客户对周易平台有了进一步了解,无论IP还是软件框架都获得了厂商的认可。在此前提下,近日,Arm中国生态发展副总裁、OPEN AI LAB创始人兼CEO金勇斌及Arm中国产品经理高锦炜解读了周易平台的更多细节。金勇斌介绍道,周易平台是Arm中国自主开发的平台,包括人工智能处理器AIPU以及AIPU SDK,以及和中国生态合作伙伴共同开发的Tengine人工智能软件框架,适配Arm CPU、Mali GPU和第三方AI处理单元,实现人工智能算力优化。“由于是Arm中国自主开发的产品
发表于 2019-05-20
借助周易平台,Arm中国打通AIoT落地的最后一公里

arm力天电子 lpc2148流水灯驱动程序详解

一个破流水灯程序看了两天了,void WriteByte(unsigned char data)这部分还是没看懂,力天电子上面介绍说这部分三端口的数据输入,选出8位的串行数据。选择16,17,18,19四个控制位,主要跟电路图的连接有关,4块74HC595,组成32位(如图所示),从下往上依次是0~31为,图中写反了。因此到D13对应的引脚应该是16,D12对应的是17,D11对应的是18,D10对应的是19. 当16,17,18,19分别为低电平时二极管才能够导通发光。高电平时熄灭1#include <NXP/iolpc2148.h>2#define         S
发表于 2019-05-20
arm力天电子 lpc2148流水灯驱动程序详解

arm力天电子 lpc2148 基于DS18b20的温度采集实验程序详解

1#include <NXP/iolpc2148.h>2#include <stdio.h>3#include "uart.h"//系统时钟4#define Fosc        12000000UL        //晶振时钟 【Hz】5#define Fcclk       (Fosc * 5)        //系统频率,必须为Fosc的整数倍(1~32),且<=60MHZ6#define Fcco  &nb
发表于 2019-05-20
arm力天电子 lpc2148 基于DS18b20的温度采集实验程序详解

arm力天电子 lpc2148 无字库的12864显示一个汉字(串行)

力天电子lpc2148开发板中配的12864小屏是不带字库的,并且没有所谓的左右屏,上下屏之分,是一个整屏.(是北京集粹电子设备有限公司生产的,资料详见http://download.csdn.net/detail/yueniaoshi/4507741 此资料介绍的芯片的相关东西http://download.csdn.net/detail/yueniaoshi/4507754 此资料介绍的是驱动函数http://download.csdn.net/detail/yueniaoshi/4507775 此资料介绍的是小小日历钟,这个里面的函数更全一点)(再说点题外话,当初买板子的时候老板服务很周到,也很热心,问什么说什么!可是一旦板子
发表于 2019-05-20
arm力天电子 lpc2148 无字库的12864显示一个汉字(串行)

arm 力天电子lpc2148无字库12864显示一行多个汉字(串行)

力天电子lpc2148开发板中配的12864小屏是不带字库的,并且没有所谓的左右屏,上下屏之分,是一个整屏.(是北京集粹电子设备有限公司生产的,资料详见http://download.csdn.net/detail/yueniaoshi/4508801 此资料是12864的数据手册http://download.csdn.net/detail/yueniaoshi/4507741 此资料介绍的12864的更进一步介绍http://download.csdn.net/detail/yueniaoshi/4507754 此资料介绍的是驱动函数http://download.csdn.net/detail/yueniaoshi/45077
发表于 2019-05-20
arm 力天电子lpc2148无字库12864显示一行多个汉字(串行)

arm 力天电子lpc2148无字库12864显示多行多个汉字(串行)

跟上一篇的显示一行多个汉字差不多,只是多加了几行代码(彩色部分)和字模#include <NXP/iolpc2148.h>//管脚宏定义#define  SCLK 0x01<<24  //595时钟端#define  MISO 0x01<<5   //数据输入端#define  MOSI 0x01<<6   //数据输出端#define  RCK  0x01<<7   //SO12864时钟输入端//LCD Define #define LCD_
发表于 2019-05-20
arm 力天电子lpc2148无字库12864显示多行多个汉字(串行)

小广播

何立民专栏

单片机及嵌入式宝典

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

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