Briefly explain the startup process and program execution process of the chip

Table of contents

1. Chip startup process

2. Startup code

2.1 Stack definition

2.2 Vector table

2.3 Reset procedure

2.4 Interrupt Service Routine

3. The process of program execution

4. Data access


1. Chip startup process

Chip startup is to run the inherent program inside the chip (that is, the startup code) after power-on. After the startup code program has established the running environment, it will read the status of the serial port, that is, each port used by the user to download the program, and determine whether the user is using the port to prepare to download the program.

If the user is downloading the program, the user program is downloaded to the specified address according to the user's request. If no program is downloaded, the chip will jump to the existing user program entry by default, thus handing over the control of the chip to the user program. If it is a new chip without a user program, it stays in the loop of reading the status of the serial port.

The startup code is usually written in flash, which is a program that is executed as soon as the system is powered on. It runs before any user C code. After power-on, the arm processor is in the arm state and runs in the privileged mode. At the same time, all system interrupts are disabled, and the PC fetches instructions from address 0 for execution.

Let's take Flash boot mode as an example. After power-on, the program starting from address 0x0800 0000 is mapped to address 0x0000 0000, and then the program starts to execute from 0x0000 0000. The chip will read a 32-bit value from address 0x0000 0000 and assign it to the stack pointer SP; then read a 32-bit value from address 0x0000 0004 and copy it to the program counter pointer PC, and the program will start executing from the content of the PC pointer .

The startup code mainly completes two aspects of work, one is to initialize the execution environment, such as interrupt vector table, stack, I/O, etc.; the other is to initialize the c library and user applications.

2. Startup code

Taking STM32 as an example, let's take a look at the process from powering on the chip to the main function. The main steps are as follows:

1. Initialize the stack pointer SP=_initial_sp, initialize PC=Reset_Handler

2. Initialize the interrupt vector table

3. Configure the system clock

4. Call the C library function __main to initialize the user stack, and then enter the main function

Because the startup process is mainly completed by assembly, most of the startup content of STM32 is in the startup file. Now take startup_stm32f103xe.s as an example (the principle of other types of startup files is similar).

2.1 Stack definition

1. StackStack

The role of the stack is to save local variables, function calls, function parameters, etc., and the size of the stack cannot exceed the size of the internal SRAM. When the program is large, the size of the stack needs to be modified, otherwise HardFault errors may occur.

Line 33: indicates that the size of the stack is 0x00000400 (1KB), and EQU is a pseudo-instruction, which is equivalent to define in C.

Line 35: open up a section of readable and writable data space, and the ARER pseudo-instruction indicates that a code segment or data segment will be defined below. Here is the definition data section. The keyword after ARER indicates the attributes of this segment. The segment name is STACK, which can be named arbitrarily; NOINIT means not initialized; READWRITE means readable and writable, and ALIGN=3 means alignment according to 8 bytes.

Line 36: SPACE is used to allocate a continuous memory space with a size equal to Stack_Size, in bytes.

Line 37: __initial_sp represents the address of the top of the stack. The stack grows from high to low.

2. Heap heap

The heap is mainly used for dynamic memory allocation, and the memory requested by the malloc() function is in the heap.

 The size of the open heap is 0x00000200 (512 bytes), the name is HEAP, NOINIT means no initialization, readable and writable, and 8-byte alignment. __heap_base represents the starting address of the pair, and __heap_limit represents the end address of the heap.

2.2 Vector table

The vector table is a WORD (32-bit integer) array, each subscript corresponds to an exception, and the value of the subscript element is the entry address of the ESR. The location of the vector table in the address space can be set, and the address of the vector table is pointed out through 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 (that is, FLASH address 0) for exception allocation during initialization. It is worth noting that there is an alternative here: the type 0 is not an entry address, but the initial value of the MSP after reset, which will be explained in detail later.

Line 55: Define a code segment, the segment name is RESET, and READONLY means read-only.

Lines 56-58: Use EXPORT to declare the 3 identifiers to be externally referenced, and declare __Vectors, __Vectors_End, and __Vectors_Size to have global attributes.

Line 60: __Vectors indicates the starting address of the vector, and DCD indicates the allocation of a 4-byte space. Each row of DCD will generate a 4-byte binary code, and the interrupt vector table actually stores the entry address of the interrupt service routine. When an exception (that is, an interrupt event) occurs, the interrupt system of the CPU will assign the corresponding entry address to the PC program counter, and then start executing the interrupt service routine. After line 60, the entry address of the interrupt service routine is defined in turn.

 Line 138: __Vectors_End is the end address of the vector table.

Line 139: __Vectors_Size is the size of the vector table, and the size of the vector table is obtained by subtracting __Vectors from __Vectors_End.

2.3 Reset procedure

The reset program is the first program executed after the system is powered on. The reset program is also an interrupt program, but it is special, so I will only talk about it here.

Line 145: A service program is defined, and PROC indicates the beginning of the program.

Line 146: Use EXPORT to declare Reset_Handler to be externally referenced, followed by [WEAK] to indicate a weak definition. A weakly defined function can be redefined in an external file. In this case, the function defined in the external file is used. If the external file is not defined, the [WEAK] function defined here is referenced. This means that the reset procedure can be re-implemented by the user in other files. This way of writing is very common in the HAL library.

Lines 147-148: refer to two labels from external files, where __main is a standard C library function, mainly used to initialize the user stack. This is done by the compiler, and this function will eventually call the main function we wrote to enter our system. SystemInit() is a library function, mainly used for system clock configuration and interrupt related configuration.

Line 149: Load the address of SystemInit from memory into register R0

Line 150: Jump to the address in R0 (that is, the SystemInit function), and determine the state of the processor according to the LSE of the register, and save the address of the next instruction before the jump to LR.

Lines 151-152: Same as the above two lines, load the address of __main from the memory into R0, and jump to the address in R0. The difference between 152 and 150 is that after line 152 jumps to the address of the specified register, it will not return.

Line 153: corresponds to PROC, indicating the end of the program.

2.4 Interrupt Service Routine

Which interrupt to use usually, you only need to write the corresponding interrupt service program, but these functions are left out in the startup file, but the content is empty, the real interrupt service program needs to be re-implemented in the external C file, here is just in advance Just took a place.

There is no need to talk about this part, similar to the service program, just pay attention to the 'B.' statement, B means jump, jump to a '.' here, which means infinite loop. 

3. The process of program execution

The program operation process of the single-chip microcomputer is divided into several steps of fetching instructions, analyzing instructions and executing instructions.

(1) Instruction fetching: Read the instruction from the program memory according to the value in the program counter PC and send it to the instruction register.

(2) Analyze instructions: take out the instruction opcode in the instruction register and decode it, and analyze the nature of the instruction. If the instruction requires an operand, look for the operand instruction.

(3) Executing instructions: It is nothing more than converting a binary code into a digital signal (high and low levels), operating logic gate circuits, and inputting and outputting like our adder. Output the result of the logic gate operation, and output the relevant pin level of the microcontroller high or low.

The process of the single-chip computer executing the program is actually to repeat the above-mentioned operation process one by one until it encounters a stop command and can wait for the command in a loop.

For example:

When powered on, the program calculator PC becomes 0000H. Then the single-chip microcomputer automatically enters the process of executing the program under the action of the sequential circuit. The execution process is actually a cyclic process of fetching instructions (fetching the pre-stored instruction stage in the memory) and executing instructions (analyzing and executing instructions).

For example, execute the instruction: MOV A,#0E0H, its machine code is 74H E0H, the function of this instruction is to send the operand E0Hinto the accumulator, which 0000Hhas been stored in the unit 74H, and 0001Hhas been stored in the unit E0H. When the single-chip microcomputer starts to run, it first enters the stage of fetching instructions, and the sequence is:

  • The contents of the program counter (at this time 0000H) are sent to the address register;

  • The content of the program counter is automatically incremented by 1 (become 0001H);

  • The content of the address register ( 0000H) is sent to the memory through the internal address bus, and the address in the memory is decoded by the circuit, so that the 0000Hunit with the address is selected;

  • The CPU asserts the read control line;

  • The content of the selected memory unit under the control of the read command (should be 74H at this time) is sent to the internal data bus, because it is the stage of fetching instructions, so the content is sent to the instruction register through the data bus.

4. Data access

For the storage and reading of instructions and data during program execution of the single-chip microcomputer, the understanding is as follows:

The code segment, .data segment, .bss segment, and rodata segment of the program are all stored in Flash. After the MCU is powered on, the initialization assembly code copies the .data segment and the .bss segment to RAM, builds a stack, and starts calling the main function of the program.

After that, there are program memory and data memory. Instructions are read from Flash (ie, instruction memory, code memory) at runtime, and data is read and written from RAM. The point of RAM is to be faster.

Regardless of whether it is a single-chip microcomputer or a PC, the existing memory pyramids are consistent. The speed factor and the cost limitation lead to faster speed and higher cost of the faster memory. It should be said that the understanding of them is the understanding of the memory pyramid.

Guess you like

Origin blog.csdn.net/panpan_jiang1/article/details/129678118