The original is here: http://www.cnblogs.com/mddblog/p/4920063.html
Overview
In the embedded system, the startup file is a very important part of the whole system, it will do some basic initialization, build the program to run the necessary environment, such as stack initialization, variable initialization and so on. If there is an error in the startup file, the entire system will not run, so it is necessary to study the startup file.
In Keil, the boot file is written by the assembly code and is generally named Startup_xxx.s,xxx as a supported chip, such as LPC15XX (NXP's lpc15xx series), MK60D10 (Freescale), stm32f10x (STMicroelectronics stm32f10x series) and other CORTEXT-M0/M3/M4 core chips. Their code formats are very similar, based on the order in which the boot file code is written from top to bottom.
It can be divided into the following 5 typical sections:
1. Stack space definition;
2. store interrupt vector table;
3. Reset Interrupt function (Reset_handler);
4. Other interrupt exception service functions, and weak [WEAK] declarations;
5. Pass the stack address to the library function, initialize the stack with the library function, and initialize the library function itself.
5 sections are specified as follows:
1. Stack space definition
As shown, the stack size is defined stack_size = 0X200, which is 512 bytes; Heap size heap_size = 0x100,256 bytes. There are also three labels defined: __initial_sp (top of Stack), __heap_base (heap start address), and __heap_limit (heap termination address), their space is applied by the Spaces keyword and recorded as Stack_mem and Heap_mem.
With these we can easily know the size of the stack, but their absolute address or base site is simply not accessible from here. When the compiler finishes compiling the project, the base address of the stack is evaluated based on the size of the generated. BSS segment (such as uninitialized global variables) and the. Data segment (such as the initialized global variable) and the start address of the RAM.
As an example:
The RAM start address for a chip is 0x0200_0000, after the program is compiled. The BSS field is 0x100 bytes, and the. Data field is 0x100 bytes. The stack size is defined as. The
A: Heap start address __heap_base==heap_mem==0x0200_0200;
B: Heap termination address is the bottom of the stack __heap_limit==stack_mem==0x0200_0300;
C: Stack top address __initial_sp==0x0200_0500.
In fact, I can see the size and base address of the stack in the. map file, as shown in:
2. Storage Interrupt Vector Table
In the startup code, you will see a number of function entries that are stored by the DCD application space, that is, the interrupt vector table, as shown in the section, listed only.
The keyword DCD represents the space to request a word, followed by the function name, which is the Interrupt Service function entry address. In addition the interrupt vector table is generally stored in the Flash 0 address.
in addition, for NXP microcontrollers, the chip is encrypted, the encryption is set at the end of the vector table, the specific address is 0X02FC. The level of encryption or encryption is implemented by storing different values at this address. Encryption is divided into three levels, crp1:0x12345678;crp2:0x87654321;crp3:0x43218765. Please refer to the chip user manual for specific instructions on each level. The following is an example of an encryption step, in CRP1:
First, the 0xFFFFFFFF is changed to 0x12345678.
Second, the figure if:lnot::D EF:NOCRP means that if you do not define a macro NOCRP The following code is executed, you must ensure that the NOCRP macro is not defined in the assembly. That is guaranteed in define: A column does not define the NOCRP can be.
3. Reset Interrupt function (Reset_handler)
After the program is power-up, loading the SP and Pc,arm first requires loading the SP from the 0 address and loading the PC from the address at offset 4 (0x00000004). Then give the program control to the program. We know that the 0 address store __initial_sp,0x00000004 address at the store Reset_handler, after loading the PC, the program jumps to Reset_handler to start running. The Reset_handler function body looks like this:
First call the Systeminit function to initialize the various clocks of the system, and then call the __main function (implemented by the Keil or C library ), in the __main function: Initialization of the data segment of the->.BSS segment variable 0 Set stack pointers and library function initialization (such as common malloc functions), and if necessary set the main function to argc and argv two parameters, call the user main function, exit.
4. Other interrupt exception service functions, and weak [WEAK] declarations
As shown, the interrupt service function here is weakly declared (labeled by [WEAK] keywords). The so-called weak declaration, that is, if the user defines the same function, the function fails and the user-defined interrupt service function is used. This is to prevent the user from interrupting the service function, which causes the program to crash. Assuming the interrupt is enabled, and the user does not define the interrupt service function, it enters the default interrupt, as shown in the default interrupt is a dead loop (the dead loop and the program crash are not a concept).
5. Pass the stack address to the library function
In the third step, call the __main function, and then __main call the library function to initialize the stack, but the library function does not know the size of the stack, so we need to tell it by passing the parameter or declaring the label.
for concrete practice, you can see the first behavior:
IF:D Ef:__microlib
is the conditional compilation option, if you define __microlib, then compile the red line above the section, or compile the red line below the section. Then there are 2 kinds of situations.
The choice of 2 cases can be achieved as follows:
If you tick "options for Target", "target" and "use MicroLIB", as shown in. Even with a micro-library, the __microlib is defined, and the compiler compiles the code above the red line. Declare __initial_sp, __heap_base and __heap_limit with export.
If "Use MicroLIB" is not checked, then the KEIL C library is used by default, the red line will participate in compiling, KEIL C library function will call __user_initial_stackheap and pass the stack as parameter to the R0~R3 C library via KEIL.
Keil in the boot file (assembly language)