×
单片机 > 单片机程序设计 > 详情

stm32的存储器结构

发布时间:2020-08-26 发布时间:
|

首先,先看一下stm32的存储器结构。

Flash,SRAM寄存器和输入输出端口被组织在同一个4GB的线性地址空间内。可访问的存储器空间被分成8个主要块,每个块为512MB。FLASH存储下载的程序,FLASH是ROM的一种。SRAM是存储运行程序中的数据,SRAM是RAM的一种。所以,只要你不外扩存储器,写完的程序中的所有东西也就会出现在这两个存储器中。


1.     STM32中的堆栈。

        首先要说明的是单片机是一种集成电路芯片,集成CPU、RAM、ROM、多种I/O口和中断系统、定时器/计数器等功能。CPU中包括了各种总线电路,计算电路,逻辑电路,还有各种寄存器。Stm32有通用寄存器R0‐R15 以及一些特殊功能寄存器,其中包括了堆栈指针寄存器。当stm32正常运行程序的时候,来了一个中断,CPU就需要将寄存器中的值压栈到RAM里,然后将数据所在的地址存放在堆栈寄存器中。等中断处理完成退出时,再将数据出栈到之前的寄存器中,这个在C语言里是自动完成的。


2.     STM32的堆栈大小

 定义大小在startup_stm32f2xx.s

Stack_Size      EQU     0x00000400

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp


;

Heap_Size       EQU     0x00000200

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base

 

3.     STM32的堆栈位置

通过MAP文件可知(在目标工程栏-->>双击工程名,就会在keil文件显示框出现map文件)

 HEAP                                     0x200106f8   Section      512  startup_stm32f2xx.o(HEAP)
 STACK                                   0x200108f8   Section     1024  startup_stm32f2xx.o(STACK)

 __heap_base                         0x200106f8   Data           0  startup_stm32f2xx.o(HEAP)
 __heap_limit                           0x200108f8   Data           0  startup_stm32f2xx.o(HEAP)
 __initial_sp                             0x20010cf8   Data           0  startup_stm32f2xx.o(STACK)

 

         显然 Cortex-m3资料可知:__initial_sp是堆栈指针,它就是FLASH的0x8000000地址前面4个字节(它根据堆栈大小,由编译器自动生成)显然堆和栈是相邻的。


这里为什么在FLASH中加了RW-Data还要在RAM中加上呢,原因是在初始化时RW-data从flash拷贝到RAM中,掉电后数据依然是在FLASH中的。


堆:是编译器调用动态内存分配的内存区域。

栈:是程序运行的时候局部变量的地方,所以局部变量用数组太大了都有可能造成栈溢出。

        堆栈的大小在编译器编译之后是不知道的,只有运行的时候才知道,所以需要注意一点,就是别造成堆栈溢出了。。。不然就等着hardfault找你吧。


举例:


(1)用庞大的全局变量数组来圈住一块内存,然后将这个内存拿来进行内存管理和分配。这种情况下,堆栈占用的内存就是上面说的:如果没有初始化数组,或者数组的初始化值为0,堆栈就是占用的RAM的ZI-data部分;如果数组初始化值不为0,堆栈就占用的RAM的RW-data部分。这种方式的好处是容易从逻辑上知道数据的来由和去向。


(2)就是把编译器没有用掉的RAM部分拿来做内存分配,也就是除掉RW-data+ZI-data+编译器堆+编译器栈后剩下的RAM内存中的一部分或者全部进行内存管理和分配。这样的情况下就只需要知道内存剩下部分的首地址和内存的尾地址,然后要用多少内存,就用首地址开始挖,做一个链表,把内存获取和释放相关信息链接起来,就能及时的对内存进行管理了。内存管理的算法多种多样,不详说,这样的情况下:OS的内存分配和自身局部变量或者全局变量不冲突,之前我就在这上面纠结了很久,以为函数里面的变量也是从系统的动态内存中得来的。这种方式感觉更加能够明白自己地址的开始和结束。

这两种方法我感觉没有谁更高明,因为只是一个内存的获取方式,高明的在于内存的管理和分配。


7.     STM32的堆栈生长方向和存储模式。


大端格式(Big-endian)

小端格式(Little-endian)

数据0x12345678存储格式

      大端格式

低地址

      小端格式

低地址

stm32是向下生长,采用的是小端存储。


关键字:stm32  存储器结构 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
C51 特殊功能寄存器SFR的名称和地址