STM32 memory structure

Publisher:BlossomWhisperLatest update time:2019-01-15 Source: eefocusKeywords:stm32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

First, let's take a look at the memory structure of stm32.

Flash, SRAM registers and input/output ports are organized in the same 4GB linear address space. The accessible memory space is divided into 8 main blocks, each of which is 512MB. FLASH stores downloaded programs, and FLASH is a type of ROM. SRAM stores data in running programs, and SRAM is a type of RAM. Therefore, as long as you do not expand the memory externally, everything in the written program will appear in these two memories.


1. Stack in STM32.

        First of all, it should be explained that the microcontroller is an integrated circuit chip that integrates CPU, RAM, ROM, multiple I/O ports and interrupt systems, timers/counters and other functions. The CPU includes various bus circuits, calculation circuits, logic circuits, and various registers. Stm32 has general registers R0-R15 and some special function registers, including the stack pointer register. When stm32 runs the program normally, an interrupt comes, the CPU needs to push the value in the register into the RAM, and then store the address of the data in the stack register. When the interrupt processing is completed and exited, the data is popped to the previous register, which is done automatically in C language.


2. STM32 stack size

 Define the size in 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 stack location

Through the MAP file, you can know (in the target project column-->> double-click the project name, and the map file will appear in the keil file display box)

 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)

 

         Obviously, from the Cortex-m3 data, we know that __initial_sp is the stack pointer, which is the first 4 bytes of the 0x8000000 address of FLASH (it is automatically generated by the compiler according to the stack size). Obviously, the heap and stack are adjacent.


 

4. Space allocation of STM32 heap and stack


Stack: Expanding to lower addresses


Heap: Expanding to higher addresses


Obviously, if you define variables in sequence


The memory address of the stack variable defined first is larger than the memory address of the stack variable defined later.


The memory address of the heap variable defined first is smaller than the memory address of the heap variable defined later 


5. Stack in programming.

In programming, we often mention the stack. To be more precise, it is an area in RAM. Let's first understand a few explanations:


(1) All the contents in the program will eventually appear only in flash and RAM (not expanded externally).


(2) Segmentation is the process of storing similar data types in one area for easier management. However, as mentioned above, data in any segment will eventually end up in flash and RAM.


Focus on analyzing STM32 and the segment division in MDK.

Code, RO-data, RW-data, ZI-data segments under MDK:

Code is used to store program code.

RO-data stores const constants and instructions.

RW-data is a global variable that stores a non-zero initialization value.

ZI-data is used to store uninitialized global variables or global variables whose initialization value is 0.

Flash=Code + RO-Data + RW-Data;

RAM= RW-data+ZI-data;


        This is the size of each segment that can be obtained after MDK compilation, and the corresponding FLASH and RAM size can also be obtained. However, there are two data segments that will also occupy RAM, but they will only be occupied when the program is running, that is, the heap and the stack. In the startup file .s file of stm32, there is a stack setting. In fact, the memory occupation of this stack is allocated from the address after the RAM is allocated to RW-data+ZI-data above.


Why is RW-Data added to FLASH and RAM? The reason is that RW-data is copied from flash to RAM during initialization, and the data remains in FLASH after power failure.


Heap: is the memory area that the compiler calls dynamic memory allocation.

Stack: It is the place where local variables are stored when the program is running, so if the array of local variables is too large, it may cause stack overflow.

        The size of the stack is unknown after the compiler compiles the program. It is known only at runtime, so you need to be careful not to cause a stack overflow. Otherwise, you will get a hard fault.


Example:



Flash=4164+336+56=0x11CC

RAM=56+1832=0x760

Then: the location pointed to by the stack pointer is 0x20000760




6. Stack and its memory management in OS.

        The stack of an embedded system, no matter what method is used to obtain memory, feels similar to the heap in programming. Currently I know of two ways to obtain memory:


(1) Use a large global variable array to enclose a piece of memory, and then use this memory for memory management and allocation. In this case, the memory occupied by the stack is as mentioned above: if the array is not initialized, or the array initialization value is 0, the stack occupies the ZI-data part of the RAM; if the array initialization value is not 0, the stack occupies the RW-data part of the RAM. The advantage of this method is that it is easy to logically know the origin and destination of the data.


(2) Use the RAM that is not used by the compiler for memory allocation, that is, manage and allocate part or all of the remaining RAM after removing RW-data+ZI-data+compiler heap+compiler stack. In this case, you only need to know the first address and the last address of the remaining memory, and then start digging with the first address to determine how much memory to use. Make a linked list, link the memory acquisition and release related information, and you can manage the memory in time. There are many different algorithms for memory management, which I will not explain in detail. In this case: the memory allocation of the OS does not conflict with its own local variables or global variables. I struggled with this for a long time before, thinking that the variables in the function were also obtained from the system's dynamic memory. This method makes it easier to understand the beginning and end of your own address.

I feel that neither of these two methods is better, because it is just a way to obtain memory. The clever part lies in the management and allocation of memory.


7. Stack growth direction and storage mode of STM32.


Big-endian

Little-endian

Data 0x12345678 storage format

      Big endian format

Low Address

      Little Endian Format

Low Address

STM32 grows downward and uses little-endian storage.


Keywords:stm32 Reference address:STM32 memory structure

Previous article:Relationship between hex file size and chip flash size in STM32
Next article:Use of STM32 independent watchdog IWDG

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号