如何在keil ram 运行中设置 函数在ram中运行

还没有帐号? 赶紧
用户版块帖子
STM32:将运行代码装入RAM中运行问题和实现
UID:1023450
在线时间2019小时
M币1036专家49
&&发表于: 10-31
将STM32运行代码将装入RAM中运行,至今没有完整而详细文档和实现代码,我在完善maple、hal 构架的STM32 ARDUINO过程中,根据点滴零碎和有限资料,终于弄明白的其中的奥妙,现在把关键部分在此向坛友作个介绍。 问题一、为何要将运行代码装入STM32的RAM中运行?A:&&STM32代码在RAM中运行比在flash(rom)中运行的速度更快(带有ICACHE/DCATHE的芯片如F4系列除外)(技术贴:GD32F103&&vs STM3 性能测试比较 ),说明: GD32 ram运行反而比flash运行要慢,以下只对STM32F1系列来说。我的测试显示:&&&&内存变量运算10000次加法:&&&&&&&&&&&&&&&&&&&&&&&&&&&&stm32f103vct6&&72M&&ram 1112us&& flash 1251us B: 偶尔用一下代码,如果装入flash,用后不擦写干净则将永久占据这个空间,而擦写则磨损flash缩短使用寿命,如果对付很多不确定却频繁这样操作显然对芯片是个考验,而ram则不同,要用那个功能就装入那个功能的代码,ram可反复读写而不影响寿命。如我们调试一段程序,需要反复改,有些需要反复试,显然每次将其放入ram运行是个好主意; C:&&留给ST自己检测用和自家(包括合作大用户)的产品上用(猜测)。&& 猜想 a: ST公司在芯片检测时,大部分的检测代码全部是放在ram中运行的,早期的mcu包括arm芯片的擦写次数并不多,如刚推出的LM系列,有报道极端的情形 有玩家数十次甚至数次擦写就死翘翘了;我想ST公司的产品也是如此,早期的手册上的寿命才写1000次,如果几十道工序对每个作个检查,这种一次性行为都写到flash中运行代码,既不必要,也不经济(降低了产品率);&&&&猜想b:为了自家产品不被轻易的仿制,代码不会轻易的被人取得,不要看现在的stm32 已经有了很多保护功能,早期可没有这么多,这方面都说清楚了,给人就多了些手段,因为我们从那些开源的调试器可见,通过JTAG(SWD)可以向mcu发出写到某个地址的某个数据,芯片内部的bootloader也能接收这样的指令如写 某个地址指定的数据和go某个地址(ram)运行;须知那个时候玩arm的都是高大上,要买个调试器是很贵的!如果手册说得太清楚了,自有聪明好事的把它开源了,这是st和那些合作的大用户不愿看到的。 问题二、STM32能运行RAM中的代码吗?这显然不是问题,我们在keil中已经这样在ram中调试了,stm32也支持在ram中运行代码,这是ST手册关于启动的: 它告诉我们,boot1/boot0 开机电平的高低决定了mcu从那里开始执行程序:00/10&& 就是我们通常写的代码,放在flash的开头处,对于stm32,这个地址所有stm32 mcu都是相同的:0x;01&& 就是我们就是从stm32的系统flash开始执行代码,这里st为我们烧了个bootloader的固件,对stm32f1 支持usb烧写和串口烧写,这就是通常所说的在系统编程 isp;而该地址不同产品线的mcu是不同的,其中stm32f1xxxx 是&&0x1FFFF000~0x1FFFF800;11&& 这个启动模式是我们要关注的,就是从内部ram运行代码;内部ram地址是: 0x;对于上述表3中列举的三种启动方式,下面的说明还向我们表明了:A&&对应到各种启动模式的不同物理地址将被映像到第0块(启动存储区);B&&即使被映像到启动存储区,仍然可以在它原先的存储器空间内访问相关的存储器。C&&CPU从位于h开始的启动存储区执行代码。
上述三个说明,让我脑洞大开,先用我们通俗一点的不是太专业的深刻理解一下:A&&就是说,如果是00/10 用户内存存储器启动模式,flash地址0x开始只读存储器 映射到了0x地址开始,而11内部SRAM启动则0x开始的SRAM映射到了0x地址开始。B 在00/01启动模式下,仍可读写执行0x08xxxxxx中的数据和代码, 并和读写执行0x00xxxxxx是一回事;在11启动模式下,仍可读写执行0x20xxxxxx 并和读写执行0x00xxxxxx是一回事;也就是说:在keil中,以xET6为例:图 2和 图3 编译连接的运行是一样的(ram运行类似); C 总是从0x启动,只不过,如果flash启动,则也可从0x开始;而SRAM启动,则也可从0x开始运行;(以上所说的启动地址是指中断矢量表开始地址,实际第一个pc地址是表中系统复位矢量RESET所指向的位置) 好奇,问题三,为何我们找不到一个例子把IROM开始地址直接写成0x?这样能准确的连接和运行吗?回答是肯定的,因为我们一试就知道了; 问题四:这样做存在什么问题及限制?这就是官方没有提供这样做例子的原因,也就是我没有看到有人这样做的原因:A&&烧写文件如果是带地址的如.hex和.dfu;,这个文件烧写时开头地址变成了0,当不在运行模式,0地址开始既没有flahs也没有sram,无法烧入;但我们知道,还有个 .bin格式的二进制文件,可以在使用stlink或jlink烧写时指定地址,选0x(flash运行)还是 0x(ram运行) ; 问题五:现在我们回到ram运行问题,代码放入ram有什么限制和不足?这到是简单了:A&&显然,ram是易失性,刚上电时,里面本没有东西,即使是我们可以用stlink或jlink将代码装入,但每次要运行,先用slink或jlink装入,麻烦一点;B&&RAM容量远小于flash,代码用用掉一些,剩下能放数据的也就少了,因此装入一些小程序,或对部件一个一个调试。C 对于AB,如 F103ZET6的有些板子,还外扩了512k或1024k外部Sram;而F4、sram有64k、 128k、196k,F746 有320k,即使是大程序都可以调试;至于装入,看红牛等板子的例子,可以用个小程序(我将它称为用户化bootloader),我们可以从nand/nor/spiflash甚至sd卡上装入并运行; 问题六:还有个问题,为什么至今ST公司都在mcu上保留了问题二中的 11模式(ram)运行?许多博客、资料总是重复了手册上的一句话,sram启动,就没有下文了,还有吐槽一下:ST给我们一个没有用的鸡肋,这没有用;许多板子干脆把boot1直接接地了。boot1 直接接地,我们仍可以从ram中执行代码,撇开用户自己的bootloader装入并跳转外,我们直接用jlink、stlink在调试时是可以设定栈地址、pc地址和跳转的,从这个角度看确实看是没有用的;但我就弄不明白:那么为什么至今ST公司都在mcu上保留了sram启动运行模式?使用这个模式一定可以达到通常做不到的事! 下面是我的第一个应用: 问题七:我们能否做成个执行代码,即可用于flash烧写或直接运行,也可装入sram临时用一下?先说结果:可以生产这样的二进制执行文件:即可烧入flash运行,也可装入SRAM临时用一下!先看一下官方示例 Sram运行设置: 这个设置将xET6 64kSram分成两个部分,A&&&&&&&& 0x开始长度为0x8000(32k)为代码IROM1,剩下的0x 长度为0x8000(32k)为数据段IRAM1;这是官方及大家都这样用的配置,因为SRAM是绝对地址,因此无论在00/10 模式,都是能正确运行的;也能做成hex文件装入sram,因为地址正确;这个物理地址的代码是不能直接烧入flash运行的,0x开始长度为0x8000(32k)指向sram,而实际放在flash地址错误。如果改成: B&&&&&&&&0x开始长度为0x8000(32k)为代码IROM1,剩下的0x 长度为0x8000(32k)为数据段IRAM1;这是我的试验,在11模式启动时,SRAM映射地址,在SRAM模式启动运行也是正确的;C&&B模式的代码显然也不能烧入flash运行,因为:当flash映射时,地址0x 长度为0x8000(32k)为数据段IRAM1,这显然是错误的,因为这区域不可写!D 我们将地址改为: 即 将A中的代码段IROM1地址改变,而数据段IRAM1不变:&&0x开始长度为0x8000(32k)为代码IROM1,0x 长度为0x8000(32k)为数据段IRAM1;这将变成无论是flash总的代码还是sram中的代码,根据启动模式的不同,IRAM1始终指向绝对地址0xx这个sram物理地址是可读写的,而运行代码总是0xx这是映射地址,也是正确的。这样的配置,无论怎样都能正确运行,而区别只是装入时根据不同的启动模式采用用不同的绝对地址,执行文件是同一个。 (注:在我的下一个版本的 STM32 HALMX ARDUINO中,有个开发者版本,内含了ram调试的生成、装载和运行,一键完成,正在最后调试中)
本文内容包含图片或附件,获取更多资讯,请
后查看;或者
成为会员获得更多权限
謝謝分享。
老哥666,厉害啊!
分析得极好!
厉害,学习了,谢谢。
相当厉害,佩服
UID:1023450
在线时间2019小时
M币1036专家49
&发表于: 10-31
顺便说一下,使用GCC(如arduino),则是在连接配置文件 *.ld中用:(RET6为例)_estack = 0x;&&&&/* 将堆栈开始地址设为 end of RAM */而内存使用则是:MEMORY{FLASH (rx)&&&&&&: ORIGIN = 0x8000000, LENGTH = 512KRAM (xrw)&&&&&&: ORIGIN = 0x, LENGTH = 64K}这样设定,改变ORIGIN=XXXXXX&&和 LENGTH=XXXX&&就可以设定了。
UID:994049
在线时间606小时
M币793专家3
&发表于: 10-31
留个标记,有空来学习一下,感谢分享
UID:231972
在线时间290小时
M币1549专家2
&发表于: 10-31
期盼着spi和i2c。字数补丁楼主留言:spi/i2c&&我抽空写一个,但你可以试试我在库中的例子,读取spiflash和读取i2ceeprom。另外,oled 成功没?如没有,你可试试我包中的库:OLED_I2C中的例子,看看能否成功。
UID:1969245
在线时间787小时
M币3643专家8
&发表于: 10-31
很详细的说,让我这个半瓶,非常受益,谢谢分享。
UID:1351094
在线时间111小时
M币1153专家6
&发表于: 10-31
可能你不认真看手册,心思想复杂了……ARM是统一编址,程序运行没有RAM、Flash的分别。RAM相对Flash来说速度没什么优势,麻烦一大堆(你总得先把程序从Flash搬移到RAM、修改SP才能跑,恢复时又要来一遍)。通用的引导程序里会提供,目的是把每1字节的Flash都交给用户——但是实际项目里不会有人这么干,升级过程掉电的话设备就要返厂了;而几十KB甚至几百KB大的Flash根本用不完,留2KB给引导程序完全没问题,还不怕掉电。至于Flash寿命那更是搞笑,最早出的M3(流明诺瑞)都是至少能擦写10万次的。实际上我用M3十多年还没用坏过MCU——我们的设备都划分一块Flash用于存储参数的,经常擦除、写入。
UID:1931804
在线时间320小时
M币1948专家0
&发表于: 10-31
好高深的样子,想学。
UID:1188446
在线时间477小时
M币10864专家3
&发表于: 11-01
透露一下,GD的F1系列是两个DIE绑定在一起的,一个是Cortex_M3内核+RAM,一个是串口FLASH。他把RAM做的比较大,在运行时会把FLASH中的内容先load到RAM中,然后执行。所以测试的时候发现GD falsh中运行和ST在RAM中运行效果是一样的,其实针对GD32F1XX来说没有FLASH运行的概念。这样带来的好处是运行速度快,带来的问题是有32K假死问题。也就是说GD代码RAM空间是32K的,每次从FLASH中装载32K的代码来运行。这样就不难理解了,如果代码执行过程中,有个函数在32K之外,那就必须重新装在代码。而且这个时间是不确定的,可能会达到秒级。楼主留言:你所说的32kRAM,是否应该是充当ICACHE用,专用于代码,所以比内部flash还快,以前我看到过一个帖子说数据SRAM是外挂在外部总线上?所以反而要慢些。
正解。gd的ram设计的很蛋疼,只有flash的一半。所以剩下的一半flash还是存点数据什么的好一些
UID:1023450
在线时间2019小时
M币1036专家49
&发表于: 11-01
回 qiuchen0403 的帖子
:透露一下,GD的F1系列是两个DIE绑定在一起的,一个是Cortex_M3内核+RAM,一个是串口FLASH。他把RAM做的比较大,在运行时会把FLASH中的内容先load到RAM中,然后执行。所以测试的时候发现GD falsh中运行和ST在RAM中运行效果是一样的,其实针对GD32F1XX来说没有FLASH运行的概念。这 .. ( 00:00) 用pos上那个GD32F103Ret6,我将执行代码放在ram中调试总是一用串口就死,不正常,不知是什么原因,st就没有这个问题。另外,用串口下载到ram时,代码长度只能小于0x,即20k,去除串口下载从system启动要使用0x前 512个字节,实际运行代码只有20k-512。[ 此帖被huaweiwx在 00:32重新编辑 ]
我用gd32 的ram跑串口,不死呀。很正常。
UID:1795013
在线时间4069小时
M币46393专家224
&发表于: 11-01
相当厉害,佩服
访问内容超出本站范围,不能确定是否安全
如果您提交过一次失败了,可以用”恢复数据”来恢复帖子内容
您目前还是游客,请
&回复后跳转到最后一页
Code by , Time now is:12-01 10:04, Total 0.111482(s) query 11,
Gzip enabled&查看: 2100|回复: 5
如何在keil中设置 函数在ram中运行呢?
主题帖子精华
初级会员, 积分 147, 距离下一级还需 53 积分
在线时间5 小时
在IAR中有 &__RAMFUNC &这个关键词 可以把一个函数放在 ram 中 运行 &(不知道我的理解整不正确),
但是KEIlL中却没有这个关键字,移植遇到了问题,请问在keil中如何实现 这个关键字的作用呢??
(这个关键字是不是把一个函数放在 ram 中运行呢? 但是程序不都是在ram中运行的吗???)
求大神指点。。。。
主题帖子精华
初级会员, 积分 147, 距离下一级还需 53 积分
在线时间5 小时
求大神指点,原子哥。。。。
主题帖子精华
金钱117721
在线时间911 小时
这个估计有点麻烦,帮顶。
我是开源电子网站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
微信公众平台:正点原子& &
主题帖子精华
初级会员, 积分 147, 距离下一级还需 53 积分
在线时间5 小时
回复【3楼】正点原子:
---------------------------------
那原子哥觉得这个关键字的作用是什么呢?有没有用过呢?
主题帖子精华
高级会员, 积分 522, 距离下一级还需 478 积分
在线时间75 小时
看下这篇文章, _ramfunc目前看除了提高效率没有其它作用
如果你移植的话,你在头文件里添加一句
#define _ramfunc
主题帖子精华
金牌会员, 积分 2676, 距离下一级还需 324 积分
在线时间685 小时
有个比较笨的办法,先确定函数在flash中的位置和size&,然后在ram空间中定义一片相同size的区域,记下起始地址,然后在启动的时候写一段程序吧flash中的数据写入到ram中,然后在程序中用函数指针调用ram中函数的地址(还要记得+1,thumb态),这样就应该能实现函数在ram中运行了。
iar中的关键字,其实也是完成了上面的操作
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
Powered bystm32中怎么在keil中设置程序运行在外部sram - STM32 - 意法半导体STM32/STM8技术社区
后使用快捷导航没有帐号?
查看: 3737|回复: 4
stm32中怎么在keil中设置程序运行在外部sram
在线时间1 小时
主题帖子好友
新手上路, 积分 4, 距离下一级还需 46 积分
新手上路, 积分 4, 距离下一级还需 46 积分
stm32中怎么在keil中设置程序运行在外部sram
在线时间59 小时
主题帖子好友
高级会员, 积分 972, 距离下一级还需 28 积分
高级会员, 积分 972, 距离下一级还需 28 积分
RE:stm32中怎么在keil中设置程序运行在外部sram
1、首先要正确配置KEIL编程环境,能正常下载到FLASH中程序。
2、修改跳转地址,编写一个.ini文件
3、这个网上有个教程写的很详细,参考一下吧。
(913.84 KB, 下载次数: 376)
08:58 上传
点击文件名下载附件
在线时间2 小时
主题帖子好友
初级会员, 积分 79, 距离下一级还需 121 积分
初级会员, 积分 79, 距离下一级还需 121 积分
回复:stm32中怎么在keil中设置程序运行在外部sram
支持楼上。。
在线时间1 小时
主题帖子好友
金牌会员, 积分 1042, 距离下一级还需 3958 积分
金牌会员, 积分 1042, 距离下一级还需 3958 积分
RE:stm32中怎么在keil中设置程序运行在外部sram
自己写一个scatter 文件,把分散加载对应的地址配置好, 另外在KEIL中设置勾选片外RAM及对应的RAM地址。
将中断向量表映射到片外RAM上
在线时间8 小时
主题帖子好友
初级会员, 积分 166, 距离下一级还需 34 积分
初级会员, 积分 166, 距离下一级还需 34 积分
回复:stm32中怎么在keil中设置程序运行在外部sram
学习学习哈
站长推荐 /2
Tel: 3-8064
备案号: 苏ICP备号-2
|||意法半导体STM32/STM8技术社区
Powered byKEIL环境下如何让代码在 RAM中运行 - ARM单片机 - 电子工程世界网
KEIL环境下如何让代码在 RAM中运行
09:44:30来源: eefocus
经常遇到有人使用KEIL时需要将部分或者全部程序放到中运行的问题,现将其总结在本文中。通过F411Nucleo的一个例子来介绍几种让程序在RAM中运行的方法。
我们先从Toggle函数在Flash中执行亮灭开始。下面是ToggleLED函数和它的调用情况。在main函数的while(1)里调用ToggleLED。
void ToggleLED(void)
{ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); /* Insert a 100ms delay */
HAL_Delay(100);
int main(void)
{ && /*##-3- Toggle PA05 IO in an infinite loop&*/
while (1) { ToggleLED(); }
编译环境的Linker的配置见下图:
Flash起始地址:0x
RAM起始地址:0x
编译后从map文件可以看到,ToggleLED以及其中调用到的HAL_GPIO_TogglePin和HAL_Delay函数的地址都在FLASH中。
将翻转LED的程序放到SRAM中执行
方法一:通过#pragma
section code = &RAMCODE &和#pragma arm section。参考Example1代码。
这种方式,可以同时将多个函数放到指定的section。具体方法如下:
1. 修改.sct文件,自定义一个叫做RAMCODE的section,放在RW_IRAM1执行区域,地址范围0xx。
LR_IROM1 0xx { ; load region size_region
ER_IROM1 0xx { ; loaddress = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
} RW_IRAM1 0xx { ; RW data
*.o(RAMCODE)
.ANY (+RW +ZI)
2. 在工程中使用前面修改的.sct文件
3.以#pragma arm section code = &RAMCODE& 开头,以#pragma arm section结尾。将所有需要放到RAMCODE section的函数包括进来。编译时,编译器会自动将这些函数放到RAMCODE所在0x开始的区域。
#pragma arm section code = "RAMCODE"
void ToggleLED(void)
{ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); /* Insert a 100ms delay */
HAL_Delay(100);
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{ /* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
GPIOx->ODR ^= GPIO_P
uint32_t HAL_GetTick(void)
void HAL_Delay(__IO uint32_t Delay)
{ uint32_t tickstart = 0;
tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay)
#pragma arm section
4.从map文件里,可以看到这四个函数都已经被放到了SRAM中。
方法二:通过__attribute__((section(&name &)))
在KEIL中可以通过__attribute__((at(address)))的方式将变量放到指定的位置。
通过__attribute__((section(&name &)))的方式将变量或者函数放到指定的位置。
下面我们来看看如何通过这种方式将程序放到SRAM中执行。
1.同样,我们需要修改.sct文件,自定义一个叫做RAMCODE的section,并在工程选项的linker页面中,选择定义好的.sct文件。(见方法一中的第1,2步)
LR_IROM1 0xx { ; load region size_region ER_IROM1 0xx { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
RW_IRAM1 0xx { ; RW data
*.o(RAMCODE)
.ANY (+RW +ZI)
2.在需要放到RAM中的函数前,用__attribute__((section("RAMCODE")))声明该函数放在RAMCODE section中。注意,该函数中调用到的所有函数也要放到RAMCODE section中。
__attribute__((section("RAMCODE")))
void ToggleLED(void)
{ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); /* Insert a 100ms delay */
HAL_Delay(100);
__attribute__((section("RAMCODE")))
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{ /* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
GPIOx->ODR ^= GPIO_P
__attribute__((section("RAMCODE")))
__weak uint32_t HAL_GetTick(void)
{ return uwT }
__attribute__((section("RAMCODE")))
__weak void HAL_Delay(__IO uint32_t Delay)
{ uint32_t tickstart = 0;
tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay)
3.从编译后的map文件可以看出,ToggleLED以及它调用到的所有函数都被到了RAM中。
方法二可以覆盖方法一,也就是说如果你同时用方法一和方法二对同一个函数的执行区域做了说明。最终起作用的是方法二。还是通过上面提到的代码来说明。
修改.sct文件。将SRAM分为两个执行区RW_IRAM1和RW_IRAM2。Section RAMCODE1,RAMCODE2分别位于0x开始,和0x开始的两个64KB的区域。
LR_IROM1 0xx { ; load region size_region ER_IROM1 0xx { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
RW_IRAM1 0xx { ; RW data
*.o(RAMCODE1)
.ANY (+RW +ZI)
RW_IRAM2 0xx {
*.o(RAMCODE2) }
2.在代码中, HAL_GetTick被放在了#pragma的作用域内被声明放在RAMCODE1 section,同时又用__attribute__( ( section ( "RAMCODE2" ) ) ) 将其放在RAMCODE2的section内。
#pragma arm section code = "RAMCODE1"
void ToggleLED(void)
{ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
/* Insert a 100ms delay */
HAL_Delay(100); }
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{ /* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
GPIOx->ODR ^= GPIO_P
__attribute__( ( section ( "RAMCODE2" ) ) )
uint32_t HAL_GetTick(void)
void HAL_Delay(__IO uint32_t Delay)
{ uint32_t tickstart = 0;
tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay) { }
#pragma arm section
3.编译完成后,我们看看map文件中HAL_GetTick被放到了哪个section。
从map里可以看到,最终HAL_GetTick被放在了RAMCODE2 section中。
**如何将整个程序放到SRAM中执行
前面介绍了将一个或多个程序放到指定地址执行的方法。如果需要放到指定地址的程序比较多,我们还可以将这些需要放到指定地址的程序集中放到一个或几个C文件中,然后在.sct文件中将这些C文件生成的目标文件放到指定地址。
在这里,我们将尝试将整个程序放到SRAM中执行。复位后程序从FLASH启动,之后将从SRAM执行所有的程序。下面是具体的步骤。
1.将中断向量表和中断处理程序放到SRAM中
新建一个stap_stm32f411xe_ram.s文件,放到0x开始的位置(在.sct文件中修改)。注意这里是新建,而不是直接将原来的文件放到SRAM中,为什么呢?大家可以思考一下。在startup_stm32f411xe_ram.s里定义新的SECTION,叫做RESET_ram(还有其他的修改,请对照参考代码)。在后面的.sct中将把RESET_ram这个section放到SRAM开始的位置上(见第3步)。
Vector Table Mapped to Address 0 at Reset
AREA RESET_ram, DATA, READONLY
EXPORT __Vectors_ram
EXPORT __Vectors_End_ram
EXPORT __Vectors_Size_ram
__Vectors_ram DCD 0 ; Top of Stack
DCD 0 ; Reset Handler
DCD NMI_H NMI Handler
2.在SystemInit中将中断向量表的偏移地址设置为0x。使能VECT_TAB_SRAM。
#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 */
3.修改.sct文件,将运行时需要的所有目标文件都放到SRAM执行区中。这里中断向量表有同样的两份,一份在0x开始的位置,一份在0x开始的位置。
LR_IROM1 0xx { ; load region size_region
ER_IROM1 0xx { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
RW_IRAM1 0xx { ; RW data
*.o (RESET_ram, +First)
startup_stm32f411xe_ram.o(+RO)
main.o(+RO +RW)
stm32f4xx_it.o(+RO +RW)
stm32f4xx_hal.o(+RO +RW)
stm32f4xx_hal_gpio.o(+RO +RW)
stm32f4xx_hal_.o(+RO +RW)
stm32f4xx_hal_cortex.o(+RO +RW)
.ANY (+RW +ZI)
4. 编译完成后,从map文件或者跟踪调试的结果都可以看到。系统复位以后,从main函数开始,所有的程序都在RAM中运行了。
另外,如果你的程序中有用到ARM底层的库,可以在.sct文件中加入*armlib*(+RO)来将所有用到的库文件放到SRAM中。
关键字:&&&&
编辑:什么鱼 引用地址:
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
微信扫一扫加关注 论坛活动 E手掌握
微信扫一扫加关注
芯片资讯 锐利解读
大学堂最新课程
汇总了TI汽车信息娱乐系统方案、优质音频解决方案、汽车娱乐系统和仪表盘参考设计相关的文档、视频等资源
热门资源推荐
频道白皮书
何立民专栏
北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。&#xe621; 上传我的文档
&#xe602; 下载
&#xe60c; 收藏
该文档贡献者很忙,什么也没留下。
&#xe602; 下载此文档
正在努力加载中...
KEIL代码放到RAM中运行
下载积分:100
内容提示:KEIL代码放到RAM中运行
文档格式:DOCX|
浏览次数:63|
上传日期: 16:46:40|
文档星级:&#xe60b;&#xe60b;&#xe60b;&#xe60b;&#xe60b;
全文阅读已结束,如果下载本文需要使用
&#xe71b; 100 积分
&#xe602;下载此文档
该用户还上传了这些文档
KEIL代码放到RAM中运行
关注微信公众号}

我要回帖

更多关于 keil ram 运行 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信