单片机堆栈小知识

2023-05-16

目录

一、关于单片机堆栈的基础知识

1、STM32程序数据分类

2、STM32内存(RAM)分配

3、经典例子分析:

4、STM32堆栈位置

5、STM32栈增长方式

三、如何设置STM32的堆栈大小

1、MDK编译环境下

2、IAR 编译环境下

四、STM32单片机程序内存占用大小分析

1、MDK编译环境下

2、IAR编译环境下


一、关于单片机堆栈的基础知识

1、STM32程序数据分类

  • Code:程序代码
  • RO-data:const常量和指令
  • RW-data:初始化值不为0的全局变量
  • ZI-data:未初始化的全局变量 或 初始化值为0的全局变量

RO Size = Code + RO Data 表示程序运行时占用的FLASH大小

RW Size = RW Data + ZI Data 表示占用RAM大小

ROM Size = Code + RO Data + RW Data 表示烧写程序后占用的FLASH大小

2、STM32内存(RAM)分配

一个由C/C ++编译的程序占用的内存可分为以下几个部分:

  • 栈(stack):由编译器自动分配释放,存放函数的参数值,局部变量的值等。
  • 堆(heap):存放程序运行中被动态分配的内存,一般由程序员分配释放,若程序员不释

放,程序结束时可能由OS回收。

  • bss段:通常是指用来存放程序中未初始化的全局变量的一块内存区域,存放ZI-data数据
  • data段:通常是指用来存放程序中已初始化的全局变量的一块内存区域,存放RW-data数据

FLASH占用大致以下两个部分:

  • 文字常量区(const) :常量字符串就是放在这里的。
  • 程序代码区 (code): 存放函数体的二进制代码

3、经典例子分析:

int a = 0;              //全局初始化区
char *p1;               //全局未初始化区
main()
{
  int b;                //栈
  char s[] = "abc";     //栈
  char *p2;             //栈
  char *p3 = "123456";  //123456\0在常量区,p3在栈上。
  static int c =0;//全局(静态)初始化区
  p1 = (char *)malloc(10);
  p2 = (char *)malloc(20);   //分配得来得10和20字节的区域就在堆区。
  strcpy(p1, "123456");      //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}

在MDK编译环境下,可在map文件的"Memory Map of the image"-->"Execution Region RW_IRAM1"内容中查看程序的RAM占用及分配情况,如下【图一】【图二】

                                                                                                              【图一】

                                                                                                                【图二】

 

4、STM32堆栈位置

首先看一下STM32的地址空间映射【图三】,STM32的堆栈就是存放在片上静态SRAM中的,地址分配可以见Keil的编译map文件的"Memory Map of the image"【图四】;可见堆的地址为0x20000a08,大小为0x200,栈的地址为 0x20000c08,大小为0x400,可推算栈顶地址为:0x20000c08 + 0x400 = 0x20001008。而程序在刚运行的时候,主堆栈指针MSP指向的是程序所占用内存的最高地址【图五】,也就是栈的栈顶地址。

                                                                                                     【图三】

                                                                                                    【图四】

                                                                                                          【图五】

5、STM32栈增长方式

STM32的栈增长方式是向下增长的,也就是程序运行后,SP指针从栈顶地址开始往下给函数的局部变量分配地址 。可以通过如下代码来测试STM32单片机的栈增长方式。

//保存栈增长方向 0,向下增长;1,向上增长.
static unsigned char stack_dir;

//查找栈增长方向,结果保存在stack_dir里面.
void find_stack_direction(void)
{
    static u8 *addr = NULL; //用于存放第一个dummy的地址。
    u8 dummy;               //用于获取栈地址 
    if(addr == NULL)        //第一次进入
    {                          
        addr = &dummy;     //保存dummy的地址
        find_stack_direction ();  //递归 
    }
    else                //第二次进入 
    {  
        if(&dummy > addr)stack_dir=1; //第二次dummy的地址大于第一次dummy,那么说明栈增长方向是向上的. 
        else stack_dir=0;             //第二次dummy的地址小于第一次dummy,那么说明栈增长方向是向下的.  
    }
} 

 

三、如何设置STM32的堆栈大小

1、MDK编译环境下

通过修改.s启动文件中的 Stack_Size 和 Heap_Size大小

2、IAR 编译环境下

通过修改Linker-->Config中的CSTACK和HEAP大小

四、STM32单片机程序内存占用大小分析

map文件:通过编译器编译之后,集程序、数据及IO空间的一种映射文件。通过map文件可以知道函数大小,入口地址等一些重要信息。

1、MDK编译环境下

编译后的map文件大致有如下几个部分:在分析内存占用时主要看d、e段就行

a、Section Cross References:模块、段(入口)交叉引用

b、Removing Unused input sections from the image:移除未调用模块

c、Image Symbol Table:映射符号表

d、Memory Map of the image:内存(映射)分布,包括存储地址和运行地址分布

 

e、Image component sizes:存储组成大小,列出了各个文件中各种数据占用的内存大小

2、IAR编译环境下

编译后的map文件大致有如下几个部分:

a、MAIN INIF:关于map文件的主要信息。包含:IAR版本、日期、输出文件路径等

b、RUNTIME MODEL ATTRIBUTES:运行时MODEL属性

c、PLACEMENT SUMMARY:概述位置,即各Section(段)存储的位置

大致意思为:

"A0"段位于0x08000000,类型为intvec(初始化向量);

"P1"段位于0x08000000 至 0x0807ffff区域,类型为 ro;

"P2"段位于0x20000000 至0x2000ffff区域,类型包含:rw, block CSTACK;

段与类型一般有对应关系:

     Section         Kind

"A1": 

     .intvec           ro code(ro代码)

"P1":

     .text             ro code(ro代码)

     .rodata          const (常量)

     CODE           ro code(ro代码)

     .iar.init_table     const(常量)

     Initializer bytes   ro data(ro数据)

"P2":

     .data           inited(已初始化数据)

     .bss            zero(未初始化数据 零)

d、INIT TABLE:初始化表

e、MODULE SUMMARY:概述模块,文件所占ro代码大小、rw数据大小

f、ENTRY LIST:入口列表,包含函数、变量等入口地址

h、最后就是程序所占用的code、RO-data、RW-data

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单片机堆栈小知识 的相关文章

  • python,在tkinter窗口中用matplotlib的figure对象画图,plot图例,plot文本,plot坐标轴,plot刻度,plot网格,plot水平线

    文章目录 1 xff0c 创建一个Figure对象1 1 Figure对象 xff12 xff0c 在tkinter窗口中用matplotlib的figure对象画图 xff12 1 xff0c 效果展示 xff12 xff12 xff0c
  • python tkinter实现侧面弹出窗口,(tkinter侧拉窗口,tkinter滑动窗口),连续多次点击弹窗按钮,重复打开窗口问题

    文章目录 xff11 xff0c 效果 xff12 xff0c 代码 xff13 xff0c 连续多次点击弹窗按钮 xff0c 重复打开窗口问题 xff11 xff0c 效果 xff12 xff0c 代码 span class token
  • pugixml使用笔记

    https pugixml org docs manual html dom tree pugixml官方使用手册 1 创建xml文件信息 例如 xff1a pugi xml document xmldoc pugi xml node de
  • QQ情话糖果情话内容获取并保存

    1 下载夜神模拟器 xff0c 打开应用商店下载xposed和qq xff0c xposed里面安装trustmealready 2 打开模拟器里面的wifi设置代理 xff0c 电脑fiddler抓包 设置代理方法 1 电脑打开fiddl
  • Qscrollarea去除边框的办法

    1 代码去除 QScrollArea是派生于QFrame xff0c 如果设置QFrame的FrameShape值为NoFrame那么就可以实现边框去除 ui gt scrollArea gt setFrameShape QFrame No
  • 简单VS问题 VS2017 文件高级保存选项显示设置

    在用VS2015的时候可以在文件 文件高级保存选项中 但是在VS2017中 xff0c 这个功能不见了 xff0c 按下面方法就可以给弄出来了 1 工具 自定义 xff1b 2 点击 命令 标签 xff1b 3 在上方单选区选中 菜单栏 x
  • Qt程序启动画面播放(gif与swf两种动画格式)

    学习Qt有一段时间了 xff0c 发现一个小问题 xff0c 网上关于Qt的资料或者总结性的学习及应用文章有点少 比如 xff0c Qt完整的API xff0c 程序运行之前的启动画面如何按理想效果播放等 xff0c 每次想在项目中添加一些
  • 自己总结的QT相关资料和网址汇总

    QT官网 xff1a http www qt io download QT项目源码 xff1a http download qt io QT编程指南 xff1a https lug ustc edu cn sites qtguide QTD
  • QT程序异常结束 处理方式

    运行几个网上的程序都出现如下程序异常结束 xff0c 感觉没有任何错误 xff0c 所以就去网上搜索解决方案 xff1a 很多人都说是 xff1a 1 环境问题 2 要不就是编译器选择不符 3 还有就是有的人是在动态编译的时候提示缺少一些d
  • 【Windows版】CMake安装教程

    一 参考资料 windows 43 cmake 43 mingw 搭建c c 43 43 开发环境 二 步骤 1 官网下载CMake安装包 CMake官网 2 解压安装包 D 360Downloads Software CMake cmak
  • GNSS入门2-RTD, RTK,精度

    2 1 RTD vs RTK RTD xff08 Real Time Differential xff09 xff1a 实时码 xff08 C A码 P码 xff09 相位差分技术 xff0c 流动站与基站距离需小于100km xff0c
  • 关于嵌入式开发的C语言基础总结

    一 位操作 C语言支持的6种位操作符如下 xff1a 1 不改变其他位的值的状况下 xff0c 对某几个位进行设值 方法 xff1a 先对需要设置的位用 amp 操作符 xff08 对应位 amp 0 xff09 进行清零操作 xff0c
  • STM32 ASSERT断言机制

    调试代码经常会有跑崩的时候 xff0c 当整机调试是出问题特别让人崩溃 xff0c 断言机制能很好的定位由于参数错误导致的系统异常的情况 在代码重要的代码区 xff0c 添加断言 xff0c 相当于对出入参数做了预判操作 xff0c 当参数
  • 舵机抖动的原因分析

    舵机抖动 舵机在很多场合都会用到 xff0c 比如航模 云台等 但有时候舵机会莫名的出现抖动 xff0c 最近我也遇到了这个问题 xff0c 花了两天的时间终于解决了 舵机抖动的原因主要有以下几点 xff1a 1 电源电压不足 xff1a
  • ubuntu系统python实现串口通信

    我使用的是USB TTL串口 xff0c 下面是测试之前的一些准备工作 span class token function ls span dev span class token comment 查看设备 xff0c 插拔串口设备注意有没
  • __FILE__,__func__,__LINE__用法举例

    C语言中 xff0c FILE func LINE 常用于logout xff0c 打trace xff0c debug调试 注意 xff1a 其使用不需要定义 xff0c FILE 指示当前文件名 func 指示当前函数名 LINE 指示
  • STM32 串口超时中断+DMA接收不定长数据 比 空闲中断(IDLE)更加灵活、稳定(一)

    前言 xff1a 最近项目有使用串口接收大段不定长GPS数据的需求 xff0c 调试了很久 xff0c 终于找到一个比较好的解决办法 我觉得这个项目需求 xff08 高波特率 大段数据 不定长 xff09 十分典型 xff0c 所以在这里记
  • STM32串口通信(基于缓冲区)

    一 串口的初始化和中断设置 1 初始化GPIO xff1a 根据手册的8 1 11节 xff0c 我们可以找到下表 xff1a 在全双工的模式下 xff0c 发送引脚需要设置为推挽复用输出 xff0c 接收引脚则设置为浮空输入或带上拉的输入
  • STM32与C#上位机串口通信示例

    1 概述 串口通信是一种非常常用的通信方式 xff0c 本文首先介绍了串口硬件和协议的相关内容 xff0c 然后给出一个STM32与C 上位机通过串口通信的示例 2 串口介绍 参考这份文档 3 通信协议 为了方便数据传输 xff0c 定义了
  • 【转】23个常用的VSCode快捷键(动图演示)

    尽管我们经常使用 VS Code中的许多快捷方式 xff0c 但是我们有可能会忘记它们 这里用可视化制作了一些GIF xff0c 以便更好地记住它们 xff0c 希望对你有所帮助 VSCode中的每个命令也可以通过使用CTRL 43 SHI

随机推荐

  • HI3531编码h.264文件播放偏慢分析随笔

    现象 xff1a 编码h 264文件播放时 xff0c 无论帧率是30fps还是60fps xff0c 播放器显示帧率为25 fps 探索过程 xff1a cat proc umap venc 显示得知 xff0c 编码的的确是30fps和
  • C++ const用法详解

    const 是C 43 43 中常用的类型修饰符 常类型是指使用类型修饰符const说明的类型 xff0c 常类型的变量或对象的值是不能被更新的 目录 一 const的作用 二 const修饰普通类型的变量 三 const修饰指针变量 四
  • Source Insight 4.0打开一会就闪退 解决方法

    遇到Source Insight 4 0打开直接闪退 xff0c 请不要着急卸载 xff0c 在Source Insight 4 0快捷键上 xff0c 点击属性 xff0c 选择兼容性如下 xff1a
  • secureCRT连接ubuntu18.04

    1 安装ssh服务器 sudo apt get install openssh server 2 ssh服务器安装失败 错误提示 xff1a 下列软件包有未满足的依赖关系 xff1a openssh server 原因 xff1a 系统预置
  • STM32——USART串口通信与串口重定向

    简介 UART 通用异步收发传输器 xff08 Universal Asynchronous Receiver Transmitter xff0c 通常称 作 UART 它将要传输的资料在串行通信与并行通信之间加以转换 作为把并行输入信 号
  • 海思文件系统缺少文件himm 、i2c_read 、i2c_write 、ssp_read 、ssp_write

    原因 xff1a 海思根文件默认没有把himm i2c read i2c write ssp read ssp write工具集成在bin里 xff0c 但是在sdk中 解决办法 xff1a cd osdrv tools board reg
  • Ubuntu 18.04 Samba服务器的安装和配置(详解)

    具体步骤 xff1a 1 设置为静态IP xff1a 点击静态IP设置链接 2 更新当前软件 sudo apt get upgrade sudo apt get update sudo apt get dist upgrade 3 安装sa
  • C52单片机(AT89C52)—流水灯

    本文重点 xff1a C52流水灯代码编写 xff0c keil如何生存hex文件和proteus如何导入hex文件 1 打开keil xff0c 建立工程 xff0c 编写如下代码 include lt reg52 h gt includ
  • Hi3516EV200图像调优

    一 平台搭建 1 将Hi3516EV200 PQ V1 0 0 3 tgz放到nfs挂载目录下解压 xff0c 进入Hi3516EV200 PQ V1 0 0 3 执行StartControl sh 2 执行HiPQTools exe xf
  • Qt低延时/可集成嵌入的网络播放器 –soundTouch的使用

    背景 在观看直播的过程中 xff0c 保不齐网络出现卡的现象 xff0c 可能导致音频数据包累积了好几秒的数据 xff0c 这时候要么丢直接播放新的 xff0c 要么直接播放基音 xff0c soundTouch可以加速播放并不要变调 主要
  • 超低延时直播rtmp推流

    项目起源 xff1a 改项目主要是基于类qt av的模式 xff0c 快速集成 xff0c 将ffmpeg融入到插件当中 xff0c 并提供本地的音频设备和视频设备的查找输出 xff0c 并可以采集各类虚拟摄像头 xff0c 酷狗直播助手
  • minio 使用aws c++ 多线程下载

    C 43 43 下载 Minio 文件 下载 aws sdk cpp git clone recurse submodules GitHub aws aws sdk cpp AWS SDK for C 43 43 麒麟上编译AWS cmak
  • 拉流推流服务器设计

    背景 该服务器也是基于一个客户的需求产生的 客户那边使用的是腾讯的直播sdk xff0c 将不同终端的流推到腾讯云平台 xff0c 但是又想推到其他平台 xff0c 基于此需求 xff0c 该产品产生了 该产品通讯协议使用的是WebSock
  • 开发实现C++ RTMP直播推流sdk

    前言 rtmp即Real Time Messaging Protocol xff08 实时消息传输协议 xff09 的首字母缩写 xff0c 它是由Adobe公司提出的一种应用层的协议 xff0c 用来解决多媒体数据传输流的多路复用 xff
  • 开发实现C++ RTMP直播拉流播放器

    背景 该直播播放器的背景是来源于 拉流推流服务器设计 的一个分支 xff0c 它的重点是把拉下来的流进行解码显示播放 设计点 要实现跨平台 xff0c 目前支持的平台linux和windows要模块化和结构化可以拉各个平台的直播流要音视频同
  • 校验和计算原理

    校验和思路 首先 xff0c IP ICMP UDP和TCP报文头都有检验和字段 xff0c 大小都是16bit xff0c 算法基本上也是一样的 在发送数据时 xff0c 为了计算数据包的检验和 应该按如下步骤 xff1a 1 把校验和字
  • gb 28181的20位编码简介

    图解Python数据结构与算法 实战篇 举例 xff1a 36030000042000000003 设备的20位编码组成 国标编码由中心编码 xff08 8位 xff09 行业编码 xff08 2位 xff09 类型编码 xff08 3位
  • 继承的构造析构函数&&父类子类同名函数,变量的调用

    include lt iostream gt include 34 string 34 using namespace std class Base public int m A int m B 61 20 Base m A 61 100
  • CMake 之静态库依赖动态库,如何使用该静态库

    参考 xff1a xff08 参考文章用的Makefile 我自己用的CMake xff09 静态库链接动态库时 xff0c 如何使用该静态库 newchenxf的专栏 CSDN博客 链接静态库 1 先建立如下工程目录文件 下载 xff08
  • 单片机堆栈小知识

    目录 一 关于单片机堆栈的基础知识 1 STM32程序数据分类 2 STM32内存 RAM 分配 3 经典例子分析 xff1a 4 STM32堆栈位置 5 STM32栈增长方式 三 如何设置STM32的堆栈大小 1 MDK编译环境下 2 I