搜索
查看: 735|回复: 0

[原创] 技术小课堂| Cortex-M架构MCU重定位向量表

[复制链接]

该用户从未签到

39

主题

173

帖子

2

蝴蝶豆

金牌会员

最后登录
2021-3-29
发表于 2020-10-23 13:37:50 | 显示全部楼层 |阅读模式

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进行构建:

1.png

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

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

2.png
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-4-24 06:07 , Processed in 1.162035 second(s), 32 queries .

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表