STM32内存分配以及堆栈、变量、代码等的存储位置理解与分析

这篇具有很好参考价值的文章主要介绍了STM32内存分配以及堆栈、变量、代码等的存储位置理解与分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

文中不足之处,欢迎各位同仁批评指正!

前言

        STM32的程序存储器、数据存储器、寄存器和输入输出端口被组织在同一个4GB的线性地址空间内, 地址范围为0x0000 0000至0xFFFF FFFF。其中FLASH为ROM类型,储存的数据掉电不易失;RAM中存储的数据掉电易失。以STM32F103系列为例,最多有512KB的FLASH空间以及最多64KB的RAM空间,另外还包含一个512字节的用于标准USB和CAN通信的SRAM。如下图所示:

sm32单片机内存情况,STM32,stm32,嵌入式硬件,单片机,1024程序员节

一、FLASH分段

FLASH主要是存放代码和只读数据的,细分图如下:

sm32单片机内存情况,STM32,stm32,嵌入式硬件,单片机,1024程序员节

        如上图所示,Flash又可以细分为文本段、只读数据段、数据复制段。其中文本段包含代码和代码中的常量部分,只读数据区通常存放程序中以const关键字修饰的数据,数据复制段存放的则是程序中初始化不为0的全局变量的数据,在每次单片机复位后要对这些变量重新赋值。

二、RAM分段

RAM主要用来存储数据,如下是STM32的RAM分区:

sm32单片机内存情况,STM32,stm32,嵌入式硬件,单片机,1024程序员节

data段:存放初始化非0的全局变量;

bss段:存放未初始化或初始化为0的全局变量;

Heap(堆)段:由程序员通过malloc/free申请和释放;

Stack(栈)段:存放局部变量和函数的入口地址;

        其中栈的方向是由栈顶自上而下的,堆的方向则是自下而上的,如果RAM空间有限而且一个程序中局部变量较多或申请的堆空间过大,便会造成堆和栈冲突,并造成系统崩溃(自己暂时写的程序较小,暂时没有遇到过类似问题)。

        栈,也叫堆栈,是一种先进后出,插入和删除操作都在栈顶操作的线性表。栈的作用通常是保存函数返回地址及保存局部变量。每个函数在运行时都有自己的栈空间,局部变量越多,占空间占用越大,函数间调用越深,栈空间也越大。CPU将打断前的程序运行到的地址、寄存器的值保存到栈中,即保护现场;当打断执行完以后,又从栈中读取之前保存的值,即恢复现场。

        如下是STM32启动文件(.s)中对栈和堆的定义,其中栈大小为0x400即1KB,堆大小为0x200即512Byte。

; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Stack_Size		EQU     0x400

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp
                                                  
; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size      EQU     0x200

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

三、kei中的map文件

如图在keil中编写如下程序代码,验证各变量的存储位置:

int a;
const int fconst[128] = {0};
volatile unsigned int *p;
volatile char *pc;
volatile int *pi;
volatile float *pf;

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

    volatile char c = 0;
	a = fconst[5];
	a = 123;
	p = (volatile unsigned int *)(0x40010800 + 0x0c);
    
  /* USER CODE END 1 */

其中:变量a为未初始化的全局变量,应保存在RAM的bss段;

           变量fconst为只读数据,应保存在Flash的只读数据段;

           变量p,pc,pi,pf均为指针型未初始化全局变量,也应保存在RAM的bss段,且均分配4字节的空间大小。

sm32单片机内存情况,STM32,stm32,嵌入式硬件,单片机,1024程序员节文章来源地址https://www.toymoban.com/news/detail-774090.html

到了这里,关于STM32内存分配以及堆栈、变量、代码等的存储位置理解与分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32微机系统框架、内存、存储器、寄存器

    大家好,我是 杰哥嵌入式开发 最近在出定时器系列, 但是线下班有一些学生在学习完C语言之后, 在51接触各种寄存器和对软件代码各种操作是如何在单片机系统中起到作用的感到非常的不解, 经过我的初步分析,是对嵌入式微机系统的大概雏形系统框架不熟悉导致。 所以

    2024年02月06日
    浏览(48)
  • 【STM32】STM32内存映射以及启动过程(超详细过程)

    下图是 STM32F103xCDE 型号的内存映射图。 由于 STM32 是 32 位,且其地址总线也为 32 根,所以其 理论能够寻找的地址大小为 4GB 。 从上图可以看出,左边的地址从 0x0000 0000 ~ 0xFFFF FFFF 的 4GB 是 STM32 理论分配的地址空间, STM32 实际上的空间大小 远远小于 4GB 的 。4GB 中又划分出了

    2024年02月11日
    浏览(28)
  • STM32存储器映射以及寄存器映射

    目录 1.STM32的寻址范围? 2.存储器映射 3.存储器功能划分(以STM32F1为例) 4.寄存器映射 1.32位单片机有32根地址线,每根地址线有两种状态,导通或者不导通。 2.单片机内存地址访问的存储单元是按字节编址的,而不是bit。 比如我们要访问0x01这个地址,访问的其实是一个字节的空

    2024年04月23日
    浏览(34)
  • STM32堆栈方面知识点

    最近弄json,发现经常的堆溢出,然后找问题。因为对STM32堆栈问题没有深刻认识,就花时间好好研究下了堆栈并且做了验证 1.栈地址区间确定 首先找到启动文件,我的启动文件在startup_stm32f40xx.s,一般的启动文件也都在startup_stm32fxxxx.s文件里 __initial_sp      这个参数是栈顶地

    2024年02月10日
    浏览(25)
  • STM32+FREERTOS任务堆栈大小

    在FREERTOS任务开发过程中,由于不知道具体需要分配多大的任务堆栈大小,就需要在开始开发阶段尽可能的多分配一些,不然在调试过程中会出现程序卡死或者数据通信异常的现象。 如何评估任务堆栈的分配大小问题,可以根据任务的规模以及所任务所需的数据空间大概进行

    2024年02月16日
    浏览(32)
  • 8.8 【C语言】动态内存分配与指向它的指针变量

    栈:全局变量和局部变量,全局变量是分配在内存中的静态存储区的,非静态的局部变量是分配在内存中的动态存储区的。 堆:数据临时存放在一个特别的自由存储区。 对内存的动态分配是通过系统提供的库函数来实现的,主要有malloc,calloc,free,realloc这四个函数。 1.用mallo

    2024年02月11日
    浏览(32)
  • stm32数据对齐、PRESERVE8、freertos堆栈

    避免数据在内存中跨边界存储,减少读取数据次数,提高效率,本质上是以空间换时间的做法 下图中属于同一水平位置的为同一边界 变量在同一边界里的一次存储周期就可以读取 一旦跨了上下两个边界来存储就需要至少两个存储周期来读取 根据存储器结构,如下图,参考链

    2024年02月11日
    浏览(29)
  • C++内存分配详解:栈、堆、静态存储区解析与实例演示

    概述: C++内存分配有栈、堆和静态存储区三种方式。栈自动管理,适用于局部变量;堆手动管理,使用new和delete;静态存储区适用于全局变量,具有整个程序生命周期。通过清晰的示例源代码,详细解释了它们的分配方法和使用步骤。 C++的内存分配涉及栈、堆和静态存储区

    2024年02月04日
    浏览(29)
  • STM32 显示代码提示 以及延时函数

    control + alt + space

    2023年04月09日
    浏览(31)
  • STM32 CAN协议讲解以及代码

    前面学习了CAN的一些理论知识,他在我们的STM32里面是怎么用的呢 前面讲了一些can的知识,在STM32里是什么样的呢 DBF调试冻结:处于程序调试模式才使用。可以设置CAN处于工作模式还是禁止收发状态,禁止收发时仍可以访问接受FIFO中的数据。 TTCM时间触发模式:设置CAN的时间

    2024年02月04日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包