S3C6410 中断向量表

默认分类 | 2015-08-15 17:18:38 | 2225次阅读 | 0评

第一步就是进行中断向量表的设置。在ARM11中,中断向量表叫做异常向量表。            ARM11共有10种异常,这个在ARM11datasheet中有。file:///root/%E6%A1%8C%E9%9D%A2/interupt.png

这里说明一下:

异常

说明

详细说明

Reset

复位异常

当系统刚上电,或者按下复位键时候,触发这个异常,这个时候,程序跳转到这个地址处执行程序

undefined_instruction

未定义指令异常

当程序执行发现有一条指令是未定义的指令,会触发这个异常,这个时候,程序跳转到这个地址处执行程序

software_interrupt

软中断异常

当软件设置软中断时,会触发这个异常,这个时候,程序跳转到这个地址处执行程序

prefetch_abort

取指异常

CPU取指令发生问题时,会触发这个异常,这个时候,程序跳转到这个地址处执行程序

data_abort

数据异常

这个就包括内部取数据和外部取数据,当取数据发生问题时,会触发这个异常,这个时候,程序跳转到这个地址处执行程序

irq

中断异常

当有中断触发后,会触发这个异常,这个时候,程序会跳转到这个地址出执行程序

fiq

快中断异常

当快中断触发后,会触发这个异常,这个时候,程序会跳转到这个地址出执行程序


 最后一个目前不知道是什么意思。现在也用不上,先就不管了。

 异常,也都写得比较清楚,都知道这些异常大致是干什么的。这里,要注意,异常发生的时候,是跳转到异常地址去执行程序的,但是每个异常地址的大小是4个字节,4个字节大小肯定是放不下程序的。所以,肯定会有第二级跳转。所以这个异常地址的指令,就是一个跳转指令,跳转到对应的程序去执行。

 这些异常,现在不用清楚这些异常怎么用,用的时候再来学习就可以了。只要知道有这么些异常就可以了。

 这些异常的地址是固定的,这个和STM32是不一样的。所以,我们设置中断向量表的时候,要将这些异常写在固定的地址上。这样,程序才能正常访问这些异常。


异常

地址

Reset

0x0000_0000

undefined_instruction

0x0000_0004

software_interrupt

0x0000_0008

prefetch_abort

0x0000_000c

data_abort

0x0000_0010

irq

0x0000_0018

fiq

0x0000_001c

从表中,会发现,数据异常和中断异常之间怎么相隔了8个字节大小,其他都是相隔的4个字节大小。这里是保留了一个异常,但是目前没有定义这个异常是什么,所以把地址给空出来了。所以,我们写程序的时候,要注意把这个地址给空出来。



下面就是我们的程序:


.text
.global _start
_start:
    b reset
    ldr  pc, _undefined_instructions
    ldr  pc, _software_interrupt
    ldr  pc, _prefetch_abort
    ldr  pc, _data_abort
    ldr  pc, _no_use
    ldr  pc, _irq
    ldr  pc, _fiq
_undefined_instructions:
    .word undefined_instructions
_software_interrupt:
    .word software_interrupt
_prefetch_abort:
    .word prefetch_abort
_data_abort:
    .word data_abort
_no_use:
    .word no_use
_irq:
    .word irq
_fiq:
    .word fiq
   
undefined_instructions:
    nop
software_interrupt:
    nop
prefetch_abort:
    nop 
data_abort:
    nop
no_use:
    nop 
irq:
    nop 
fiq:
    nop
reset:


简单说明下

.text :  表示是代码段,说明下面的程序是代码

.global _start : 定义全局标号_start

_start的代码,就是设置中断向量表了。可以看出,其实都是跳转指令。不同的异常,跳转到不同的地方去执行程序,这样就实现了异常的处理。

这里

                         ldr  pc, _undefined_instructions     1

_undefined_instructions:           

    .word undefined_instructions

undefined_instructions:

    nop


  1的指令,就是将标号_undefined_instructions地址处的值赋值给pc这样pc的值就是undefined_instructions的值,所以就跳转到undefined_instructions程序地方去执行。这里,undefined_instructions程序就只有一个nop指令。因为目前没有用到这些异常,所以这里,除了Reset异常我们是编写代码外,其他的异常我们都是写的nop

  其他异常的分析,和以上的分析是一样的。只是要注意,我们中间定义了一个_no_use异常。可是这个异常是ARM异常里面没有的。这里定义这个异常,就是为了占一个字节大小,这样的话,irq的地址才会是0x0000_0018,否则的话就是0x0000_0014,这样就不对了。

   这里有个问题,只有Reset的跳转指令是b指令,其他的指令都是ldr指令。这个是为什么了?

   b指令是相对跳转指令,ldr是绝对跳转指令。在上电或者复位的时候,程序在内部的stepping stone中执行,地址从0x0000_0000开始。但是我们在编译代码的时候,用的链接脚本的链接地址是0x5000_0000,如果使用ldr决定跳转指令的话,就会跳到内存去执行程序了,这个时候,我们还没有把程序拷贝到内存中,所以执行就会出错了,所以这里使用b指令。复位结束后,我们已经把代码拷贝到内存中去了,所以这个时候,就要用ldr绝对跳转指令了。

   以上,就将我们的异常向量表就设置好了,接下来,我们就对Reset函数编写代码就好了。因为这里写的代码,就是上电执行的代码。

原文来自:http://comm.chinaaet.com/adi/blogdetail/39909.html


博友评论,共0条
浏览66046次
最新评论