STM32学习笔记-STM32堆栈区(二)

2020-01-16来源: eefocus关键字:STM32  堆栈区  分区

STM32的分区


STM32的分区从0x2000 0000(0x2000 0000是SRAM的起始地址,由此可知,堆栈等都是在RAM中的)开始。静态区,堆,栈。所有的全局变量,包括静态变量之类的,全部存储在静态存储区。 紧跟静态存储区之后的,是堆区(如没用到malloc,则没有该区),之后是栈区,栈在程序中存储局部变量。


先看启动文件startup_stm32f10x_md.s的定义:

;

Amount of memory (in bytes) allocated for Stack 


; Tailor this value to your application needs 


; Stack Configuration 


; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> 


;


Stack_Size

EQU 0x00000400


AREA

STACK, NOINIT, READWRITE, ALIGN=3 


Stack_Mem SPACE Stack_Size 


__initial_sp


; Heap Configuration 


; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> 


;


Heap_Size

EQU 0x00000200


AREA

HEAP, NOINIT, READWRITE, ALIGN=3 


__heap_base 


Heap_Mem SPACE Heap_Size 


__heap_limit


这里定义了堆栈各自大小,堆:512bytes 栈1k;

所以栈区大小有限制,我们在局部变量中不要定义大数组否则容易溢出。


再看下code ro rw zi


Code指存储到flash【Rom】中的程序代码。


ZI英语是zero initial,就是程序中用到的变量并且被系统初始化为0的变量的字节数,keil编译器默认是把你没有初始化的变量都赋值一个0,这些变量在程序运行时是保存在RAM中的。


RW是可读可写变量,就是初始化时候就已经赋值了的,RW + ZI就是你的程序总共使用的RAM字节数。


RO是程序中的指令和常量,这些值是被保存到Rom中的。


Total ROM Size (Code +RO Data + RW Data)这样所写的程序占用的ROM的字节总数,也就是说程序所下载到ROM flash 中的大小。为什么Rom中还要存RW,因为掉电后RAM中所有数据都丢失了,每次上电RAM中的数据是被重新赋值的,每次这些固定的值就是存储在Rom中的,为什么不包含ZI段呢,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间。


实际上,ROM中的指令至少应该有这样的功能:


将RW从ROM中搬到RAM中,因为RW是变量,变量不能存在ROM中。

将ZI所在的RAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中。

例子:


1,首先来看:栈(STACK)的问题.


函数的局部变量,都是存放在“栈”里面,栈的英文是:STACK。STACK的大小,我们可以在stm32的启动文件里面设置,在startup_stm32f10x_hd.s里面,开头就有:


Stack_Size     EQU     0x00000800


表示栈大小是0X800,也就是2048字节,这样,CPU处理任务的时候,函数局部变量过多可占用的大小就是:2048字节。注意:是所有在处理的函数,包括函数嵌套,递归,等等,都是从这个“栈”里面,来分配的。


所以,如果一个函数的局部变量过多,比如在函数里面定义一个u8 buf[512],这一下就占了1/4的栈大小了,再在其他函数里面来搞两下,程序崩溃是很容易的事情,这时候,一般你会进入到hardfault…


这是初学者非常容易犯的一个错误.切记不要在函数里面放N多局部变量,尤其有大数组的时候!


对于栈区,一般栈顶,也就是MSP,在程序刚运行的时候,指向程序所占用内存的最高地址。比如附件里面的这个程序序,内存占用如下图:

在这里插入图片描述

图中,我们可以看到,程序总共占用内存:20+2348字节=2368=0X940


那么程序刚开始运行的时候:MSP=0X2000 0000+0X940=0X2000 0940.

事实上,也是如此,如图:

在这里插入图片描述

图中,MSP就是:0X2000 0940,程序运行后,MSP就是从这个地址开始,往下给函数的局部变量分配地址。


2,再来说说,堆(HEAP)的问题.

全局变量,静态变量,以及内存管理所用的内存,都是属于“堆"区”,英文名:“HEAP”,与栈区不同,堆区,则从内存区域的起始地址开始分配给各个全局变量和静态变量。

堆的生长方向,都是向上的。在程序里面,所有的内存分为:堆+栈,只是他们各自的起始地址和增长方向不同,他们没有一个固定的界限,所以一旦堆栈冲突,系统就到了崩溃的时候了。

3,再说说,大小端的问题


大端模式:低位字节存在高地址上,高位字节存在低地址上

小端模式:高位字节存在高地址上,低位字节存在低地址上

STM32属于小端模式,简单的说,比如u32 temp=0X12345678;

假设temp地址在0X2000 0010.

那么在内存里面,存放就变成了:

地址

| HEX |


0X2000 0010 | 78 56 43 12 |

关键字:STM32  堆栈区  分区 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic485835.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32 keil4 extern问题
下一篇:关于STM32堆栈方面知识点

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM8 GPIO 学习(驱动LED、Button)
STM8中GPIO寄存器有:输出寄存器(ODR),输入寄存器(IDR),方向寄存器(DDR),控制寄存器1(CR1)和控制寄存器2(CR2).后面三个寄存器组和可以配置为8种GPIO的模式定义如下:/**  * @brief General Purpose I/Os (GPIO)  */typedef struct GPIO_struct{  __IO uint8_t ODR; /*!< Output Data Register */  __IO uint8_t IDR; /*!< Input Data Register */  __IO uint8_t DDR
发表于 2020-01-19
STM8 GPIO 学习(驱动LED、Button)
STM8单片机STVD环境新建工程笔记
;workspace10.修改workspace的路径为我们自己新建的STVDcosmic下。11.项目名称、路径、编译器设置如下 STM8想用C语言编程,很多人都是用的STVD+COSMIC,安装cxstm8_FSE_stm32_32K.exe软件。这里说说STVD的编译的事情,STVD本身只支持汇编语言,想用C还得借助COSMIC,所以一些设置是必须的,就是在STVD下面选择COSMIC的编译文件(这个根据软件版本自行设置),下图用我的举例单单是把两个软件安装好,编译路径配置好,编译的时候肯定还会出现STM8官方头文件找不到的错误,网上也有解决办法,就是要把头文件复制到自己的工程下,在工程下面把头文件添加进来,这样每个工程都得弄一次,实在是
发表于 2020-01-19
STM8单片机STVD环境新建工程笔记
stm8使用iar刚开始烧录ok,用着用着就下载失败解决方案
用iar写代码的时候,用stlink 下载,再排除接线和烧录器问题,基本上都是要重新用stvp烧录下错误提示:Failed to set configuration with MCU name STM8S207MB: SWIM error [30006] xxxxxxx要是嫌麻烦,可以直接用svtp开发也行1.配置iar 输出s19格式点击rebuild all 生成.s19文件文件在Debug/Exe下打开ST Visual Programmer(STVP)并设置硬件连接方式和MCU型号,这里以ST-Link连接STM8S003F为例用swim方式导入要烧录的.s19文件,设置是否锁定芯片(可以不设置)点击下载按钮Program
发表于 2020-01-19
stm8使用iar刚开始烧录ok,用着用着就下载失败解决方案
stm8系列通过option_byte 来实现端口的remaping
最近在调 stm8,发现需要用到端口映射,研究下用option byte来修改首先确定需求需要使用PC6来发射方波,用到定时器1的ch1需要激活重定向三种方式可以实现,一种是通过IAR for stm8,一种是stvp,一种是在程序执行的时候去改通过程序写flash,这儿先介绍软件的方式IAR 改option byte打开IAR打开option bytes右击 选择 激活保存到制定位置右击打开option找到地方,勾选之后,在重新rebuil all 然后烧录就行了stvp这个就简单了打开,选择型号,点开option byte下拉框选一下,然后电机这个按钮就行了打完收工
发表于 2020-01-19
stm8系列通过option_byte 来实现端口的remaping
IAR for stm8安装破解
1.下载安装包和注册机链接:https://pan.baidu.com/s/1maBEtoyps2HhcdGYxmZUcA提取码:31dn复制这段内容后打开百度网盘手机App,操作更方便哦百度云下载下来这个样子:2.双点击EWSTM8-3104-Autorun安装同意,下一步到结束 。。。 中间会装几个驱动,装就是了装完退出,打完收工3. 注册IAR for STM8是一个收费的软件,官方严厉打击盗版,若你是商业用途,建议购买正版软件。当然,我这里是针对个人开发学习的朋友而言,进行非商业用途的使用。3.1 打开上面安装好的IAR for STM8软件(没有创建桌面快捷方式,可以从开始菜单打开软件)。 Help ->
发表于 2020-01-19
IAR for stm8安装破解
STM32 下载程序时,往flash固定位置写数据配置
1.就像参数定义时使用下面语句const unsigned char Flash_user_data[16] __attribute__((at(0X08080000))) ={            0x01,0x02,0x03,0x04,               0x01,0x01,0x03,0x03,     
发表于 2020-01-19
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved