网站首页 > 技术文章 正文
学习STM32单片机的时候,总是能遇到“堆栈”这个概念。分享本文,希望对你理解堆栈有帮助。
对于了解一点汇编编程的人,就可以知道,堆栈是内存中一段连续的存储区域,用来保存一些临时数据。堆栈操作由PUSH、POP两条指令来完成。而程序内存可以分为几个区:
- 栈区(stack)
- 堆区(Heap)
- 全局区(static)
- 文字常亮区程序代码区
程序编译之后,全局变量,静态变量已经分配好内存空间,在函数运行时,程序需要为局部变量分配栈空间,当中断来时,也需要将函数指针入栈,保护现场,以便于中断处理完之后再回到之前执行的函数。
栈是从高到低分配,堆是从低到高分配。
普通单片机与STM32单片机中堆栈的区别
普通单片机启动时,不需要用bootloader将代码从ROM搬移到RAM。
但是STM32单片机需要,可以参考相关文章:STM32代码的启动过程。这里我们可以先看看单片机程序执行的过程,单片机执行分三个步骤:
- 取指令
- 分析指令
- 执行指令
根据PC的值从程序存储器读出指令,送到指令寄存器。然后分析执行执行。这样单片机就从内部程序存储器去代码指令,从RAM存取相关数据。
RAM取数的速度是远高于ROM的,但是普通单片机因为本身运行频率不高,所以从ROM取指令慢并不影响。
而STM32的CPU运行的频率高,远大于从ROM读写的速度。所以需要用bootloader将代码从ROM搬移到RAM,相关文章:单片机中的RAM vs ROM。
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。
其实堆栈就是单片机中的一些存储单元,这些存储单元被指定保存一些特殊信息,比如地址(保护断点)和数据(保护现场)。
嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!
无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。
点击这里找小助理0元领取: 点击文中蓝色字体即可领取
如果非要给他加几个特点的话那就是:
- 这些存储单元中的内容都是程序执行过程中被中断打断时,事故现场的一些相关参数。如果不保存这些参数,单片机执行完中断函数后就无法回到主程序继续执行了。
- 这些存储单元的地址被记在了一个叫做堆栈指针(SP)的地方。
结合STM32的开发讲述堆栈
从上面的描述可以看得出来,在代码中是如何占用堆和栈的。可能很多人还是无法理解,这里再结合STM32的开发过程中与堆栈相关的内容来进行讲述。
如何设置STM32的堆栈大小?
在基于MDK的启动文件开始,有一段汇编代码是分配堆栈大小的。
这里重点知道堆栈数值大小就行。还有一段AREA(区域),表示分配一段堆栈数据段。数值大小可以自己修改,也可以使用STM32CubeMX数值大小配置,如下图所示。
STM32F1默认设置值0x400,也就是1K大小。
Stack_Size EQU 0x400
函数体内局部变量:
void Fun(void){ char i; int Tmp[256]; //...}
局部变量总共占用了256*4 + 1字节的栈空间。所以,在函数内有较多局部变量时,就需要注意是否超过我们配置的堆栈大小。
函数参数:
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
这里要强调一点:传递指针只占4字节,如果传递的是结构体,就会占用结构大小空间。提示:在函数嵌套,递归时,系统仍会占用栈空间。
堆(Heap)的默认设置0x200(512)字节。
Heap_Size EQU 0x200
大部分人应该很少使用malloc来分配堆空间。虽然堆上的数据只要程序员不释放空间就可以一直访问,但是,如果忘记了释放堆内存,那么将会造成内存泄漏,甚至致命的潜在错误。
MDK中RAM占用大小分析
经常在线调试的人,可能会分析一些底层的内容。这里结合MDK-ARM来分析一下RAM占用大小的问题。在MDK编译之后,会有一段RAM大小信息:
这里4+6=1640,转换成16进制就是0x668,在进行在调试时,会出现:
这个MSP就是主堆栈指针,一般我们复位之后指向的位置,复位指向的其实是栈顶:
而MSP指向地址0x20000668是0x20000000偏移0x668而得来。具体哪些地方占用了RAM,可以参看map文件中【Image Symbol Table】处的内容:
原文链接:
https://mp.weixin.qq.com/s/ftQHZOFNi3UdRe349mQC_Q转载自:STM32嵌入式开发
原文链接:详解STM32单片机的堆栈
本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。
猜你喜欢
- 2025-06-28 电脑蓝屏提示代码0x00000023的解决方法
- 2025-06-28 “错误代码0X80004005”无法访问共享电脑的解决方法
- 2025-06-28 电脑蓝屏错误代码详解以及蓝屏原因
- 2025-06-28 修电脑一波三折,反复拆装拆到吐,蓝屏代码0×00000124终解决
- 2025-06-28 共享打印机突然无法连接打印,错误代码0x0000011b
- 2025-06-28 打印机无法共享的实用解决方法(打印机无法共享什么原因)
- 2025-06-28 win7旗舰版错误代码0x80004005怎么解决?
- 2025-06-28 年轻的朋友速来看教你一招电脑蓝屏详解
- 2025-06-28 电脑突然蓝屏怎么办?1分钟教你轻松搞定,无需重装系统
- 2025-06-28 开启电脑防火墙提示错误代码0x80070422,应该怎么办?
- 1506℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 484℃MySQL service启动脚本浅析(r12笔记第59天)
- 484℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 462℃启用MySQL查询缓存(mysql8.0查询缓存)
- 458℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 442℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 421℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 418℃MySQL server PID file could not be found!失败
- 最近发表
-
- 你真的懂NAS网络?以极空间为例,介绍解绑Bond、虚拟网桥、Bond
- Edge浏览器首个安全漏洞曝光:Win10正式版前被发现
- 知名服务的端口号大全,2025年最新整理,收藏!
- 某教程学习笔记(一):1、windows基础
- NAS教程丨如何通过DDNS实现SMB服务的远程访问?
- 怎么用淘汰的旧电脑构建家庭NAS?(旧电脑搭建nas私人网盘)
- 网络安全:白帽子如何利用Kali Linux的MSF对Win7进行永恒之蓝攻防
- 445端口是啥?445端口怎么关闭?(电脑445端口关闭有什么影响)
- 微软被曝高危漏洞被称为“永恒之黑”,或波及全球10万服务器
- S7-200SMART从端口定义到程序指令,说清楚如何实现自由口通信
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)