[STM32] STM32 memory mapping and startup process (super detailed process)

1. Memory mapping

1. Memory map

The figure below is the memory map of the STM32F103xCDE model.

insert image description here

2. Memory division

Since STM32 is 32 bits, and its address bus is also 32, the address size that it can theoretically find is 4GB .

As can be seen from the above figure, the 4GB address space on the left from 0x0000 0000 ~ 0xFFFF FFFF is the address space allocated by STM32 theory, and the actual space size of STM32 is much smaller than 4GB . 8 blocks are divided into 4GB, one block occupies 512MB, which are respectively used as code area, SRAM area, peripheral area, FSMC1 area, FSMC2 area, FSMC register area, unused area, and Cortex-M3 internal peripheral area.

3. Memory mapping

Mapping actually means corresponding. In fact, the memory itself does not have an address, and the theoretical address of the chip is assigned to the memory, which is memory mapping . All the on-chip peripherals of STM32 are actually memories, so all these memories need to be mapped.

Theoretically, the beginning of the address is the house number , and each byte in the storage is a room. After the memory is produced, these rooms have no address (house number). The mapping process is actually to assign these house numbers to these rooms, and assign After completion, each house number can only access its own room, and the address that has not been assigned is a reserved address. The so-called reserved address means that there is no corresponding actual storage space.

insert image description here

The FLASH in the STM32 chip is divided into two parts: the main storage block and the information block.

  • main storage block
    • Main Flash : used to store programs, the programs we write are generally stored here.
  • information block
    • System memory (system FLASH) : The startup program (BootLoader) stored in the system memory in bootstrap mode, when the program is loaded by ISP, it is executed by this program. This area is written into BootLoader by the chip factory, and then locked, the user cannot change this area .
    • Option byte : configuration information of the memory chip and protection information for the main memory block (main Flash).

The memory space range of the main Flash of the STM32F103VET6 chip is 0x0800 0000 ~ 0x0807 FFFF, a total of 512KB.

insert image description here

4. Register mapping

insert image description here

In the block2 peripheral area, that is, the area with addresses from 0x4000000 ~ 0x5FFFFFF, on-chip peripherals are designed. They use four bytes as a unit , a total of 32 bits, and each unit corresponds to a different function. When we control these units When it can drive peripherals to work. You can find the starting address of each unit, and then access these units through the operation of C language pointers . If you access this address every time, it is not only difficult to remember but also prone to errors. Smart engineers use The function of each unit is different, and an alias is given to this memory unit in the name of the function. This alias is what we often call a register. This process of aliasing a memory unit with a specific function that has been assigned an address is called register mapping .

insert image description here

5. Address remapping

A bootstrap computer device uses a hardware-loaded program that initializes enough software to find and load a fully functional operating system. Also used to describe the process of loading the bootloader. What is the bootstrap of the single-chip microcomputer, the bootstrap of the single-chip microcomputer is the startup of the single-chip microcomputer .

As we all know, the microcontroller starts to execute from address 0 every time it is powered on , so there is a problem. When we download the program, we put the code in the main Flash, and its address is 0x0800 0000 ~ 0x0807 FFFF. If it is not at address 0, how can the MCU find the code and execute it?

insert image description here

In the area of ​​address division, it can be seen that the function of the area 0x0000 0000 ~ 0x0007 FFFF is dedicated to address remapping , and the area to be remapped depends on the BOOT pin, through the level value of the BOOT1 and BOOT0 pins , you can choose to map 0x0000 0000 ~ 0x0007 FFFF to different memory .
This explains why we set the download address of the program in keil to 0x8000000, but the microcontroller does start execution from 0 when it is powered on . It is because we set BOOT0=1 and BOOT1=X on the hardware, which caused the main FLASH area to be mapped to 0x0000 0000 ~ 0x0007 FFFF (512KB), so the code is downloaded to the storage space after 0x80000000, but it is said to run is run from address 0x00000000.

5.1 STM32 startup mode

insert image description here

  • Start from the main FLASH : map the main Flash address 0x0800 0000 to 0x0000 0000, so that the code starts from 0x08000000 after starting . Generally, when using JTAG or SWD mode to download the program, it is downloaded to this, and the program is directly started from here after restarting.
  • Boot from system memory : Code execution starts at system memory address 0x1FFF F000. The system memory is a specific area inside the chip. When the chip leaves the factory, a section of Bootloader is preset in this area, which is commonly referred to as the ISP program. The content of this area cannot be modified or erased after the chip leaves the factory, that is, it is a ROM area. The function of the program activated is set by the factory. What the system memory stores is actually the bootloader code that comes with the STM32.
  • Start from the built-in SRAM : map the SRAM address 0x20000000 to 0x00000000, so that the code starts from 0x20000000 after starting. The built-in SRAM, that is, the memory of STM32, since it is SRAM, naturally has no ability to store programs. This mode is generally used for program debugging. If I only modify a small place in the code, then I need to re-erase the entire Flash, which is time-consuming. You can consider starting the code from this mode for fast program debugging. After the program debugging is completed, the program downloaded to SRAM .

insert image description here

6. Program burning method

6.1 ISP (serial programming)

  • BOOT0 = 1,BOOT1 = 0
  • Start address: 0x1FFF F000
  • Use the serial port to download the program
  • The system memory (system Flash) startup mode runs the built-in Bootloader, and writes the program into the main storage area (main Flash)
  • After restarting, you need to pull BOOT0 low again to start the program from the main storage area (main Flash)

6.2 ICP (SWD/JTAG interface programming)

  • BOOT0 = 0,BOOT1 = x
  • Start address: 0x0800 0000
  • Download program using JTAG or SWD mode
  • The main flash memory (main Flash) boot mode, write the program in the main storage area
  • Start the program directly from here after restarting

6.3 IAP

The principle of IAP is quite different from the above two. In this way, the main storage area is divided into two areas (allocated by the developer according to actual needs). This part at the beginning of 0x0800 0000 stores a developer’s own The designed Bootloader program, another part stores the APP program that actually needs to run .

The main function of the Bootloader program of the single-chip microcomputer is to upgrade the single-chip microcomputer. When the single chip microcomputer is started, it starts from the Bootloader program first, and generally does not need to be upgraded , it will immediately jump from the Bootloader program to the APP program in another part of the storage area to start running .

If the Bootloader program needs to be upgraded (for example, when the APP program is running, if an upgrade command is received, a flag can be set at a specific position in the flash, and then a restart is triggered , and the Bootloader program enters after the restart. The Bootloader program can judge whether needs to be upgraded), it will Write to the location where the APP program is stored in the storage area, and jump to this location after the writing is completed, that is, the program upgrade is realized .
insert image description here

2. Startup process

The on-chip RAM of STM32 is divided into the following segments:

insert image description here

1. Summary

The start-up file is compiled by assembly and is the first program executed after the system is powered on and reset. Mainly did the following work:

  1. Initialize the stack pointer SP=_initial_sp
  2. Initialize PC pointer = Reset_Handler
  3. Initialize the interrupt vector table
  4. Configure system clock
  5. Call the C library function _main to initialize the user stack, and finally call the main function to go to the C world

2. Stack initialization

// #define Stack_Size      0x00000400
Stack_Size      EQU     0x00000400
// STACK:段名;NOINIT:不初始化;READWRITE:可读可写;ALIGN=3:2^3,即 8 字节对齐
                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
// 栈的结束地址,即栈顶地址,需要保存栈顶的地址
__initial_sp
  • EQU : A pseudo-instruction for macro definition , equivalent to equal, similar to define in C.
  • AREA : Tells the assembler to assemble a new code or data segment .
  • SPACE : used to allocate a certain size of memory space , the unit is byte. Here the specified size is equal to Stack_Size.

3. Heap initialization

// #define Heap_Size       0x00000200
Heap_Size       EQU     0x00000200
// HEAP:段名;NOINIT:不初始化;READWRITE:可读可写;ALIGN=3:2^3,即 8 字节对齐
                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
// 堆的起始地址
__heap_base
Heap_Mem        SPACE   Heap_Size
// 堆的结束地址
__heap_limit

                PRESERVE8
                THUMB
  • PRESERVE8 : Specifies that the stack of the current file is aligned by 8 bytes.
  • THUMB : Indicates that the following instructions are compatible with THUMB instructions. THUBM is the previous instruction set of ARM, 16bit, now Cortex-M series all use THUMB-2 instruction set, THUMB-2 is 32-bit, compatible with 16-bit and 32-bit instructions, it is a superset of THUMB.

4. Initialize the vector table

4.1 Open up vector table space

// RESET:段名;DATA:包含数据,不包含指令;READONLY:只读
AREA    RESET, DATA, READONLY
/* 声明 __Vectors、__Vectors_End 和 __Vectors_Size 这三个标号具有全局属性,
可供外部的文件调用 */
EXPORT  __Vectors
EXPORT  __Vectors_End
EXPORT  __Vectors_Size
  • EXPORT : Declare a label that can be used by external files, so that the label has global attributes . If it is an IAR compiler, the instruction GLOBAL is used.

4.2 Initialize vector table

// __Vectors:向量表起始地址
__Vectors       DCD     __initial_sp               ; 栈顶地址
                DCD     Reset_Handler              ; 复位程序地址
                DCD     NMI_Handler                ; NMI Handler
                DCD     HardFault_Handler          ; Hard Fault Handler
                DCD     MemManage_Handler          ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler            ; SysTick Handler

                // 外部中断开始
                DCD     WWDG_IRQHandler            ; Window Watchdog
                DCD     PVD_IRQHandler             ; PVD through EXTI Line detect
                DCD     TAMPER_IRQHandler          ; Tamper
                DCD     RTC_IRQHandler             ; RTC
                
				// 限于篇幅,中间代码省略
				
                DCD     DMA2_Channel2_IRQHandler   ; DMA2 Channel2
                DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel3
                DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
// __Vectors_End:向量表结束地址
__Vectors_End
// 获得向量表大小
__Vectors_Size  EQU  __Vectors_End - __Vectors

The vector table is placed starting from address 0 (0x0800 0000) of FLASH, with 4 bytes as a unit, address 0 (0x0800 0000) stores the top address of the stack, 0x04 stores the address of the reset program, and so on . From the code point of view, the function names of the interrupt service functions are stored in the vector table, but we know that the function name in C language is an address.

  • DCD : Allocate one or more words in units of memory, aligned with four bytes, and require initialization of these memories . In the vector table, DCD allocates a bunch of memory and initializes them with the entry address of the ESR.

4.3 Reset interrupt program initialization

// .text:段名;DATA:包含机器指令;READONLY:只读
AREA    |.text|, CODE, READONLY
                
// Reset handler
Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  __main
                IMPORT  SystemInit
                LDR     R0, =SystemInit
                BLX     R0               
                LDR     R0, =__main
                BX      R0
                ENDP

The reset subroutine is the first program executed after the system is powered on. It calls the SystemInit function to initialize the system clock, then calls the C
library function _mian, and finally calls the main function to go to the C world.

  • WEAK : Indicates a weak definition. If the external file defines the label first, the label will be referenced first. If the external file does not declare, there will be no error . This means that the reset subroutine can be re-implemented by the user in other files , which is not unique here.
  • IMPORT : Indicates that the label comes from an external file , similar to the EXTERN keyword in C language. Here it means that the two functions SystemInit and __main are from external files.
    • SystemInit(): Standard library function, which is always defined in the library file system_stm32f10x.c. The main function is to configure the system clock . After calling this function here, the system clock configuration of the microcontroller is configured to 72M.
    • __main: Standard C library function, the main function is to initialize the user stack , and call the main function at the end of the function to go to the C world . That's why every program we write has a main function.

insert image description here

4.4 Other interrupt program initialization

/* 初始化默认中断程序(无限循环) */
NMI_Handler     PROC
                EXPORT  NMI_Handler                [WEAK]
                B       .
                ENDP
                
// 限于篇幅,中间代码省略
SysTick_Handler PROC
                EXPORT  SysTick_Handler            [WEAK]
                B       .
                ENDP

/* 外部中断 */
Default_Handler PROC
                EXPORT  WWDG_IRQHandler            [WEAK]
                EXPORT  PVD_IRQHandler             [WEAK]
                EXPORT  TAMPER_IRQHandler          [WEAK]
                EXPORT  RTC_IRQHandler             [WEAK]
// 限于篇幅,中间代码省略
DMA2_Channel1_IRQHandler
DMA2_Channel2_IRQHandler
DMA2_Channel3_IRQHandler
DMA2_Channel4_5_IRQHandler
                B       .
                ENDP
                ALIGN
  • B : Jump to a label . Here jump to a '.', which means an infinite loop.
  • PROC : Start of a process (subroutine).
  • ENDP : End of process (subroutine).
  • ALIGN : Align the address where the instruction or data is stored , followed by an immediate value. The default means 4-byte alignment.

4.5 User Stack Initialization

/* 用户栈和堆初始化, 由 C 库函数 _main 来完成 */
				 // 这个宏在 KEIL 里面开启
				 IF      :DEF:__MICROLIB	
                
                 EXPORT  __initial_sp
                 EXPORT  __heap_base
                 EXPORT  __heap_limit
                
                 ELSE
                 // 这个函数由用户自己实现
                 IMPORT  __use_two_region_memory	
                 EXPORT  __user_initial_stackheap
                 
__user_initial_stackheap
                 LDR     R0, =  Heap_Mem
                 LDR     R1, =(Stack_Mem + Stack_Size)
                 LDR     R2, = (Heap_Mem +  Heap_Size)
                 LDR     R3, = Stack_Mem
                 BX      LR

                 ALIGN
                 ENDIF
                 END

First determine whether __MICROLIB is defined. If this macro is defined , the labels __initial_sp (stack top address),
__heap_base (heap start address), __heap_limit (heap end address) global attributes are assigned, which can be called by external files. Then the initialization of the stack is done by the C library function _main .
If __MICROLIB is not defined , the dual-segment memory mode is used, and the declaration label __user_initial_stackheap has global attributes, allowing users to initialize the stack by themselves .

insert image description here

  • IF, ELSE, ENDIF : Assembly conditional branch statement, similar to if, else in C language.
  • END : end of file

References:
https://zhuanlan.zhihu.com/p/511268958
https://zhuanlan.zhihu.com/p/367821312

Guess you like

Origin blog.csdn.net/weixin_48896613/article/details/129641391