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

STM32经验分享——内存分布详解(1)

[复制链接]
STMCU小助手 发布时间:2022-8-28 21:55
STM32具有和PC机类似的结构组成。那么我们平时听到的RAM和ROM就相当于PC的内存条和硬盘,当然了PC的硬盘和单片机的ROM也并不是所谓的只读,只不过以前的技术原因很难做到多次读写,因为最初的存储器是纸带、熔丝或者其他一次性存储器,因此只能读取,也就是ROM,当然那时候也不需要持续的修改。随着技术的革新,这些最初的ROM慢慢的增大内存、增加写功能、提高读写速度。而ROM的叫法也一直延续下来。! S) S" Y( Y" g' h

' b# U) [" C6 g        扩展一下,为什么ROM也可以写,不用ROM当RAM呢?因为ROM还是太慢了,读取可还行(比如F7、H7就支持QSPI运行程序),写就是肉眼可见级别的延迟了。所以RAM这种需要高速读写的还是让SRAM、SDRAM、DDR等等来干吧。
, U! Q4 u; c6 ]6 M
( X4 }. Q) A" T1 K/ Q. N        那这两大块内存在单片机上是怎么分布的呢?以F103C8T6为例。
5 g) K9 w9 {7 I; |# ]8 F
`{M0{1UYCQDWW@]5XKGMB8U.png
' Q8 l4 Z1 j, q) Q" o* \9 V
! z6 w. @$ s+ Y: }5 E0 p
ROM&RAM声明

; D$ \. E8 d: C  ]; a; }2 }        这里就勾选使能了两块内存,一个是ROM,一个是RAM,当然也有的支持两块ROM或者ROM,这里先不管,ROM的起始地址是0x0800 0000,大小是0x2400。RAM的地址是0x2000 0000,大小是0x5000。(为什么ROM比RAM还小,因为这是个Bootloader,要占用尽可能小的空间,不然的结果就是你买的64G手机,什么都没装就还有56G)。: [% `# {3 F& ?' r
: Y0 x1 v/ |; u' @* C/ u
        或者看一下默认的分散加载文件,也可以得到ROM和RAM的地址和大小。" ]6 y4 d! G3 i4 x2 n- s  S$ d
2 c5 z" S; C4 [7 h# b' w9 z
AR0J4_@V7H)LT9)NN~1YP.png
) e# T7 o0 F- }

; _$ o3 a, I8 H. j* R/ S. H
分散加载内容
% }' V4 m. ^5 I& k
        关于ROM和RAM做什么用的你应该很清楚了,不清楚我们就再叙述一下。RAM是随机存取存储器,可读可写,并且想怎么读怎么读,想怎么取怎么取,还很快。正是这种特点RAM才适合做CPU和ROM的中介,上可速度对等CPU,下可衔接ROM永久存储数据。但是呢?一断电它就清零了,就跟你敲了半天的word崩了打开就空了一样。而ROM就不会,并且ROM的空间大小可以做到很大很大。而ROM的缺点就是写比较慢,如果是串行的传输方式那么会更慢。
7 d8 b5 X' u9 v4 Q" ^8 z* r* B3 i* L5 ^  V
        CPU就非常快了,上到GHz级别,因此如果需要进行数据的读写,显然ROM速度完全跟不上,但是RAM一断电就没了,所以完美的结构是先从ROM读取到RAM,然后再运行。这就是为什么同时需要ROM和RAM。3 T: @8 V- K( z8 [; g% v9 s9 o
$ r) o4 Y' k6 g% N
        ROM保存着需要固化的内容,比如函数到底存储着哪些寄存器操作指令,程序到底定义了哪些全局变量,程序使用了哪些字库、图片或者数组(比如使用查表加速计算)。你下载的程序就存储在这里,比如你使用fromelf --bin !L -o .\BIN\Firmware_F4.bin指令生成了bin文件。(bin文件名称:Firmware_F4.bin 可以自定义)那么这些数据就会固化在0x0800 0000这里,就像这样。# ]0 R1 B1 Z: r/ W- F+ E, {5 |

; g1 @" W3 K+ U2 G4 {3 [
FA60_X[8}8R0)FTXOPKBJ.png
' C& \8 q1 y# U/ F

, o, h3 ?- z' F
BIN文件数据

/ X1 b8 N7 }* B9 Z, b5 z        而你定义的数组则会存在0x2000 0000这块区域,具体是哪里可以使用取址指令得到地址,例如value数组的地址是:0x20000898。
: r! M& o' m8 R) m  U$ o+ N8 x( X0 N2 i& G6 \2 }
0XP59$R%L74`K`ULNS5$N@C.png

3 O0 Y3 h* Q" q! k, W0 i" Y
" m4 ~" N( U  y
数组地址打印

$ I% C! T: A, C. ]3 v: P        或者你也可以直接看变量窗口的地址,如下。
0 S$ P6 N. N3 D, h5 ]0 z/ ~# l. U0 G  J+ g+ Y
2I[Z]6E221VRBJP1Z5~MN)W.png
5 H: v: o4 V0 U% \% H" w0 K

7 F8 I4 |# [0 ^7 q
变量地址查看
3 I5 m3 |- l6 U8 a
        当你写了数据,相应的就可以看到RAM的数值变化。比如执行到60行的时候,第59行的赋值就有了效果。
  M9 J2 i: G( n$ \9 D4 o5 ?1 }7 E4 ]% o4 d
7{FA`4UTM~[4MY(~[IYCD_T.png
! X$ x& N% z- G: G. J" P5 I- A
, r% F" i' E. z: f) a% L
变量地址&数据查看

9 `+ d, @4 V8 e" I( [        相对应的内存处也产生了变化。& B3 g9 o+ t$ v! ?( M1 C

- B" i7 a6 V2 d# r
CYAU)A`2HTMU7J3AJJ{OUGW.png

2 p1 ?8 |9 s9 |. K5 L% ]) b0 D6 H  C
数组数据变化

+ _- K8 _- O; n) q6 W1 I5 {        随着数组内容的写入可以看到数据的变化过程。
+ e6 G( s4 E5 ^* P% Y; g7 a
4 g, k) w9 d/ n+ b5 Z  A4 f
{_WD7Y0A_LF3IT1WF_][KC4.png

' G4 h5 \6 |2 y- _; S3 l5 V( j3 Q' m* W3 D7 u  s  B+ w; E
数组数据变化

9 g! f4 @4 `' f+ p) z/ m% L% e( v        甚至你还可以看到main函数存在了哪里。2 k: y( U/ T" u, ~
) Y0 m0 [+ h; e( R
(Z7STT7_Q3MDE8MPD8Z~5PC.png
% K7 h( |9 p2 e! Y- D3 h. S0 i7 |
# o& ~3 e. F! o6 S
主函数存储地址

) f1 `9 j6 k3 k) Z        又或者你直接查看Map文件。9 D# N% A; N/ e' h8 u' K9 K: B$ j

. \* a# U9 J+ e4 ?
_}4SGJL%_Q(315[E5)C5.png
) `, |8 h: t/ U2 @
1 F& d% E8 n6 F' l" I; m0 j
map文件main函数存储地址

3 z9 I$ p* A9 z        这是你定义的字库的地址:0x08007B96,或者你也可以用同样的方式把它打印出来。
$ k" M) ]" I  a: i  k1 ?
& u4 N. w) A+ F# h/ l! ^( T* T6 [
64F4ISOGRGP14%ZVE[XIAOY.png
/ ]& j! d% w# ]. r/ G
6 F) E0 x0 _9 K6 C* r9 V
字库存储地址

+ A6 O+ y) @  `9 O/ ^+ Y/ {        同样是数组,一个在RAM,一个在ROM,因为字库不需要更改,所以使用const关键字定义在常量区,也就是ROM。而变量数组需要更改,这里没有赋0以外的值,所以你需要多大的空间,编译器到时候给你去RAM分配就是了,然后编译器再把这些分配地址的指令写进BIN,然后你下载存储到0x0800 0000的单片机的硬盘里,到时候单片机的Cortex-M内核就知道0x2000 0000的那一块地址是属于你的数组了。3 S/ f( u4 ^$ M- r; P
2 C7 j" P! g3 A, n* ~
        如果赋值不是0呢?可以看到,地址还是0x2000 0000这块区域。而main函数的局部变量就需要分配了,有初始非0值相当于预定了,而局部变量只有运行的时候才有会给分配地址。
; ~- A2 c7 d4 m6 U8 x1 |& }
/ p3 v5 F7 n0 D, f$ B
DFH003)VA78{}FI1A[P~F00.png

# j# z' Q( M# E4 L* f/ w! ^# h3 t) Y* @/ ^! i; u2 X! I
全局非0初始化存储地址
( j1 Q9 {5 U3 f' F3 _( g0 J4 o! C
        就好像有初始值相当于交了押金,会给你预定包间,虽然你还没住但是已经有了房间号,而你不初始化只有到了再订包间,所以在这之前你完全不知道你的房间号。并且如果你来晚了还有可能没有包间可用,已经被别人包完了,对应到单片机就是堆栈溢出了。那如果你预定都预定不到的话,就是内存不够了。
. ]5 G' g# f& {* \: n  M$ D' M9 P$ S" n
作者:mymymind
5 y5 s1 t8 I8 o1 Q! |. `  ^- c0 l; q6 u+ N! P# u$ l. K, O

, b- u. b7 K- Y' V: D5 l  ]
赞 收藏 评论0 发布时间:2022-8-28 21:55

举报

0个回答

所属标签

相似技术帖

官网相关资源

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