1. Introduction to ARM controller startup
After the controller of the ARM7/ARM9 core is reset, the CPU will fetch the first instruction from the absolute address 0x000000 of the storage space and start by executing the reset interrupt service program, that is, the starting address after reset is fixed to 0x000000 (PC = 0x000000) and the position of the interrupt vector table is not fixed. The Cortex-M3 core is just the opposite, there are three cases:
1. The interrupt vector table can be located in the SRAM area through the boot pin setting, that is, the starting address is 0x2000000, and the PC pointer is located at 0x2000000 after reset;
2. The interrupt vector table can be located in the FLASH area through the boot pin setting, that is, the starting address is 0x8000000, and the PC pointer is located at 0x8000000 after reset;
3. The interrupt vector table can be located in the built-in Bootloader area through the boot pin setting.
The Cortex-M3 core stipulates that the starting address must store the stack top pointer, and the second address must store the reset interrupt entry vector address. In this way, after the Cortex-M3 core is reset, it will automatically fetch the reset interrupt entry vector from the next 32-bit space of the starting address and jump to execute the reset interrupt service program. Compared with the ARM7/ARM9 core, the Cortex-M3 core has a fixed interrupt vector table location and a variable starting address.
2. Introduction to STM32 startup files
2.1 Main tasks of the startup file
The startup file is written in assembly language and is the first program executed after the system is powered on and reset. It mainly does 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 the 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.2 Some assembly instructions in the startup file:
2.3 Some startup code analysis
2.3.1 Stack Definition
1 Stack_SizeEQU 0x00000400
2
3AREASTACK, NOINIT, READWRITE, ALIGN=3
4 Stack_MemSPACE Stack_Size
5 __initial_sp
The size of the stack is 0X00000400 (1KB), the name is STACK, NOINIT means no initialization, readable and writable, and 8 (2^3) byte alignment.
The stack is used for local variables, function calls, function parameters, etc. The size of the stack cannot exceed the size of the internal SRAM. If the program you write is large and defines many local variables, you need to modify the size of the stack. If one day, your program has an inexplicable error and enters a hard fault, then you should consider whether the stack is not large enough and overflows.
EQU: A macro-defined pseudo-instruction, equivalent to equals, similar to define in C.
AREA: tells the assembler to assemble a new code segment or data segment. STACK indicates the segment name, which can be named arbitrarily; NOINIT indicates no initialization; READWRITE indicates read-write, and ALIGN=3 indicates alignment according to 2^3, that is, 8-byte alignment.
SPACE: used to allocate a certain size of memory space in bytes. Here the specified size is equal to Stack_Size.
The label __initial_sp is placed next to the SPACE statement, indicating the end address of the stack, that is, the top address of the stack. The stack grows from high to low.
Then define the heap.
Initialize the user stack size. This part is completed by the C library function __main. After the stack is initialized, the main function is called to go to the C world.
2.3.2 Define a data segment to place the interrupt vector table
1 AREA RESET, DATA, READONLY
2 EXPORT __Vectors
3 EXPORT __Vectors_End
4 EXPORT __Vectors_Size
Define a data segment named RESET, which is readable, and declare that the three labels __Vectors, __Vectors_End, and __Vectors_Size can be used by external files.
EXPORT: declares a label that can be used by external files, making the label have global attributes. If it is an IAR compiler, the GLOBAL instruction is used.
The following passage is quoted from "CM3 Authoritative Guide CnR2" 3.5-Vector Table. Since no description of the M4 vector table has been found yet, but CM4 is similar to CM3, it has great reference value.
When the CM3 core responds to an exception, the corresponding exception service routine (ESR) will be executed. In order to determine the entry address of the ESR, CM3 uses a "vector table lookup mechanism". A vector table is used here. The vector table is actually a WORD (32-bit integer) array, and the value of the element is the entry address of the ESR. The position of the vector table in the address space can be set, and the address of the vector table is indicated by a relocation register in the NVIC. After reset, the value of this register is 0. Therefore, a vector table must be included at address 0 (i.e. FLASH address 0) for initial exception allocation.
…………..(Other interrupts are listed in this order)
For example, if exception 11 (SVC) occurs, the NVIC will calculate the offset as 11x4=0x2C, and then fetch the entry address of the service routine from there and jump in. It should be noted that there is an alternative here: type 0 is not an entry address, but gives the initial value of MSP after reset.
2.3.3 Create a vector table
1 __VectorsDCD __initial_sp; stack top address
2 DCD Reset_Handler ; Reset program address
3 DCD NMI_Handler
4 DCD HardFault_Handler
5 DCD MemManage_Handler
6 DCD BusFault_Handler
7 DCD UsageFault_Handler
8 DCD 0; 0 means reserved
9 DCD 0
10 DCD 0
11 DCD 0
12 DCD SVC_Handler
13 DCD DebugMon_Handler
24; Due to space limitations, the intermediate code is omitted
25 DCD LTDC_IRQHandler
26 DCD LTDC_ER_IRQHandler
27 DCD DMA2D_IRQHandler
28 __Vectors_End
1 __Vectors_SizeEQU __Vectors_End - __Vectors
__Vectors is the starting address of the vector table, and __Vectors_End is the ending address of the vector table. Subtracting the two can calculate the size of the vector table.
The vector table is placed starting from address 0 of FLASH, with 4 bytes as a unit. Address 0 stores the address of the top of the stack, 0X04 stores the address of the reset program, and so on. From the code, the vector table stores the function names of the interrupt service functions, but we know that the function name in C language is an address. (From this, we know that the function name of the interrupt function is already known)
DCD: Allocate one or more memory in word units, align 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 ESR.
2.3.4 Reset Procedure
1 AREA |.text|, CODE, READONLY
Define a readable code section named .text.
1 Reset_HandlerPROC
2 EXPORT Reset_Handler [WEAK]
3 IMPORT SystemInit
4 IMPORT __main
56
LDR R0, =SystemInit
7 BLX R0
8 LDR R0, =__main
9 BX R0
10 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.
__main is a standard C library function, which is mainly used to initialize the user stack and finally call the main function to enter the C world. This is why all programs we write have a main function. If we do not call __main here, the program will not call the main in our C file. If you are a naughty user, you can modify the name of the main function and then import the name of the main function you wrote here.
2.3.5 System startup process
After leaving reset, the first thing CM3 does is read the values of the following two 32-bit integers:
1. Get the initial value of MSP from address 0x0000,0000.
2. Take the initial value of PC from address 0x0000,0004 - this value is the reset vector, and the LSB must be 1. Then fetch the instruction from the address corresponding to this value.
Note that this is different from the traditional ARM architecture - and in fact, it is different from most other microcontrollers. The traditional ARM architecture always executes the first instruction from address 0. Their address 0 is always a jump instruction. In CM3, the initial value of MSP is provided at address 0, and then the vector table follows. The values in the vector table are 32-bit addresses, not jump instructions. The first entry in the vector table points to the first instruction that should be executed after reset, which is the Reset_Handler function just analyzed.
Because CM3 uses a full stack that grows downward, the initial value of MSP must be the last address of the stack memory plus 1. For example, if our stack area is between 0x20007C00-0x20007FFF, then the initial value of MSP must be 0x20008000.
The vector table follows the initial value of the MSP - that is, the second table entry. Note that because CM3 is executed in Thumb state, each value in the vector table must have the LSB set to 1 (that is, an odd number). It is for this reason that 0x101 is used in Figure 3 to represent address 0x100. When the instruction at 0x100 is executed, the program execution officially begins (that is, going to the C world). It is necessary to initialize the MSP before this, because NMI or other faults may occur before the first instruction has time to execute. After the MSP is initialized, the stack is prepared for their service routines.
Now, the program has entered the familiar C world, and now we should also understand that main is not the first program executed by the system.
2.4 Specific comments for each line of code
Line 1: Defines whether to use external SRAM, 1 means use, 0 means not use.
Line 2: Defines the stack space size as 0x00000400 bytes, that is, 1Kbyte.
Line 3: Pseudo-instruction AREA
Line 4: Opens up a memory space of size Stack_Size as the stack.
Line 5: Label __initial_sp, indicating the top address of the stack space.
Line 6: Defines the heap space size as 0x00000400 bytes, also 1Kbyte. Line 7
: Pseudo-instruction AREA
Line 8: Label __heap_base, indicating the starting address of the heap space.
Line 9: Opens up a memory space of size Heap_Size as the heap. Line 10
: Label __heap_limit, indicating the end address of the heap space.
Line 11: Tells the compiler to use the THUMB instruction set.
Line 12: Tells the compiler to align with 8 bytes.
Lines 13-81: IMPORT directive, indicating that the subsequent symbols are defined in an external file (similar to the global variable declaration in C language), and these symbols may be used in the following text.
Line 82: Define the read-only data segment, which is actually in the CODE area (assuming that STM32 is started from FLASH, the starting address of this interrupt vector table is 0x8000000)
Line 83: Declare the label __Vectors as a global label, so that external files can use this label.
Line 84: Label __Vectors, indicating the entry address of the interrupt vector table.
Lines 85-160: Create an interrupt vector table.
Line 161:
Line 162: Reset interrupt service routine, PROC...ENDP structure indicates the start and end of the program.
Line 163: Declare the reset interrupt vector Reset_Handler as a global attribute, so that external files can call this reset interrupt service.
Line 164: IF…ENDIF is a pre-compiled structure to determine whether to use external SRAM, which has been defined as "not used" in line 1.
Lines 165-201: The purpose of this part of the code is to set the FSMC bus to support SRAM. Since external SRAM is not used, this part of the code will not be compiled.
Line 202: Declare the __main label.
Lines 203-204: Jump to the __main address for execution.
Line 207: IF…ELSE…ENDIF structure to determine whether to use DEF:__MICROLIB (not used here).
Lines 208-210: If DEF:__MICROLIB is used, __initial_sp, __heap_base, __heap_limit, that is, the stack top address and the heap start and end addresses are assigned global attributes so that external programs can use them.
Line 212: Define the global label __use_two_region_memory.
Line 213: Declare the global label __user_initial_stackheap, so that external programs can also call this label.
Line 214: Label __user_initial_stackheap, indicating the user stack initialization program entry.
Lines 215-218: Save the stack top pointer and stack size, the stack start address and stack size to the R0, R1, R2, and R3 registers respectively.
Line 224: The program ends.
2.5 STM32 startup file and startup process
At this point, we can summarize the startup file and startup process of STM32. First, define the size of the stack and heap, and establish an interrupt vector table at the beginning of the code area. The first table entry is the stack top address, and the second table entry is the reset interrupt service entry address. Then jump to the __main function of the C/C++ standard real-time library in the reset interrupt service program. After completing the initialization of the user stack, jump to the main function in the .c file to start executing the C program. Assuming that STM32 is set to start from the internal FLASH (which is also the most common case), the starting position of the interrupt vector table is 0x8000000, then the stack top address is stored at 0x8000000, and the reset interrupt service entry address is stored at 0x8000004. When STM32 encounters a reset signal, it takes out the reset interrupt service entry address from 0x80000004, then executes the reset interrupt service program, then jumps to the __main function, and finally enters the mian function to enter the world of C.
Previous article:cortex-m3/m0 assembly startup code analysis
Next article:In-depth analysis of STM32 startup files
Recommended ReadingLatest update time:2024-11-24 20:33
- Popular Resources
- Popular amplifiers
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- CATL releases October battle report
- Battery industry in October 2024: growth momentum remains unabated!
- Mercedes-Benz will launch the eCitaro equipped with NMC4 batteries to provide high energy density and long life
- Many companies have announced progress on solid-state batteries. When will solid-state batteries go into mass production?
- Xsens Sirius Series Inertial Sensors Enable 3D Inertial Navigation in Harsh Environments
- Infineon's Automotive Landscape: From Hardware to Systems
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- X-NUCLEO-IKS01A3 MakeCode Driver (Extension) Collection
- This strange circuit
- EEWORLD University ---- test
- [New CH554 Review] III. Formation Procedure
- Better
- SimpleLink MCU code migration guide: CC1310 from VQFN48 (7×7) to VQFN32 (5×5) code migration process reference
- Eliminating Software Failures with MSP432
- Welcome the new moderator of the "201420208012" eSports
- What is the difference between a servo motor and a brushless DC motor?
- Share and discuss: How to quickly determine whether a domestic chip is truly self-developed or just a sham?