你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32程序内存分布

[复制链接]
STMCU小助手 发布时间:2022-1-17 21:38
一般 MCU 包含的存储空间有:片内 Flash 与片内 RAM,RAM 相当于内存,Flash 相当于硬盘。编译器会将一个程序分类为好几个部分,分别存储在 MCU 不同的存储区。
Keil 工程在编译完之后,会有相应的程序所占用的空间提示信息,如下所示:
  1. linking...
    + W  a# K0 w5 z' u" |; w9 d) ]
  2. Program Size: Code=48008 RO-data=5660 RW-data=604 ZI-data=2124" X1 }# y/ H; K
  3. After Build - User command \#1: fromelf --bin.\\build\\rtthread-stm32.axf--output rtthread.bin
    $ j9 t* u7 v; m" C1 W! }3 |
  4. ".\\build\\rtthread-stm32.axf" - 0 Error(s), 0 Warning(s).3 y* @, P) [2 v8 @* {
  5. Build Time Elapsed: 00:00:07
复制代码

( ^: J, O' g- y5 D. x# P
上面提到的 Program Size 包含以下几个部分:
    1)Code: 代码段,存放程序的代码部分
    2)RO-data:只读数据段, 存放程序中定义的常量;
    3)RW-data: 读写数据段,存放初始化为非0值的全局变量
    4)ZI-data: 零数据段,存放未初始化的全局变量及初始化为0的变量;
编译完工程会生成一个. map 的文件,该文件说明了各个函数占用的尺寸和地址,在文件的最后几行也说明了上面几个字段的关系:
  1. Total RO Size (Code + RO Data) 53668 ( 52.41kB)" n& N- ?" {5 y' j" h2 [  A
  2. Total RW Size (RW Data + ZI Data) 2728 ( 2.66kB)( J9 ^1 e- l& e$ N& E4 K- J
  3. Total ROM Size (Code + RO Data + RW Data) 53780 ( 52.52kB)
复制代码
* B8 t0 K+ t/ Z8 ^0 _
    1) RO Size 包含了 Code 及 RO-data,表示程序占用Flash空间的大小
    2)RW Size 包含了RW-data及ZI-data,表示运行时占用的RAM的大小
    3)ROM Size 包含了Code, RO Data以及RW Data, 表示烧写程序所占用的Flash空间的大小
       程序运行之前,需要有文件实体被烧录到 STM32 的 Flash 中,一般是 bin 或者 hex 文件,该被烧录文件称为可执行映像文件。如图 3-3 中左图所示,是可执行映像文件烧录到 STM32 后的内存分布,它包含 RO 段和 RW 段两个部分:其中 RO 段中保存了 Code、RO-data 的数据,RW 段保存了 RW-data 的数据,由于 ZI-data 都是 0,所以未包含在映像文件中。
       STM32 在上电启动之后默认从 Flash 启动,启动之后会将 RW 段中的 RW-data(初始化的全局变量)搬运到 RAM 中,但不会搬运 RO 段,即 CPU 的执行代码从 Flash 中读取,另外根据编译器给出的 ZI 地址和大小分配出 ZI 段,并将这块 RAM 区域清零
1565092-20191130230439746-167047464.png
/ m& b# @" B) ~/ R
: @+ x2 F# i: T" i1 `' |
其中动态内存堆为未使用的 RAM 空间,应用程序申请和释放的内存块都来自该空间。
如下面的例子:
  1. rt_uint8_t* msg_ptr;
    , T/ C% o4 y$ t! ]6 }4 H
  2. msg_ptr = (rt_uint8_t*) rt_malloc (128);
    & I+ \' O  t, L8 h; r
  3. rt_memset(msg_ptr, 0, 128);
复制代码
- N- r8 d$ |9 g; `9 X: Z
代码中的 msg_ptr 指针指向的 128 字节内存空间位于动态内存堆空间中。
而一些全局变量则是存放于 RW 段和 ZI 段中,RW 段存放的是具有初始值的全局变量(而常量形式的全局变量则放置在 RO 段中,是只读属性的),ZI 段存放的系统未初始化的全局变量,如下面的例子:
  1. #include <rtthread.h>+ f8 M7 T% Q- k5 f- h
  2. ' m: C7 b5 @' E$ I+ ~
  3. const static rt_uint32_t sensor_enable = 0x000000FE;0 a9 V# l, \% \- a& R7 K! ~! s
  4. rt_uint32_t sensor_value;
    8 X" ~2 e" B6 p) K3 l& X
  5. rt_bool_t sensor_inited = RT_FALSE;+ v% U7 ?! f% Y' I1 W
  6.   }7 Y8 C" Y! t- {$ v9 {) C
  7. void sensor_init()2 B8 e- ]3 c: Q( o* e( G% p7 E
  8. {
    2 i, H1 ?2 H4 H3 ~
  9.      /* ... */
    2 f4 j2 Q9 e% x' s. q& G) _( `) Y
  10. }
复制代码
: w$ J% D" F9 a; X# |
8 k4 o% @- D/ A, Y0 B+ j
sensor_value 存放在 ZI 段中,系统启动后会自动初始化成零(由用户程序或编译器提供的一些库函数初始化成零)。sensor_inited 变量则存放在 RW 段中,而 sensor_enable 存放在 RO 段中。

/ ?% O0 ?. X- `% x# s  q) r2 C3 `$ Y
赞 收藏 评论0 发布时间:2022-1-17 21:38

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版