首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ARM Cortex-M3中断跳转过程

ARM Cortex-M3中断跳转过程

在学习CM3的时候,仔细学习了CM3的中断跳转过程,发现嵌入式的MCU在这一块基本上是一样的,当然不同架构的MCU也有自己的特性。
我来介绍下CM3的中断跳转过程,首先假设中断发生,CM3内核开始响应中断,由于不同厂家的CM3可能略有区别,但CM3的内核肯定是一样的,所以我们在这个前提下开始讨论,暂时把中断屏蔽位,标志位之类的东西放在一边。
现在介绍中断响应的过程:
1、压栈。从这一点来讲几乎所有的处理器都是一样的,用压栈保护现场。压入哪些寄存器呢,又是怎样一个顺序?如果就大多数的C语音编程来讲,这个不是很关心的内容。但是CM3的压栈寄存器特点,让我们来见识下ARM设计的特点。其压栈顺序如下图所示,请注意压栈的地址顺序和时间顺序不是相同的。

  地址(SP

  
  寄存器

  
  被保护顺序(时间顺序)

  
  N-0
  
  之前已压栈内容

  
  

  
  N-4
  
  xPSR
  
  2
  
  N-8
  
  PC
  
  1
  
  N-12
  
  LR
  
  8
  
  N-16
  
  R12
  
  7
  
  N-20
  
  R3
  
  6
  
  N-24
  
  R2
  
  5
  
  N-28
  
  R1
  
  4
  
  N-32
  
  R0
  
  3
  
这一点就我们普通coding来讲,是非常奇特的,堆栈的空间顺利和进栈时间没有必然联系,跟我们“后进先出”的观点有很大出入,那么显然这里的“堆栈”,并不是我们传统意义的上的堆栈,具体怎样实现ARM没有详述,只是说他们可以做到这点。

我们可以看到PCxPSRR0R1R2R3是率先入栈的(时间上),这样做的目的,是为了编译器优先使用入栈了的寄存器来保存中间结果(如果程序过大也可能要用到R4-R11,此时编译器负责生成代码来push它们)。这也是要求ISR尽量短小的原因,用更少的寄存器,以加快响应。

2、查找中断向量表。其实这一步跟第一步是并行的,只是为了分别介绍我,列了序号。ARM是有D-Code(数据总线)和I-Code(指令总线),两条总线。可以看到PC是第一个压栈的,此时数据总线正忙于压栈操作,与此同时指令总线就可以查找中断向量表,查询中断服务程序的入口地址。在CM3中中断向量表位于地址从0x00000000开始的一段存储空间,每个表项占一个字(4byte)。这是中断向量表没有重定位的情况,当然中断向量表也可以重定位,即存储在其他地方。这个需要设置相应的寄存器,我个人认为还是让其固定在这个默认的位置比较好,以免出现以外情况。在看中断向量表的时候我遇到了一个很有意思的问题:

中断服务函数的入口地址为0x67C(图1所示),但是中断向量表中存储的地址确是0x67D(图2所示),竟然加了1

    这让我纠结了很久,后来一位整ARM7的大牛解答了我的问题。ARMPC最低位是0的时候ARM会进入ARM模式,但是最低位是1的时候会进入thumb模式。而我们的CM只支持thumb模式,所以PC最低位必须为1。而且thumb指令集是16位的,所以0x67D就是指向0x67C所存储的指令,但是减一就不行了,就变成了指令空间内上一个地址存储的指令。

CM3中断跳转过程写出来跟大家分享,若有不妥之处,望大家斧正。

图1 方框内为所对应中断服务函数入口地

图2 方框内为中断向量表中中断服务函数入口地址
继承事业,薪火相传
返回列表