After the hardware is reset, the first step is to execute the reset handler. The entry of this program is in the startup code (by default). Here is an excerpt of the reset processing entry code of cortex-m3:
- Reset_Handler PROC; PROC is equivalent to FUNCTION, indicating the beginning of a function, as opposed to ENDP?
- EXPORT Reset_Handler [WEAK]
- IMPORT SystemInit
- IMPORT __main
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX
- ENDP
-
Reset_Handler PROC ;PROC等同于FUNCTION,表示一个函数的开始,与ENDP相对?
-
EXPORT Reset_Handler [WEAK]
-
IMPORT SystemInit
-
IMPORT __main
-
LDR R0, =SystemInit
-
BLX R0
-
LDR R0, =__main
-
BX R0
-
ENDP
Here, SystemInit function is the hardware low-level clock initialization code written by me in C code. This is not done by Keil MDK. After initializing the stack pointer and executing the user-defined low-level initialization code, it is found that the next code calls the __main function. The reason why there is a __main function here is that the main function is defined in the C code. The function label main() has a special meaning. main() The existence of the function forces the linker to link to the initialization code in __main and __rt_entry .
Among them, the __main function performs code and data copying, decompression, and zero initialization of ZI data. To explain, in C code, the global variables that have been assigned are placed in the input section of the RW attribute. The initial values of these variables are compressed by Keil mdk and placed in ROM or Flash (RO attribute input section). What is an assigned global variable? If you define a global variable in the code like this: int nTimerCount=20; the variable nTimerCount is an assigned variable. If it is defined like this: int nTimerCount; the variable nTimerCount is a non-assigned variable. Keil defaults to putting it in the input section with the attribute ZI. Why do you need to compress? This is because if there are many assigned variables, it will occupy more Flash storage space. Keil uses its own compression algorithm by default. This "decompression" is to decompress the initial values of the variables stored in the RO input area (usually ROM or Flash) according to a certain algorithm and copy them to the corresponding RAM area. ZI data clearing means clearing the RAM area where the variables in the ZI area are located. Using UNINIT attributes to mark the execution area can avoid __main zero initialization of the ZI data in the area. This sentence is very important. For example, if I have some variables that store some important information and do not want them to be cleared after reset, then I can use the scatter loading file to define a region with UNINIT attributes and define the variables that I do not want to be zero initialized to this region.
|