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

详解STM32单片机的堆栈

[复制链接]
STMCU小助手 发布时间:2022-10-31 22:13
学习STM32单片机的时候,总是能遇到“堆栈”这个概念。分享本文,希望对你理解堆栈有帮助。    对于了解一点汇编编程的人,就可以知道,堆栈是内存中一段连续的存储区域,用来保存一些临时数据。堆栈操作由PUSH、POP两条指令来完成。而程序内存可以分为几个区:
  • 栈区(stack)
  • 堆区(Heap)
  • 全局区(static)
  • 文字常亮区程序代码区
    : i0 R1 Y1 C9 T9 b: j2 r2 m
    程序编译之后,全局变量,静态变量已经分配好内存空间,在函数运行时,程序需要为局部变量分配栈空间,当中断来时,也需要将函数指针入栈,保护现场,以便于中断处理完之后再回到之前执行的函数。    栈是从高到低分配,堆是从低到高分配。7 S( ~2 Y! M2 M
普通单片机与STM32单片机中堆栈的区别
' m3 _  j' H! H% G& ~  `# \/ _    普通单片机启动时,不需要用bootloader将代码从ROM搬移到RAM。
这里我们可以先看看单片机程序执行的过程,单片机执行分三个步骤:
  • 取指令
  • 分析指令
  • 执行指令+ Z2 E2 r) j4 p* \& {* r4 ?
    根据PC的值从程序存储器读出指令,送到指令寄存器。然后分析执行执行。这样单片机就从内部程序存储器去代码指令,从RAM存取相关数据。" x( O3 d- r1 n( l3 u
    RAM取数的速度是远高于ROM的,但是普通单片机因为本身运行频率不高,所以从ROM取指令慢并不影响。0 D; C; S' U7 y1 D
    而STM32的CPU运行的频率高,远大于从ROM读写的速度。所以需要用bootloader将代码从ROM搬移到RAM。
0 m. g5 d( B8 c+ Y  使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。* {  b. I, J8 @) X  W% Z
    其实堆栈就是单片机中的一些存储单元,这些存储单元被指定保存一些特殊信息,比如地址(保护断点)和数据(保护现场)。( w/ r" J  l% v8 V" V/ \
    如果非要给他加几个特点的话那就是:
  • 这些存储单元中的内容都是程序执行过程中被中断打断时,事故现场的一些相关参数。如果不保存这些参数,单片机执行完中断函数后就无法回到主程序继续执行了。
  • 这些存储单元的地址被记在了一个叫做堆栈指针(SP)的地方。
    2 W4 e; C% L  c; L

5 j& U4 ~! c. i4 ]& a( D
+ Y7 Y, R( c6 l( ~: B2 x
结合STM32的开发讲述堆栈6 A+ _: }2 u/ a5 ^- ?
    从上面的描述可以看得出来,在代码中是如何占用堆和栈的。可能很多人还是无法理解,这里再结合STM32的开发过程中与堆栈相关的内容来进行讲述。
8 s$ `0 h/ }; C- R: B6 c5 P    如何设置STM32的堆栈大小?
' n( w/ B5 V4 n6 `* ^2 A: z9 l    在基于MDK的启动文件开始,有一段汇编代码是分配堆栈大小的。) _3 Q2 `5 U: l9 ~( ~& u
2 b; c; t; B) G4 B6 Q0 V
8 O6 s2 x9 f/ K% p
微信图片_20221031215329.png
. T5 T  H: u+ L
/ W! z0 W$ y0 n* f0 V+ s! C
( W; N! z/ a, \/ U) c* w5 S; c9 F& [5 _
    这里重点知道堆栈数值大小就行。还有一段AREA(区域),表示分配一段堆栈数据段。数值大小可以自己修改,也可以使用STM32CubeMX数值大小配置,如下图所示。
" H5 m* T; X- I3 X7 T% R: i
4 U+ O, E6 b2 {, D7 r. r7 B

2 k$ ]9 t/ c4 G  t 微信图片_20221031215326.png ( _* q2 Y6 i/ n+ \' g

% |8 g, i7 V, k/ N5 v

$ F9 ?0 z- M( z+ `/ R0 w9 N1 v    STM32F1默认设置值0x400,也就是1K大小。) `! n4 ]' c5 D/ Y

, Q4 Q+ b7 \" U5 R: P

& L5 R  x0 {" O2 V. t) ^: `/ SStack_Size EQU 0x400 6 ]) H8 r0 X+ K
3 B1 b9 U( o* d. D" a
. }, L# n4 i8 N2 A4 c
   函数体内局部变量:7 B' m# S% u9 l) L  ?  z$ I1 H4 T
void Fun(void){ char i; int Tmp[256]; //...}    局部变量总共占用了256*4 + 1字节的栈空间。所以,在函数内有较多局部变量时,就需要注意是否超过我们配置的堆栈大小。- J/ W7 h6 X6 m! ]$ z$ f8 I

7 g  V7 z# U4 b3 y( ~9 Y
7 v' h+ I# ?. [4 m# u1 [- g
    函数参数:
8 d  r- l* ]/ ~: L7 g8 g4 z
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)    这里要强调一点:传递指针只占4字节,如果传递的是结构体,就会占用结构大小空间。提示:在函数嵌套,递归时,系统仍会占用栈空间。
- M3 X+ M' e" F, ^
) J+ z4 q$ M" P4 |0 Y) ^4 L
( {4 Q/ l% Y  t6 ~3 x
    堆(Heap)的默认设置0x200(512)字节。
: u* V6 h, B9 f& E8 A- C
Heap_Size EQU 0x200
! c: C- s- l& V
/ X5 O( U+ F0 i1 |+ R& ~

% ^$ c3 a- t( P  W) s    大部分人应该很少使用malloc来分配堆空间。虽然堆上的数据只要程序员不释放空间就可以一直访问,但是,如果忘记了释放堆内存,那么将会造成内存泄漏,甚至致命的潜在错误。
% D8 ^- b" n2 i: T! n5 O7 ?+ }) r7 i4 Q1 v3 O/ Y
6 t$ P' c3 i, i1 b& b; k
MDK中RAM占用大小分析
5 R8 v6 H* Y4 w" g' Z   经常在线调试的人,可能会分析一些底层的内容。这里结合MDK-ARM来分析一下RAM占用大小的问题。在MDK编译之后,会有一段RAM大小信息:
2 o9 {) F' h" }+ J0 Z& h& Q3 V4 _8 d3 e9 P8 [; a

7 P$ ^6 t3 O2 \/ b! F$ d' L: D- \+ b 微信图片_20221031215322.png    
4 {( G2 m* b! b0 G# q5 D8 t& S$ T! G: R: t8 Y
6 I8 y! u8 `% B5 V9 l/ F" l
这里4+6=1640,转换成16进制就是0x668,在进行在调试时,会出现:
8 H9 @4 Q( K% K, U; W
  P* ]# ^6 K8 K2 ^$ `
微信图片_20221031215319.png 3 q$ Y, f9 b6 t/ S  ^

8 u9 G5 f. K( y! f: s" k( ~3 A

+ B5 U3 ?* L% l7 b6 q; I    这个MSP就是主堆栈指针,一般我们复位之后指向的位置,复位指向的其实是栈顶:
8 _# f) C$ Z& s5 f2 r6 x0 {( ]# t
" x6 _- c* z% M& L$ c

/ t6 K+ O1 ]3 M# H: W& w 微信图片_20221031215316.png    
+ K" R( X3 ?0 s$ T( c
& `0 }4 u+ |* x5 N, Y0 |0 U: W+ O
* G  F7 p" f7 R6 l! ?; p
而MSP指向地址0x20000668是0x20000000偏移0x668而得来。具体哪些地方占用了RAM,可以参看map文件中【Image Symbol Table】处的内容:9 G% N; l4 T4 ~

$ N8 W/ W* {, f 微信图片_20221031215312.png ) [% C2 R. h- I& g' i7 }* U8 v
+ r( o. j+ F) r
6 q. o8 K3 Y* s3 b* J* y
转载自:STM32嵌入式开发" g" }/ u2 p7 \$ N) @' n# b& ~
收藏 评论0 发布时间:2022-10-31 22:13

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版