stm32 代码RAM溢出

KEIL编译程序后报下边错误:

原因是因为代码的全局变量太多或全局的数组太大导致程序编译后RAM溢出,建议先查看有没有比较大的全局数组

BootLoader\BootLoader.axf: Error: L6406E: No space in execution
regions with .ANY selector matching startup_stm32f103xb.o(STACK). …
BootLoader\BootLoader.axf: Error: L6407E: Sections of aggregate size
0x768 bytes could not fit into .ANY selector(s). Not enough
information to list image symbols. Not enough information to list load
addresses in the image map. Finished: 2 information, 0 warning and 17
error messages.

程序编译没错 运行时报错:

最常见的两个问题:
1:指针越界或者空指针
》数组指针越界死机一般存在两种情况 :直接死机或者添加其他代码时死机,原因是开始程序比较简单时数组越界访问的地址是有效可访问的地址此时越界是不会死机的,但添加其他代码运行后代码突然死机就是访问到了不可访问的地址就死机,一般此类问题原因比较难查:只能一层层的代码过滤找到死机的函数,最终确认越界的数组指针。

2:栈溢出:函数中存在比较打的 局部数组 ,像读flash一般定义4k数组
3:ram(堆)要是不够用,可以把一些常量数组值前+const(有些单片机会把常量放进flash而不是ram)

常用的stm32单片机:

stm32f103ret6:大片 Flash:512k ram:64k rom:512k
stm32f103c8t6 :小片 Flash:128k ram:20k rom:64k

keil编写后程序占ram rom

Program Size: Code=13004 RO-data=292 RW-data=64 ZI-data=18976
其中:rom=Code+ RO-data + RW-data
ram=RW-data+ ZI-data
我用的是stm32f103c8t6 小片,ram= 20k,程序中有两个比较大的全局数组arr[4096],调用使用这个数组的函数,编译直接报上边这些错误。
原因是: RW-data+ ZI-data>20k
修改办法:
1:换用大片
2:减少全局变量与数组的大小

附加:
1.stm32数据手册
STM32小容量,中等容量和大容量的型号区别

 因为STM32F103xx是一个完整的系列,其成员之间是完全地脚对脚兼容,软件和功能上也兼容。在参考手册中,STM32F013x4和STM32F103x6被归为小容量产品,STM32F103x8和STM32F103xB被归为中等容量产品,STM32F103xC,STM32103xD和STM32F103xE被归为大容量产品

stm32内存说明
2.编译参数的意义:
Program Size: Code=13004 RO-data=292 RW-data=64 ZI-data=18976
1、Code 是代码占用的内存。
2、RO-data是 Read Only 只读常量的大小,如const型。
3、RW-data是(Read Write) RW是可读可写变量,就是初始化时候就已经赋值了的,RW + ZI就是你的程序总共使用的RAM字节数。
4、ZI-data是(Zero Initialize) 没有初始化的可读写变量的大小,就是程序中用到的变量并且被系统初始化为0的变量的字节数,keil编译器默认是把你没有初始化的变量都赋值一个0,这些变量在程序运行时是保存在RAM中的。

程序编译后:.lcf、.adx、.map文件中字段解释 .data,.sdata,.rodata,.sbss ,.text
ELF文件说明
.data 是指初始化段 表示已经初始化的全局变量和静态变量,需要占用内存空间以保存初始值
.sdata是指smll data初始化段(小于多少可以算small data,可以在codewarrior中设置)
.rodata表示只读数据,如程序中用到的字符串常量,printf中的格式串,switch语句中的跳转表等
.sbss 是指small data未初始化段。
.text是代码段,如函数指针指向的就是这个区域

写代码时注意事项

Flash用来存储机器代码,常量,初始化值不为0的全局变量,而且程序运行是在Flash中;

RAM:用来存储初始化值为0的全局变量,以及静态变量(模块内部或者函数内部),堆和栈。

STM32微控制器包含的存储单元如下所示:

Main memory block:Flash,地址为0x8000000,RAM,地址为0x20000000
System storage block:this area is used to store the code about bootloader which is used to upgrade firmware,地址为0x1FFF0000。
OTP area:One Time Programmable area
Optional bytes:
如何选择系统从哪个区域运行代码?

系统开机上电或者硬件复位后会根据BOOT pin进行判断,如果BOOT pin为低电平,则系统从Flash中运行代码(地址为:0x8000000),如果BOOT pin为高电平,则系统从System storage block运行代码(地址为:0x1FFF0000)。

系统启动文件?

系统的启动文件为Startup_stm32L011XX.s,该文件是汇编语言,用于初始化芯片关键模块,主要包括异常向量表和PC、SP指针。

系统编译之后包含的数据类型?
'
数据类型:
> Ro code:机器代码,存放在Flash中 Ro data:常量,用const修饰的变量,存放在flash中 RW
> data:全局变量,初始化值不为0,存放在flash中,运行时会拷贝到RAM中,RAM运行速度快,节省修改数据时间 ZI
> data:全局变量,初始化值为0,存放在RAM中 ZI stack:栈空间数据,函数内部的局部变量,存放在RAM中 ZI
> heap:堆空间,使用malloc分配,存放在RAM中
'

  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 在将STM32代码从Flash搬移到RAM的过程中,我们首先需要确保芯片的RAM容量足够存储代码。然后,我们需要将代码的链接脚本进行修改,以便将代码从Flash的地址重新定位到RAM的地址。接下来,我们需要进行代码的复制操作,将Flash中的代码复制到RAM中。 为了完成这个过程,我们可以使用如下的步骤: 1. 修改链接脚本:打开链接脚本文件并进行修改,将代码的起始地址和大小重新定义为RAM的地址和大小。 2. 修改代码运行起始位置:检查代码中的启动函数,确保它指向RAM的起始位置,而不是Flash的起始位置。 3. 复制代码RAM:在代码的启动函数中,我们需要添加复制代码RAM的操作。可以使用内置的复制函数(如`memcpy()`)或者手动复制方式进行。将Flash中的代码复制到RAM中后,确保更新相关变量的地址。 4. 设置向量表位置:在引导代码的开头,我们需要设置向量表的位置为RAM。这需要根据具体的芯片进行设置,可以通过修改SCB的VTOR寄存器来实现。 5. 更新中断向量表地址:在启动文件中,确保中断向量表的地址已经更新为RAM的地址。这样做可以确保芯片在中断发生时正确地跳转到RAM中的中断处理函数。 6. 验证代码正常运行:重新编译和烧写代码,并确保所有代码正常运行,没有出现异常或错误。 总结起来,将STM32代码从Flash搬移到RAM需要修改链接脚本和代码运行起始位置,并进行代码的复制操作。同时,还需要设置向量表的位置,更新中断向量表地址,并验证代码的正常运行。这样做可以提高代码的执行速度,尤其适用于性能要求较高的应用。 ### 回答2: 将STM32代码从Flash搬移到RAM的主要目的是为了提高代码的执行效率和响应速度。在Flash中存储的代码是只读的,因此每次执行代码时,MCU都需要从Flash读取指令,这会导致一定的读取延迟和访问速度下降。而将代码搬移到RAM中后,可以直接从RAM中读取指令,以极大地减少读取延迟和提高执行效率。 搬移代码的操作一般分为两步:将代码从Flash中复制到RAM,并将复制后的代码重新定位到RAM的起始地址。这样,当代码执行时,MCU会首先从RAM读取指令,而不需要再每次都从Flash中读取。 搬移代码的过程可以通过使用相关函数或指令来完成。在STM32中,可以使用HAL库中的相应函数,如HAL_FLASHEx_DATAEEPROM_Copy()函数来实现将Flash中的代码复制到RAM。在复制完成后,还需要根据具体的MCU型号和使用的开发工具,设置复制后代码的起始地址,以便MCU能够正确地访问RAM中的代码。 需要注意的是,将代码搬移到RAM中后,需要合理利用RAM的容量和管理RAM的使用,因为RAM的容量一般比Flash有限。在复制代码之前,应该先估计代码的大小,并确保RAM有足够的空间来存储代码。此外,还可以考虑将一些频繁执行的代码块搬移到RAM中,以进一步提高执行效率。 总结来说,将STM32代码从Flash搬移到RAM是为了提高代码的执行效率和响应速度。通过复制代码RAM并设置正确的起始地址,可以减少访问延迟,提高读取速度和执行效率。然而,在搬移代码时需要注意RAM的容量限制,并合理管理RAM的使用。 ### 回答3: 将STM32代码从Flash搬移到RAM可以提高代码执行效率和速度。通常情况下,STM32代码存储在Flash中,当在运行时需要执行部分代码时,会从Flash中读取指令并执行。搬移到RAM后,所有代码都存储在RAM中,运行时不再需要从Flash读取指令,而是直接在RAM中执行指令,从而减少了访问存储器的时间。 实现将STM32代码从Flash搬移到RAM的步骤如下: 1. 在代码工程中将Flash部分的代码复制到RAM区域的一部分以确保代码可用。可以在代码中声明一个特殊的RAM段,将相关函数和变量放入其中。 2. 通过编译器和链接器设置,将这部分特殊RAM段的起始地址和大小与MCU的RAM进行关联。这样,编译器在生成可执行文件时会将相应的代码放到RAM区域中。 3. 在代码中修改启动向量,使得MCU重启后直接从RAM中启动,而不是从Flash启动。这可以通过设置复位向量表中的复位向量地址为RAM的起始地址来实现。 4. 对于涉及到中断向量表的代码,还需要修改中断向量表,使得中断服务程序能够从RAM中正确地执行。 通过将代码搬移到RAM中,可以减少Flash访问的延迟和读取时间,提高代码执行速度和效率。这在对实时性要求较高的应用中特别有用,例如控制任务响应、数据处理和实时通信等。然而,需要注意的是,将大量代码从Flash搬移到RAM可能会导致RAM资源紧张,因此需要仔细评估代码规模和RAM容量,以确保RAM能够容纳所需的代码和数据。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值