STM32关于堆栈,局部变量全局变量内存分配的问题

STM32关于堆栈,局部变量全局变量内存分配的问题


  • 开发环境:IAR for ARM 8.30.1
  • MCU:STM32F103RCT6

以一个简单的bootloader程序为例,先来看看map文件中的内存分配:

*******************************************************************************
*** PLACEMENT SUMMARY
***

"A0":  place at 0x800'0000 { ro section .intvec };		//ROM的起始位置,从这里开始烧录程序
"P1":  place in [from 0x800'0000 to 0x800'4000] { ro };	//整个Bootloader代码的存储空间
define block CSTACK with size = 1K, alignment = 8 { };	//编译器中定义的栈大小,1K字节
define block HEAP with size = 0M, alignment = 8 { };	//没有用到malloc之类的函数,设置为0
"P2":  place in [from 0x2000'0000 to 0x2000'bfff] {		//RAM的地址空间,分三个部分
          rw, block CSTACK, block HEAP };
initialize by copy { rw };

RAM空间地址的三个部分划分:
.data:初始化的全局和静态变量;
.bss:未初始化的全局和静态变量,编译器自动初始化为0;
CSTACK:存放局部变量,局部变量超过栈大小将会发生堆栈溢出,程序崩溃;

"P2", part 1 of 3:                           0x89
  P2-1                        0x2000'0000    0x89  <Init block>
    .data            inited   0x2000'0000     0x4  stm32f1xx_hal.o [1]
    .data            inited   0x2000'0004     0x4  system_stm32f1xx.o [1]
    .data            inited   0x2000'0008    0x38  xlocale_c.o [2]
    .data            inited   0x2000'0040    0x48  xlocale_c.o [2]
    .data            inited   0x2000'0088     0x1  stm32f1xx_hal.o [1]
                            - 0x2000'0089    0x89

"P2", part 2 of 3:                         0x10dc
  .bss               zero     0x2000'008c  0x1000  boot.o [1]
  .bss               zero     0x2000'108c    0x58  spi.o [1]
  .bss               zero     0x2000'10e4    0x40  usart.o [1]
  .bss               zero     0x2000'1128    0x20  stm32f1xx_hal_flash.o [1]
  .bss               zero     0x2000'1148    0x10  spi_flash.o [1]
  .bss               zero     0x2000'1158     0x4  spi_flash.o [1]
  .bss               zero     0x2000'115c     0x4  spi_flash.o [1]
  .bss               zero     0x2000'1160     0x4  stm32f1xx_hal.o [1]
  .bss               zero     0x2000'1164     0x4  xfail_s.o [2]
                            - 0x2000'1168  0x10dc

"P2", part 3 of 3:                          0x400
  CSTACK                      0x2000'1168   0x400  <Block>
    CSTACK           uninit   0x2000'1168   0x400  <Block tail>
                            - 0x2000'1568   0x400

这里查看系统剩余的ROM和RAM空间:

Unused ranges:

         From           To    Size
         ----           --    ----
   0x800'3cbd   0x800'4000   0x344
  0x2000'0089  0x2000'008b     0x3
  0x2000'1568  0x2000'bfff  0xaa98

1.堆栈

  • 在IAR中的设置:
    CSTACK大小决定了你函数中局部变量的总大小,由系统自动分配和释放,如果定义的局部变量大小超过了栈大小,虽然编译能通过,但是程序无法运行;同样,将CSTACK设置为0,编译器也能编译通过,但程序无法运行
    在这里插入图片描述

2.全局变量初始化问题

这里的全局变量还包括static声明的静态变量,初始化与未初始化存放的位置不同,初始化为不同的值在占用ROM大小也是不同的

从下面的示例可以看出,全局变量不初始化和初始化为0占用内存一样的,而且他们都是分配在全局未初始化区,系统初始化的时候统一赋值为0;

而初始化为1或者其他值,就会额外占用ROM的空间来存放你要初始化的常数,而且还可以看到初始化为不同的值,占用的ROM和RAM还不一样,下面就有RAM占用反而变小了的情况,这是因为这个变量存放的位置变成了全局初始化区,会受到编译器优化和数据对齐的影响;

  • 未初始化
u32 update_file_mark;
void Boot_Initializes(void)
{
  u16 i,j;
//以下代码省略
占用内存情况:
  14 684 bytes of readonly  code memory
     869 bytes of readonly  data memory
   5 481 bytes of readwrite data memory
  • 初始化为0
u32 update_file_mark = 0;
占用内存情况:
  14 684 bytes of readonly  code memory
     869 bytes of readonly  data memory
   5 481 bytes of readwrite data memory
  • 初始化为1
u32 update_file_mark = 1;
占用内存情况:
  14 684 bytes of readonly  code memory
     873 bytes of readonly  data memory
   5 477 bytes of readwrite data memory
  • 初始化为0xFFFFFFFF
u32 update_file_mark = 0xFFFFFFFF;
占用内存情况:
  14 684 bytes of readonly  code memory
     872 bytes of readonly  data memory
   5 477 bytes of readwrite data memory

3.局部变量初始化的问题

还是那个变量,这次放到函数内部让它成为局部变量

可以看到,局部变量初始化与否不会影响到RAM的分配变化,这个从RAM的空间划分的三个部分也可以看出
仅仅影响ROM而且是readonly code memory的变化,其中:
不初始化最节省ROM,初始化为0其次,初始化为其他值可能占用更多的ROM

  • 未初始化
void Boot_Initializes(void)
{
  u16 i,j;
  u32 update_file_mark;
占用内存情况:
  14 676 bytes of readonly  code memory
     869 bytes of readonly  data memory
   5 477 bytes of readwrite data memory
  • 初始化为0
void Boot_Initializes(void)
{
  u16 i,j;
  u32 update_file_mark  = 0;
占用内存情况:
  14 680 bytes of readonly  code memory
     869 bytes of readonly  data memory
   5 477 bytes of readwrite data memory
  • 初始化为1
void Boot_Initializes(void)
{
  u16 i,j;
  u32 update_file_mark  = 1;
占用内存情况:
  14 680 bytes of readonly  code memory
     869 bytes of readonly  data memory
   5 477 bytes of readwrite data memory
  • 初始化为0xFFFFFFFF
void Boot_Initializes(void)
{
  u16 i,j;
  u32 update_file_mark  = 0xFFFFFFFF;
占用内存情况:
  14 684 bytes of readonly  code memory
     869 bytes of readonly  data memory
   5 477 bytes of readwrite data memory
  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值