Cortex-M架构MCU重定位向量表

浏览:948来源:本站时间:2020-10-23

Cortex-M架构使用了“向量表查表机制”,当异常发生时,内核会自动从向量表查找出Handler的入口地址。向量表其实是一个 WORD(32 位整数)数组,每个下标对应一种异常,该下标元素的值则是该异常 handler的入口地址。

向量表在地址空间中的位置是可以设置的,通过SCB中的VTOR寄存器来指出向量表的地址。在复位后,该寄存器的值为0。因此,在地址0处必须包含一张向量表,用于初始时的异常分配。但在系统运行之后我们可以通过修改VTOR寄存器重定位向量表到其他地址,可以是Flash区域,也可以是RAM区域。但必须注意向量表的起始地址的要求:必须先求出系统中共有多少个向量,再把这个数字向上增大到是 2 的整次幂,而起始地址必须对齐到后者的边界上。例如,如果一共有68个中断,则共有 68+16(系统异常)= 84 个向量,向上增大到 2 的整次幂后值为 128,因此地址必须能被 128*4=512 整除。

本文以IAR EWARM开发环境为例,将STM32F107的向量表重定位到SRAM的起始地址。EWARM要求默认的向量表要命名为“__vector_table”,以便它的调试系统能够正确识别出向量表,并且放置在Flash的零地址。

然后,在SRAM也定义一个向量表,这个表的命名可以任意,这里命名为“sram_vector_table”。在系统初始化之后,将__vector_table里面的内容复制到sram_vector_table,实现新的向量表构建。因为要控制向量表的存放位置,所以通过#pragma预处理指令将向量表放置在一个自定义的section中,命名为“.vector”。“__root”关键字强制编译器保留向量表,不进行任何优化操作。

#define VECTOR_LEN       84UL

#pragma location = ".vector"

__root  uint32_t

sram_vector_table[VECTOR_LEN];  /* Vector table in sram */

然后在IAR链接器脚本icf文件中,控制.vector的存放位置,将其放置在SRAM的起始位置:

place at start of RAM_region { section .vector };

在代码中适当的位置对sram_vector_table进行构建:


在进行重定位向量表时应该先关闭全局中断,避免过程中发生中断造成不可预料的情况发生。SRAM_BASE是RAM的起始地址0x20000000,VECT_TAB_OFFSET为0。

重新设置了VTOR之后,再次开启全局中断,至此中断向量表完成了重定位。


京ICP备:京ICP备05011254号-1 版权归北京麦克泰软件技术有限公司所有
北京麦克泰软件技术有限公司