0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

学习STM32单片机,要理解它的堆栈

lcdz66 来源:雨飞工作室 2023-10-29 17:12 次阅读

学习STM32单片机的时候,总是能遇到 “堆栈” 这个概念。对于了解一点汇编编程的人,就可以知道,堆栈是内存中一段连续的存储区域,用来保存一些临时数据。堆栈操作由 PUSH、POP 两条指令来完成。而程序内存可以分为几个区:栈区(stack)、堆区(Heap)、全局区(static)、字符常量区、程序代码区。

栈,用于存放局部变量,局部数组等; 堆,用于malloc申请内存空间; 全局静态区,用于保存全局变量和静态变量; 字符常量区,用于保存字符串等; 代码区,用于保存程序的二进制代码。

程序编译之后,全局变量,静态变量已经分配好内存空间。在函数运行时,程序需要为局部变量分配栈空间,当中断来时,也需要将函数指针入栈,保护现场,以便于中断处理完之后再回到之前执行的函数。栈是从高到低分配,堆是从低到高分配。

普通单片机与STM32单片机中堆栈的区别

普通单片机启动时,不需要用bootloader 将代码从ROM搬移到RAM;但是STM32单片机需要。这里我们可以先看看单片机程序执行的过程,单片机执行分三个步骤:取指令、分析指令、执行指令。根据PC的值从程序存储器读出指令,送到指令寄存器。然后分析、执行。这样单片机就从内部程序存储器取代码指令,从RAM 存取相关数据。RAM 取数据的速度是远高于 ROM 的,但是普通单片机因为本身运行频率不高,所以从 ROM 取指令慢并不影响。

而STM32的CPU运行的频率高,远大于从ROM读写的速度。所以需要用 bootloader 将代码从ROM搬移到 RAM(请注意,这部分表述不准确)。使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。 其实堆栈就是单片机中的一些存储单元,这些存储单元被指定保存一些特殊信息,比如地址(保护断点)和数据(保护现场)。如果非要给堆栈加几个特点的话,那就是:

这些存储单元中的内容都是程序执行过程中被中断打断时,事故现场的一些相关参数。如果不保存这些参数,单片机执行完中断函数后就无法回到主程序继续执行了。

这些存储单元的地址被记在了一个叫做堆栈指针(SP)的地方。

结合STM32的开发讲述堆栈

从上面的描述可以看得出来,在代码中是如何占用堆和栈的。可能很多人还是无法理解,这里再结合STM32的开发过程中与堆栈相关的内容来进行讲述。 如何设置STM32的堆栈大小?在基于MDK的启动文件开始,有一段汇编代码是分配堆栈大小的。

ee413696-7633-11ee-939d-92fbcf53809c.png

这里重点知道堆栈数值大小就行。还有一段 AREA(区域),表示分配一段堆栈数据段。数值大小可以自己修改,也可以使用STM32CubeMX数值大小配置,如下图所示。

ee4eaec0-7633-11ee-939d-92fbcf53809c.png

STM32F1默认设置值 0x400,也就是1K大小。

Stack_Size EQU 0x400函数体内局部变量:void Fun(void) { chari; intTmp[256];//... }局部变量总共占用了256*4+1字节的栈空间。所以,在函数内有较多局部变量时,就需要注意是否超过我们配置的堆栈大小。 函数参数:voidHAL_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大小信息:

ee6a522e-7633-11ee-939d-92fbcf53809c.png

这里4+1636=1640,转换成16进制就是0x668,在线进行调试时,会出现:

ee6dccba-7633-11ee-939d-92fbcf53809c.png

这个MSP就是主堆栈指针,一般我们复位之后指向的位置,复位指向的其实是栈顶:

ee7bce8c-7633-11ee-939d-92fbcf53809c.png

而MSP指向地址0x20000668是0x20000000偏移0x668 而得来。具体哪些地方占用了RAM,可以参看map文件中【Image Symbol Table】处的内容:

ee8cb198-7633-11ee-939d-92fbcf53809c.png

STM32栈空间溢出的处理方法

在写STM32程序时会用到一些局部变量,函数中的局部变量是存在栈空间当中,在

STM32的启动文件当中可以设置栈空间大小。如果在函数当中定义的局部变量超过栈空间大小编译时不会报错,但运行时极有可能出现错误,甚至会导致程序卡死,那么该如何处理呢?

方法一:修改栈空间大小1、找到启动文件hd.s (例如:是stm32f103 则是 startup_stm32f10x_hd.s) 2、找到启动文件当中的栈空间大小定义:

//系统默认栈空间大小为 1K Stack_SizeEQU0x000004003、修改栈空间大小//我们修改为4K Stack_SizeEQU0x00001000方法二:将局部变量改为全局变量。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6035

    文章

    44554

    浏览量

    634593
  • 寄存器
    +关注

    关注

    31

    文章

    5336

    浏览量

    120224
  • STM32
    +关注

    关注

    2270

    文章

    10895

    浏览量

    355715
  • 堆栈
    +关注

    关注

    0

    文章

    182

    浏览量

    19753

原文标题:学习STM32单片机,要理解它的堆栈

文章出处:【微信号:雨飞工作室,微信公众号:雨飞工作室】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    STM32单片机学习笔记(5):ADC模数转换器

    利用CubMX生成基于32单片机的HAl库工程,然后编写程序在proteus上仿真验证。本项目最适合没有开发板的同学学习,零成本利用仿真软件率先入门STM32单片机。这是第五部分针对
    发表于 07-19 15:34 844次阅读
    <b class='flag-5'>STM32</b><b class='flag-5'>单片机</b><b class='flag-5'>学习</b>笔记(5):ADC模数转换器

    STM32单片机学习笔记(6):PWM波形产生

    利用CubMX生成基于32单片机的HAl库工程,然后编写程序在proteus上仿真验证。本项目最适合没有开发板的同学学习,零成本利用仿真软件率先入门STM32单片机。这是第六部分针对
    发表于 07-19 15:34 2233次阅读
    <b class='flag-5'>STM32</b><b class='flag-5'>单片机</b><b class='flag-5'>学习</b>笔记(6):PWM波形产生

    详解STM32单片机堆栈

    学习STM32单片机的时候,总是能遇到“堆栈”这个概念。分享本文,希望对你理解堆栈有帮助。 对于
    发表于 01-12 11:30

    单片机堆栈理解

    参考链接:对单片机堆栈理解STM8数据手册给出了堆栈的位置及大小。栈是从高到低分配,堆是从低到高分配。堆栈是内存中一段连续的存储区域,用来
    发表于 02-21 07:29

    详细的STM32单片机学习笔记

    STM32单片机学习笔记给大家参考
    发表于 11-23 17:55 1.5w次阅读

    单片机堆栈的小故事让你更容易理解堆栈的概念

    因为单片机有CPU、存储器、IO等等,使他(人性化一点以配合下文)看起来就像一个比较小的计算机,所以在理解单片机的时候如果能把你之前有的那些也许仅仅是直觉上的对计算机的理解融入进来的话
    的头像 发表于 09-23 15:58 4478次阅读

    51单片机STM32单片机有哪些区别

    大部分朋友可能都知道51单片机stm32单片机也知道一般入门会先学习51单片机学习
    发表于 08-13 17:32 17次下载
    51<b class='flag-5'>单片机</b>和<b class='flag-5'>STM32</b><b class='flag-5'>单片机</b>有哪些区别

    什么是单片机堆栈单片机堆栈有什么作用和原理说明

    什么是单片机堆栈?在片内RAM中,常常指定一个专门的区域来存放某些特别的数据,遵循顺序存取和后进先出(LIFO/FILO)的原则,这个RAM区叫
    的头像 发表于 08-03 09:29 2w次阅读

    STM32单片机堆栈深入解析

    学习STM32单片机的时候,总是能遇到堆栈这个概念。分享本文,希望对你理解堆栈有帮助。 对于了解
    的头像 发表于 10-30 17:31 4704次阅读
    <b class='flag-5'>STM32</b><b class='flag-5'>单片机</b>的<b class='flag-5'>堆栈</b>深入解析

    单片机堆栈是什么?的原理和作用又是什么?

    什么是单片机堆栈?在片内RAM中,常常指定一个专门的区域来存放某些特别的数据,遵循顺序存取和后进先出(LIFO/FILO)的原则,这个RAM区叫
    发表于 11-11 10:51 70次下载
    <b class='flag-5'>单片机</b><b class='flag-5'>堆栈</b>是什么?<b class='flag-5'>它</b>的原理和作用又是什么?

    STM32单片用什么编程?如何学习STM32单片机开发

    在大学刚开始接触51单片机的时候,我们学习的都是汇编指令,再到后来学习了C语言,用C语言代替汇编指令来开发编程单片机STM32
    发表于 11-13 12:51 28次下载
    <b class='flag-5'>STM32</b><b class='flag-5'>单片</b>用什么编程?如何<b class='flag-5'>学习</b><b class='flag-5'>STM32</b><b class='flag-5'>单片机</b>开发

    单片机学习STM32 和 51 区别

    单片机学习STM32 和 51 区别
    发表于 11-14 15:36 18次下载
    【<b class='flag-5'>单片机</b><b class='flag-5'>学习</b>】<b class='flag-5'>STM32</b> 和 51 区别

    分析单片机堆栈,分享个人理解

    看关于单片机方面的书籍的时候,总是能看到别人说的一些堆栈啊什么的操作,之前看到这个术语就直接跳过,没想到去探究单片机内部的原理。但是最近课程学习微机原理这门课,需要我们写汇编程序,汇编
    发表于 11-22 09:21 6次下载
    分析<b class='flag-5'>单片机</b><b class='flag-5'>堆栈</b>,分享个人<b class='flag-5'>理解</b>

    详解STM32单片机堆栈

    学习STM32单片机的时候,总是能遇到“堆栈”这个概念。分享本文,希望对你理解堆栈有帮助。
    发表于 02-08 15:41 5次下载
    详解<b class='flag-5'>STM32</b><b class='flag-5'>单片机</b>的<b class='flag-5'>堆栈</b>

    普通单片机STM32单片机堆栈的区别

    学习STM32单片机的时候,总是能遇到“堆栈”这个概念。分享本文,希望对你理解堆栈有帮助。
    的头像 发表于 04-13 11:15 3159次阅读