Contact SCM has a few years of time, has been focused on how to write some applications on a single chip microcomputer, how to start the knowledge of little, ashamed ashamed ... Today, I have to tidy up a bit, deepen the understanding of the SCM, such as why the definition of the data area of the variable restart the initial value of 0.
When the MCU is powered on, it will execute startup. The instructions for the A51 file, I analyzed the instructions in this file in a project where I did the following things: Initialize the size and stack pointers of the 8051 hardware stack, initialize the interrupt vector table, assign each interrupt's entry address and interrupt service function, and initialize the internal RAM space, i.e. data/ Idata, the content is clear 0; initializes the external RAM space, that is, the xdata/pdata, the content is 0; initializes the stack pointer used by the Reentrant function in Small/compact/large mode, and calls the main () function to execute the code we write.
When using Keil as the development environment, create a project, you need to choose the type of SCM, and then Keil will be the corresponding SCM Startup.a51 files to the engineering directory, at compile time, the file will be compiled into the final target file. In general, this file does not need us to make changes, keep the default state can be, so many people may not be familiar with this file. Here is the specific code and my personal analysis:
$NOMOD 51; Cancel 8051 SFR predefined, defined by the user.; The following defines 3 SFR SFR Clksel = 0x8f SFR P3 = 0xb0 SFR mmu_sel = 0xc3; The following initialization of Idata, XData and pdata storage area Idatastart EQU 00H; The absolute start-address of idata memory Idatalen EQU 100H;
The length of idata memory in bytes.
; Xdatastart EQU 0H; The absolute start-address of XDATA memory Xdatalen EQU;
The length of XDATA memory in bytes.
; Pdatastart EQU 0H; The absolute start-address of PDATA memory Pdatalen EQU 100H;
The length of PDATA memory in bytes. ;
Defines the address where the PLL value is stored.
Plladdr EQU 0xEFFF; ; When the function is reentrant (decorated with the reentrant keyword), the following initializes the stack used by the Reentrant function, taking into account the three compilation patterns Small/compact/large.;
Stack spaces for reentrant functions in the SMALL model. Ibpstack EQU 0;
Set to 1 if small reentrant is used. Ibpstacktop EQU 0ffh+1;
Set top's stack to highest location+1. ;
;
Stack spaces for reentrant functions in the LARGE model. Xbpstack EQU 0;
Set to 1 if large reentrant is used. Xbpstacktop EQU 0ffffh+1; Set top of Stack to HIghest location+1. ;
;
Stack spaces for reentrant functions in the COMPACT model. Pbpstack EQU 0;
Set to 1 if compact reentrant is used. Pbpstacktop EQU 0ffffh+1;
Set top's stack to highest location+1. ;
;------------------------------------------------------------------------------
; Initialization of the pdata area; Page Definition for Using the Compact Model with the KByte xdata RAM;; The following EQU statements define the XData page used for pdata; Variables. The EQU PPAGE must conform with the PPAGE control used;
In the linker invocation.
; Ppageenable EQU 1;
Set to 1 if Pdata object are used. PPAGE EQU 0;
Define PPAGE number. PPAGE_SFR DATA 0a0h start_gpnvm_code EQU 00H; Start of Code;;------------------------------------------------------------------------------; Standard SFR symbols ACC data 0e0h B data 0f0h SP data 81H DPL data 82H DPH Data 83 H P2 DATA 0a0h NAME? C_startup; Defines the name of the assembly code in the obj file; Declare three externally defined interrupt functions to invoke the EXTRN code (TRQISR) EXTRN Code (UARTISR) EXTRN Code (FLASHINTERRUPT) in this module; Declare segment C_c51startup and stack storage locations? C_c51startup SEGMENT CODE? STACK SEGMENT idata; Select the stack segment and set the stack size rseg? STACK DS 96; Select the address 0x00 (code area) and jump to the location of the 0x0200 (code area) cseg at 0x00 ljmp 0x0200 code (? C_start); Declare the outer segment name C_start so that you can call public in this module? C_startup declare that the segments defined in this document are C_startup public to be invoked by other modules; Select the address 0x0200 (code area) and jump to the location of the STARTUP1 (code area) cseg at 0x0200? C_STARTUP:LJMP STARTUP1;
Here is the interrupt vector table, which assigns each interrupt address and the corresponding interrupt service function. Cseg at START_GPNVM_CODE+0BH; IT Timer 0; GPNVMVECTORETUCNT:LJMP TRQISR RETI; LJMP interruptroutinevectoretucnt cseg at start_gpnvm_code+13h; MMU COB or DOB or OVD; GPNVMVECTORFAULT:LJMP Uartisr RETI cseg at start_gpnvm_code+23h; MMU COB or DOB orOVD; GPNVMVECTORFAULT:LJMP Flashinterrupt RETI; Select the address of the C_c51startup segment rseg? C_c51startup Startup1:mov Mmu_sel, #01H; Initialize Sfr:mmu_sel MOV P3, #05H; Initialize SFR:P3 the clock frequency of the MCU DPTR, #PLLADDR Movx A, @DPTR ANL A, #0C0H mov clksel, A; Initialize IRAM (0x00-0xff) IF idatalen <> 0 MOV R0, #IDATALEN-1; MOV R1, #IDATASTART CLR a Idataloop:mov @R0, A; INC R1 djnz r0,idataloop ENDIF; Initialize Xram if Xdatalen <> 0 mov DPTR, #XDATASTART mov R7, #LOW (Xdatalen) if (Low (Xdatalen)) <> 0 mov r6,# (high (Xdatalen)) +1 ELSE MOV R6, #HIGH (xdatalen) ENDIF CLR A Xdataloop:movx @ Dptr,a INC DPTR djnz r7,xdataloop djnz r6,xdataloop ENDIF;
Initialize pdata if ppageenable <> 0 mov P2, #PPAGE ENDIF if Pdatalen <> 0 mov R0, #PDATASTART MOV R7,#LOW (Pdatalen) CLR a pdataloop:movx @R0, a INC R0 djnz r7,pdataloop ENDIF; Initializes the stack pointer used by the Reentrant function (small/compact/large) IF ibpstack <> 0 extrn DATA (? C_IBP) MOV? C_IBP, #LOW ibpstacktop ENDIF IF xbpstack <> 0 extrn DATA (? C_XBP) MOV? C_XBP, #HIGH xbpstacktop MOV? C_xbp+1, #LOW xbpstacktop ENDIF IF pbpstack <> 0 extrn DATA (? C_PBP) MOV? C_PBP, #LOW pbpstacktop ENDIF MOV sp,#? STACK-1; Initializes the stack pointer, pointing to the bottom of the stack; Declares an externally defined function B_switch0 and invokes the Extrn CODE (?). B_switch0) call? B_switch0; Init Bank mechanism to code Bank 0 ljmp?
C_start, calling main () function end
This is a compile output file. Some of the code in LST is allocated in the coding area, combining the assembly code, we can know what instructions are stored somewhere in the code area.
000000h 000002H 000003H---OFFS. CODE? CO? Sttf06?3 The code stored here is ljmp 0x0200 000003H 00000AH 000008H------**gap** 00000BH 00000EH 000004H ---OFFS. CODE? CO? Sttf06?5 The code stored here is ljmp trqisr 00000FH 000012H 000004H------**gap** 000013H 000016H 000004H- --OFFS. CODE? CO? Sttf06?6 The code stored here is ljmp uartisr 000017H 000022H 00000CH------**gap** 000023H 000026H 000004H ---OFFS. CODE? CO? Sttf06?7 The code stored here is ljmp flashinterrupt 000027H 0001FFH 0001d9h------**gap** 000200H 000202H 000 003H---OFFS. CODE? CO? Sttf06?4 The code stored here is ljmp STARTUP1 000203H 0006e9h 0004e7h BYTE Unit code? C? Lib_code 0006EAH 0007a0h 0000b7h BYTE unit CODE? C_c51startup The code stored here is paragraph? C_c51startup the contents of the microcontroller to do initialization of the hardware
The following is a description of startup. A51 's flowchart, as the summary of this study.