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

STM32的内存分配

[复制链接]
STMCU-管管 发布时间:2020-10-9 10:10
STM32的内存分配
7 ^& J6 [  b% x" K, g" {" C: [' G* l: L) w% L2 J0 C4 Z0 S1 z

/ Y/ P4 C' I$ y0 x使用keil编写代码,局部变量和全局变量分别存放在什么地方?" `( X8 O8 m, L1 G
1、局部变量和全局变量, D1 h5 s3 o2 j$ M  l0 B1 {
1.1、局部变量) j3 u/ f- B6 @
在一个函数内部定义的变量是内部变量,它只在本函数范围内有效,也就是说只有在本函数内才能使用它们,在此函数以外是不能使用这些变量的,这称为局部变量。
5 ?7 U. f( Y9 m1 M' R! D使用局部变量注意以下问题:) F6 t2 G0 `$ R% C% a1 r
不同函数中可以使用相同名字的变量,它们代表不同的对象,互不干扰。, a$ M/ h3 k; }& Q
形式参数也是局部变量。+ Q( a1 Q$ Y8 N; U: p! Q2 [
局部变量的作用域在函数内部。" h/ D& W8 M+ ~* X% w: d
1.2、全局变量
- R8 G( ?: M9 d1 z2 t- m! M/ K0 P
在函数内部定义的变量是局部变量,而在函数之外定义的变量称为外部变量,也就是全局变量。使用全局变量的注意事项:. W! n: Q8 ]7 m! N! e, i5 [6 h
全局变量可以为本文件中其他函数所共用。它的有效范围为从定义变量的位置开始到本源文件结束。- ~7 {! |, o" {8 i& ]. \
设置全局变量的作用是增加了函数间数据联系的渠道。3 ~% H7 d" a; e  h- e3 C6 m
如果在同一个源文件中,外部变量和局部变量同名,则在局部变量的作用范围内,外部变量被“屏蔽”, 即外部变量将不起作用。; K: u: T* @# S, q8 }; P; w
int g_a;//全局变量

, U0 B2 z' Z9 q$ o3 e9 Wint main(void)! r) I  z2 j+ P- t6 e
{' l2 w& Y6 r4 v( W, k' W
    int b;//局部变量
5 x& E  O0 x2 v% y& ?. S}
# I. e& O1 `. p3 j! K: [$ a1.3、用 static 声明局部或者全局变量

) ]; E# U4 `) E有时候希望函数中的局部变量的值在函数调用结束后不消失而保留原值,即占用的存储单元不释放,在下一次该函数调用时,该变量已有值,就是上一次函数调用结束时的值。这时可以使用关键字 static 进行声明。% @9 n$ o( P. [1 f7 `/ j
用 static 声明一个变量的作用:
) ]6 c* e1 z2 q, b4 y. w, K* |  e
对局部变量用 static 声明,则使用该变量在整个程序执行期间不释放,为其分配的的空间始终存在。
( L! M5 H! y  w$ ]  \全局变量用 static声明,则该变量的作用域只限于本文件模块(即被声明的文件中) 。9 K. a3 n% K  S: y/ {; u; S5 s+ q
局部变量、全局变量和代码在STM32中是如何存储的?先了解一下,存储器的简单概念; S) V+ ~+ e+ M! p' D: V! P$ D6 M
2、何为RAM和ROM?% a" E3 F& k) I
RAM:是“Random Access Memory”的缩写,被译为随机存储器。2 X6 k& w; \: n# P' p: r9 |
可以随时进行读写操作,速度很快,掉电以后数据会丢失。比如内存条、 SRAM、 SDRAM、 DDR 等都是 RAM。RAM 一般用来保存程序数据、中间结果。
% s* d4 M% i' S; t& ]比如我们在程序中定义了一个变量 a,然后对这个 a 进行读写操作。
! I3 x) E( e8 |
ROM: 是“Read Only Memory”的缩写,意为只能读的存储器。
1 g0 a5 x" f' y* S笔者认为目前“只读存储器”这个定义不准确。比如我们买手机,通常会告诉你这个手机是 4+64 或 6+128 配置,说的就是 RAM 为 4GB 或 6GB, ROM 为 64G 或128GB。但是这个 ROM 是 Flash,比如 EMMC 或 UFS 存储器,因为历史原因,很多人还是将Flash 叫做 ROM。但是 EMMC 和 UFS,甚至是 NAND Flash,这些都是可以进行写操作的!只是写起来比较麻烦,要先发送要先进行擦除,然后在发送要写的地址或扇区,最后才是要写入的数据。% N7 B3 O! d6 N) }6 x* }
学习过 STM32,使用过 WM25QXX 系列的 SPI Flash 的同学应该深有体会。
6 r: k6 ~/ |& B% t
可以看出,相比于 RAM,向 ROM 或者 Flash 写入数据要复杂很多,因此意味着速度就会变慢(相比 RAM),% N1 h) Z1 O) w( b
但是 ROM 和 Flash 可以将容量做的很大,而且掉电以后数据不会丢失,适合用来存储资料,比4 A; R3 n; x0 z3 V
如音乐、图片、视频等信息。

6 F/ h6 q  l5 T综上所述, RAM 速度快,可以直接和 CPU 进行通信,但是掉电以后数据会丢失,容量不
6 o3 s' J- V3 P8 j, T1 Y  U( J容易做大(和同价格的 Flash 相比)。ROM(目前来说,更适合叫做 Flash)速度虽然慢,但是容量6 q1 e3 n/ m' y  H2 s; Q/ }
大、适合存储数据。
" G/ T% w0 K& \  J, ^' o
STM32407有192KB的RAM。128KB的SRAM,64KB的CCMRAM# |4 r4 j$ {! m$ x( U; t
3、Keil编译大小及存储说明- c2 A% J1 y2 h2 h3 ~% U. o. i" [# v
Keil编译文件大小9 A4 `9 y: ^3 @2 m0 l% u9 F
Keil编译文件大小
* ^* p* @- P! f0 c' O1 l3.1、说明:
1 k( h0 e/ G4 Y
Code:指代码的大小;# Y" _" }; e" ^. [; [
Ro-data:指除了内联数据(inline data)之外的常量数据;
. u5 r1 ~# c/ H2 ^/ @" X2 x; qRW-data:指可读写(RW)、已初始化的变量数据;$ z8 H  H( t& e& ?) H
ZI-data:指未初始化(ZI)的变量数据;

) n' w, K" m4 z! C/ u  D+ N3.2、总结:- s! K4 w! R" ~! A& n5 R
Code、Ro-data:位于FLASH中;
  K% |* s  h' b) C# DRW-data、ZI-data:位于RAM中;- d3 \3 q) ?$ T8 J. ~( y
3.3、提醒:

% ^' r  v' E- S& }8 v7 p0 PRW-data已初始化的数据会存储在Flash中,上电会从FLASH搬移至RAM中。
3 l( A* U7 W0 r! u7 J  t; I9 |3.4、五种内存说明
: t. i! p+ w4 I; {4 |' I1 Z1、栈区(stack): 用于局部变量,函数调时现场保护和返回地址,函数的形参等。) I! B- I6 f* y2 g; J. b
2、堆区(heap) :一般由程序员(使用malloc)分配和(使用free)释放, 若程序员不释放,则一直被占用。一般来说,STM32单片机类的程序一般没有使用堆。9 a9 Z$ S" D" A$ S( w' R& _  T
3、全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。1 l4 R# A7 {' _2 V6 W) m
4、文字常量区(const) :常量字符串就是放在这里的。
2 Z" b% o6 P# k4 S5、程序代码区 (code):存放函数体的二进制代码。: W/ P4 x+ A- G+ b
  1. uint32_t a = 0; //全局初始化区, 可以被其他 c 文件 extern 引用3 U4 l/ \- U# G1 [4 K" E
  2. static uint32_t ss = 0; //静态变量,只允许在本文件使用
    " }. B! P7 z& ?  N( a! y
  3. uint8_t *p1; //全局未初始化区' G# ^% N4 R4 z' V" h8 h+ F9 m
  4. int main(void)
    , {& ~2 r0 W! E
  5. {
    , K' m- g3 V3 A0 i% @
  6.     uint32_t b; //栈9 Q0 S3 d3 C/ P4 d0 P2 m
  7.     uint8_t s[] = "abc"; //栈9 L9 I; @, N6 H9 p7 S8 o
  8.     uint8_t *p2; //栈$ g( y+ i6 P- P& ]
  9.     uint8_t *p3 = "123456"; //123456\0 在常量区, p3 在栈上。* @# B+ w( k/ e" }' [; d. ^- ~
  10.     static uint32_t c =0; //全局(静态)初始化区& d8 {: N4 a6 ]. {+ V
  11.     p1 = (uint8_t *)malloc(10); //在堆区申请了 10 个字节空间& K2 X9 T5 B4 _0 ?$ W5 ?
  12.     p2 = (uint8_t *)malloc(20); //在堆区申请了 20 个字节空间
    ' |! j/ N8 o0 ?' [3 ]
  13.     strcpy(p1, "123456"); /* 123456 字符串(结束符号是 0(\0),总长度 7)放在常量区,& @& ?  ~" S4 x$ }
  14.     编译器可能会将它与 p3 所指向的"123456"优化成一个地方 */
    + c( p+ c5 {. Q: ?. _
  15. }
复制代码
通过查看 MAP 文件,可以看全局变量在 RAM 中的位置:

; u; r" a. v4 H, ^
  1. Symbol Name                Value           Ov Type             Size            Object(Section)# S4 T: W( y% G* g
  2. a                          0x20000000      Data                4               main.o(.data)
    / }  H. O; `: G
  3. p1                         0x2000000c      Data                4               main.o(.data)4 U, @% Q0 W6 Q! P
  4. ss                      0x20000004      Data                4               main.o(.data)
    6 T% r( j( @5 i0 v+ ~* @4 z
复制代码
9 @8 C! s# v9 n9 ?

, e* P2 ?' N/ I& d3 `# B8 t/ h( [* I9 a
赞 收藏 评论0 发布时间:2020-10-9 10:10

举报

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