在SRAM中运行代码#
以STM32为例进行说明。
- 将代码下载到SRAM中(代码中需配置VTOR)
- 设置SP和PC指针
- 运行代码
1. 将所有代码放进SRAM并运行#
通常我们会使用调试器将程序直接下载到SRAM中,然后依靠调试器的初始化文件配置栈指针、PC指针和中断向量表偏移地址,从而实现在SRAM中运行代码。
一个简单的补救方法是:直接在Keil中手动修改SP和PC指针。
1.1 那么为什么需要从SRAM启动#
可能的原因有以下几点(参考资料《ARM Cortex M3 & M4权威指南》15.7节 下载地址):
-
所使用的设备可能具有OTP ROM(仅可进行一次编程),因此在最终确定前,是不会将程序编程到芯片中的。
-
有些微控制器中没有内部Flash存储器,需要使用外部的存储器,在软件开发期间,可能会想用内部的SRAM进行测试。
-
对于产品测试或者特定方面的测试,不想改动Flash中现有的程序实现某些新功能的测试工作,此时可以将测试代码下载到SRAM中运行。
-
对于Flash存储器比较小的系统,可能想在启动阶段将程序从Flash复制到SRAM中以提高性能,并在SRAM中执行程序以达到最佳性能。
1.2 配置方法#
1.2.1#
采用上述方法,无论STM32的启动模式是从Flash启动还是从SRAM启动,代码均可以在SRAM中运行,但是程序复位后不能重新运行。因为我们在调试器初始化文件中配置的栈指针、PC指针和中断向量表偏移地址只有在启动调试的时候才会执行配置。
1.2.2 设置中断向量表偏移#
添加宏定义 VECT_TAB_SRAM :
该宏定义影响的代码:
// system_stm32f10x.c
// SystemInit()
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
1.2.1 修改链接脚本#
按照下图所示方式,即可在Keil编辑器中打开链接脚本:
打开链接脚本文件后,将内容修改如下:
; 以STM32F103C8T6为例
; 从SRAM启动终端向量表(RESET段)必须位于启动空间的0地址
; InRoot$$Sections 必须位于root区域(执行地址与装载地址相同的区域)
LR_IROM1 0x20000000 0x00005000 { ;装载地址为SRAM首地址
RW_IRAM1 0x20000000 0x00005000 { ;执行地址==装载地址
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
.ANY (+RW +ZI)
}
}
1.2.2 配置栈指针、PC指针和中断向量表偏移#
编写调试器初始化文件RAM.ini,其内容如下:
SP = _RDWORD(0x20000000); // 设置栈指针
PC = _RDWORD(0x20000004); // 设置PC指针
_WDWORD(0xE000ED08, 0x20000000); // 设置中断向量表偏移
按照下图所示方式将该初始化文件配置到Keil中:
1.2.3 修改Keil中的Flash Download设置#
因为是直接从SRAM启动并执行程序,不需要对Flash进行操作,所以把Flash相关操作全部去掉。
以上就是完整的配置,现在编译项目并点击调试,就能看到程序成功在SRAM中运行了。
2. 将指定的代码放到SRAM运行#
http://emb.hqyj.com/Column/20198162.html