ARM裸機篇---啟動代碼分析
先搞清楚啟動代碼和Bootloader的區(qū)別,啟動代碼是指CPU復(fù)位后到進(jìn)入C語言的main函數(shù)之前需要執(zhí)行的那段匯編代碼。
下面的代碼先暫且這樣吧,沒啥注釋的,時間關(guān)系,我還是先搞些應(yīng)用再說^_^
;=========================================; NAME: 2410INIT.S; DESC: C start up codes; Configure memory, ISR ,stacks;Initialize C-variables; HISTORY:; 2002.02.25:kwtark: ver 0.0; 2002.03.20:purnnamu: Add some functions for testing STOP,POWER_OFF mode; 2002.04.10:SJS:sub interrupt disable 0x3ff -> 0x7ff ;=========================================GET option.sGET memcfg.sGET 2410addr.s BIT_SELFREFRESH EQU(1<<22);Pre-defined constantsUSERMODE EQU 0x10FIQMODE EQU 0x11IRQMODE EQU 0x12SVCMODE EQU 0x13ABORTMODE EQU 0x17UNDEFMODE EQU 0x1bMODEMASK EQU 0x1fNOINT EQU 0xc0;The location of stacksUserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~ SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~ ;Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.GBLL THUMBCODE[ {CONFIG} = 16 THUMBCODE SETL {TRUE} CODE32 | THUMBCODE SETL {FALSE} ] MACROMOV_PC_LR [ THUMBCODE bx lr | movpc,lr ]MEND MACROMOVEQ_PC_LR [ THUMBCODE bxeq lr | moveq pc,lr ] MEND MACRO$HandlerLabel HANDLER $HandleLabel$HandlerLabelsubsp,sp,#4 ;decrement sp(to store jump address)stmfdsp!,{r0} ;PUSH the work register to stack(lr does"t push because it return to original address)ldr r0,=$HandleLabel;load the address of HandleXXX to r0ldr r0,[r0] ;load the contents(service routine start address) of HandleXXXstr r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stackldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)MENDIMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)IMPORT |Image$$RW$$Base| ; Base of RAM to initialiseIMPORT |Image$$ZI$$Base| ; Base and limit of areaIMPORT |Image$$ZI$$Limit| ; to zero initialiseIMPORT Main ; The main entry of mon program AREA Init,CODE,READONLYENTRY ;1)The code, which converts to Big-endian, should be in little endian code.;2)The following little endian code will be compiled in Big-Endian mode. ; The code byte order should be changed as the memory bus width.;3)The pseudo instruction,DCD can"t be used here because the linker generates error.ASSERT:DEF:ENDIAN_CHANGE[ ENDIAN_CHANGE ASSERT :DEF:ENTRY_BUS_WIDTH [ ENTRY_BUS_WIDTH=32bChangeBigEndian ;DCD 0xea000007 ] [ ENTRY_BUS_WIDTH=16andeqr14,r7,r0,lsl #20 ;DCD 0x0007ea00 ] [ ENTRY_BUS_WIDTH=8streqr0,[r0,-r10,ror #1] ;DCD 0x070000ea ]| bResetHandler ]bHandlerUndef;handler for Undefined modebHandlerSWI;handler for SWI interruptbHandlerPabort;handler for PAbortbHandlerDabort;handler for DAbortb.;reservedbHandlerIRQ;handler for IRQ interrupt bHandlerFIQ;handler for FIQ interrupt;@0x20bEnterPWDNChangeBigEndian;@0x24[ ENTRY_BUS_WIDTH=32 DCD0xee110f10;0xee110f10 => mrc p15,0,r0,c1,c0,0 DCD0xe3800080;0xe3800080 => orr r0,r0,#0x80; //Big-endian DCD0xee010f10;0xee010f10 => mcr p15,0,r0,c1,c0,0][ ENTRY_BUS_WIDTH=16 DCD 0x0f10ee11 DCD 0x0080e380 DCD 0x0f10ee01][ ENTRY_BUS_WIDTH=8 DCD 0x100f11ee DCD 0x800080e3 DCD 0x100f01ee ]DCD 0xffffffff ;swinv 0xffffff is similar with NOP and run well in both endian mode. DCD 0xffffffffDCD 0xffffffffDCD 0xffffffffDCD 0xffffffffb ResetHandler;Function for entering power down mode; 1. SDRAM should be in self-refresh mode.; 2. All interrupt should be maksked for SDRAM/DRAM self-refresh.; 3. LCD controller should be disabled for SDRAM/DRAM self-refresh.; 4. The I-cache may have to be turned on. ; 5. The location of the following code may have not to be changed.;void EnterPWDN(int CLKCON); EnterPWDNmov r2,r0;r2=rCLKCONtst r0,#0x8;POWER_OFF mode?bne ENTER_POWER_OFFENTER_STOPldr r0,=REFRESHldr r3,[r0];r3=rREFRESHmov r1, r3orr r1, r1, #BIT_SELFREFRESHstr r1, [r0];Enable SDRAM self-refreshmov r1,#16 ;wait until self-refresh is issued. may not be needed.0subs r1,r1,#1bne %B0ldr r0,=CLKCON;enter STOP mode.str r2,[r0] mov r1,#320subs r1,r1,#1;1) wait until the STOP mode is in effect.bne %B0;2) Or wait here until the CPU&Peripherals will be turned-off; Entering POWER_OFF mode, only the reset by wake-up is available.ldr r0,=REFRESH ;exit from SDRAM self refresh mode.str r3,[r0]MOV_PC_LRENTER_POWER_OFF;NOTE.;1) rGSTATUS3 should have the return address after wake-up from POWER_OFF mode.ldr r0,=REFRESHldr r1,[r0];r1=rREFRESHorr r1, r1, #BIT_SELFREFRESHstr r1, [r0];Enable SDRAM self-refreshmov r1,#16 ;Wait until self-refresh is issued,which may not be needed.0subs r1,r1,#1bne %B0ldr r1,=MISCCRldrr0,[r1]orrr0,r0,#(7<<17) ;Make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE=L during boot-up strr0,[r1]ldr r0,=CLKCONstr r2,[r0] b .;CPU will die here.WAKEUP_POWER_OFF;Release SCLKn after wake-up from the POWER_OFF mode.ldr r1,=MISCCRldrr0,[r1]bicr0,r0,#(7<<17) ;SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:L->Hstrr0,[r1];Set memory control registers ldrr0,=SMRDATAldrr1,=BWSCON;BWSCON Addressaddr2, r0, #52;End address of SMRDATA0 ldrr3, [r0], #4 strr3, [r1], #4 cmpr2, r0bne%B0mov r1,#2560subs r1,r1,#1;1) wait until the SelfRefresh is released.bne %B0 ldr r1,=GSTATUS3 ;GSTATUS3 has the start address just after POWER_OFF wake-upldr r0,[r1]mov pc,r0LTORG HandlerFIQ HANDLER HandleFIQHandlerIRQ HANDLER HandleIRQHandlerUndef HANDLER HandleUndefHandlerSWI HANDLER HandleSWIHandlerDabort HANDLER HandleDabortHandlerPabort HANDLER HandlePabortIsrIRQ subsp,sp,#4 ;reserved for PCstmfdsp!,{r8-r9} ldrr9,=INTOFFSETldrr9,[r9]ldrr8,=HandleEINT0addr8,r8,r9,lsl #2ldrr8,[r8]strr8,[sp,#8]ldmfdsp!,{r8-r9,pc};=======; ENTRY ;=======ResetHandlerldrr0,=WTCON ;watch dog disable ldrr1,=0x0 strr1,[r0]ldrr0,=INTMSKldrr1,=0xffffffff ;all interrupt disablestrr1,[r0]ldrr0,=INTSUBMSKldrr1,=0x7ff;all sub interrupt disable, 2002/04/10strr1,[r0][ {FALSE} ; rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~data & 0xf)<<4); ; Led_Displayldrr0,=GPFCONldrr1,=0x5500strr1,[r0]ldrr0,=GPFDATldrr1,=0x10strr1,[r0]];To reduce PLL lock time, adjust the LOCKTIME register. ldrr0,=LOCKTIMEldrr1,=0xffffffstrr1,[r0] [ PLL_ON_START;Configure MPLLldrr0,=MPLLCON ldrr1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ;Fin=12MHz,Fout=50MHzstrr1,[r0]];Check if the boot is caused by the wake-up from POWER_OFF mode.ldrr1,=GSTATUS2ldrr0,[r1]tstr0,#0x2 ;In case of the wake-up from POWER_OFF mode, go to POWER_OFF_WAKEUP handler. bneWAKEUP_POWER_OFFEXPORT StartPointAfterPowerOffWakeUpStartPointAfterPowerOffWakeUp;Set memory control registers ldrr0,=SMRDATAldrr1,=BWSCON;BWSCON Addressaddr2, r0, #52;End address of SMRDATA0 ldrr3, [r0], #4 strr3, [r1], #4 cmpr2, r0bne%B0 ;Initialize stacksblInitStacks ; Setup IRQ handlerldrr0,=HandleIRQ ;This routine is neededldrr1,=IsrIRQ ;if there isn"t "subs pc,lr,#4" at 0x18, 0x1cstrr1,[r0];Copy and paste RW data/zero initialized dataldrr0, =|Image$$RO$$Limit| ; Get pointer to ROM dataldrr1, =|Image$$RW$$Base| ; and RAM copyldrr3, =|Image$$ZI$$Base| ;Zero init base => top of initialised datacmpr0, r1 ; Check that they are differentbeq%F21 cmpr1, r3 ; Copy init dataldrccr2, [r0], #4 ;--> LDRCC r2, [r0] + ADD r0, r0, #4 strccr2, [r1], #4 ;--> STRCC r2, [r1] + ADD r1, r1, #4bcc%B12 ldrr1, =|Image$$ZI$$Limit| ; Top of zero init segmentmovr2, #03 cmpr3, r1 ; Zero initstrccr2, [r3], #4bcc%B3 [ :LNOT:THUMBCODE blMain ;Don"t use main() because ...... b. ] [ THUMBCODE ;for start-up code for Thumb mode orrlr,pc,#1 bxlr CODE16 blMain ;Don"t use main() because ...... b. CODE32 ];function initializing stacksInitStacks;Don"t use DRAM,such as stmfd,ldmfd......;SVCstack is initialized before;Under toolkit ver 2.5, "msr cpsr,r1" can be used instead of "msr cpsr_cxsf,r1"mrsr0,cpsrbicr0,r0,#MODEMASKorrr1,r0,#UNDEFMODE|NOINTmsrcpsr_cxsf,r1;UndefModeldrsp,=UndefStackorrr1,r0,#ABORTMODE|NOINTmsrcpsr_cxsf,r1;AbortModeldrsp,=AbortStackorrr1,r0,#IRQMODE|NOINTmsrcpsr_cxsf,r1;IRQModeldrsp,=IRQStack orrr1,r0,#FIQMODE|NOINTmsrcpsr_cxsf,r1;FIQModeldrsp,=FIQStackbicr0,r0,#MODEMASK|NOINTorrr1,r0,#SVCMODEmsrcpsr_cxsf,r1;SVCModeldrsp,=SVCStack;USER mode has not be initialized.movpc,lr ;The LR register won"t be valid if the current mode is not SVC mode.LTORGSMRDATA DATA ; Memory configuration should be optimized for best performance ; The following parameter is not optimized. ; Memory access cycle parameter strategy; 1) The memory settings is safe parameters even at HCLK=75Mhz.; 2) SDRAM refresh period is for HCLK=75Mhz. DCD (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)) DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;GCS0 DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;GCS1 DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;GCS2 DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ;GCS3 DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ;GCS4 DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ;GCS5 DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6 DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7 DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) DCD 0x32 ;SCLK power saving mode, BANKSIZE 128M/128M DCD 0x30 ;MRSR6 CL=3clk DCD 0x30 ;MRSR7; DCD 0x20 ;MRSR6 CL=2clk; DCD 0x20 ;MRSR7 ALIGN AREA RamData, DATA, READWRITE ^ _ISR_STARTADDRESSHandleReset # 4HandleUndef # 4HandleSWI # 4HandlePabort # 4HandleDabort # 4HandleReserved # 4HandleIRQ # 4HandleFIQ # 4;Don"t use the label "IntVectorTable",;The value of IntVectorTable is different with the address you think it may be.;IntVectorTableHandleEINT0 # 4HandleEINT1 # 4HandleEINT2 # 4HandleEINT3 # 4HandleEINT4_7# 4HandleEINT8_23# 4HandleRSV6# 4HandleBATFLT # 4HandleTICK # 4HandleWDT# 4HandleTIMER0 # 4HandleTIMER1 # 4HandleTIMER2 # 4HandleTIMER3 # 4HandleTIMER4 # 4HandleUART2 # 4HandleLCD # 4HandleDMA0# 4HandleDMA1# 4HandleDMA2# 4HandleDMA3# 4HandleMMC# 4HandleSPI0# 4HandleUART1# 4HandleRSV24# 4HandleUSBD# 4HandleUSBH# 4HandleIIC # 4HandleUART0 # 4HandleSPI1 # 4HandleRTC # 4HandleADC # 4 END
上面這個還沒啥注釋的,下面請看這個有注釋的吧,這個是實驗室買的設(shè)備帶的:
;*--------------------------------------------- 文件信息 ---------------------------------------------------- ;*;* 文件名稱 : 2410INIT.S;* 文件功能 : 該文件為ARM9硬件平臺的C語言啟動代碼,用于分配中斷向量表,初始化ISR地址,初始化堆??臻g,;* 初始化應(yīng)用程序執(zhí)行環(huán)境,配置存儲器系統(tǒng),設(shè)定時鐘周期,呼叫主應(yīng)用程序。;* 補充說明 : 基于S3C2410的ARM9硬件平臺的啟動代碼;*-------------------------------------------- 最新版本信息 -------------------------------------------------;* 修改作者 : ARM開發(fā)小組;* 修改日期 : 2005/08/23;* 版本聲明 : V1.0.1;*-------------------------------------------- 歷史版本信息 -------------------------------------------------;* 文件作者 : ARM開發(fā)小組;* 創(chuàng)建日期 : 2004/04/20;* 版本聲明 : v1.0.0;*-----------------------------------------------------------------------------------------------------------;*-----------------------------------------------------------------------------------------------------------;************************************************************************************************************;*/GET option.sGET memcfg.sGET 2410addr.sBIT_SELFREFRESH EQU(1<<22);//Pre-defined constantsUSERMODE EQU 0x10FIQMODE EQU 0x11IRQMODE EQU 0x12SVCMODE EQU 0x13ABORTMODE EQU 0x17UNDEFMODE EQU 0x1bMODEMASK EQU 0x1fNOINT EQU 0xc0;//The location of stacksUserStackEQU(_STACK_BASEADDRESS-0x3800);//0x33ff4800 ~ SVCStack EQU(_STACK_BASEADDRESS-0x2800) ;//0x33ff5800 ~UndefStackEQU(_STACK_BASEADDRESS-0x2400) ;//0x33ff5c00 ~AbortStackEQU(_STACK_BASEADDRESS-0x2000) ;//0x33ff6000 ~IRQStack EQU(_STACK_BASEADDRESS-0x1000) ;//0x33ff7000 ~FIQStackEQU(_STACK_BASEADDRESS-0x0);//0x33ff8000 ~ ;//Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.GBLL THUMBCODE[ {CONFIG} = 16 THUMBCODE SETL {TRUE} CODE32 | THUMBCODE SETL {FALSE} ] MACROMOV_PC_LR [ THUMBCODE bx lr | movpc,lr ]MEND MACROMOVEQ_PC_LR [ THUMBCODE bxeq lr | moveq pc,lr ]MEND MACRO$HandlerLabel HANDLER $HandleLabel$HandlerLabelsubsp,sp,#4 ;//decrement sp(to store jump address)stmfdsp!,{r0} ;//PUSH the work register to stack(lr does"t push because it return to original address)ldr r0,=$HandleLabel;//load the address of HandleXXX to r0ldr r0,[r0] ;//load the contents(service routine start address) of HandleXXXstr r0,[sp,#4] ;//store the contents(ISR) of HandleXXX to stackldmfd sp!,{r0,pc} ;//POP the work register and pc(jump to ISR)MENDIMPORT |Image$$RO$$Limit| ;// End of ROM code (=start of ROM data)IMPORT |Image$$RW$$Base| ;// Base of RAM to initialiseIMPORT |Image$$ZI$$Base| ;// Base and limit of areaIMPORT |Image$$ZI$$Limit| ;// to zero initialise;//IMPORT Main ;// The main entry of mon program AREA Init,CODE,READONLYENTRY ; //1)The code, which converts to Big-endian, should be in little endian code.; //2)The following little endian code will be compiled in Big-Endian mode. ; // The code byte order should be changed as the memory bus width.; //3)The pseudo instruction,DCD can"t be used here because the linker generates error.ASSERT:DEF:ENDIAN_CHANGE[ ENDIAN_CHANGE ASSERT :DEF:ENTRY_BUS_WIDTH [ ENTRY_BUS_WIDTH=32bChangeBigEndian ;//DCD 0xea000007 ] [ ENTRY_BUS_WIDTH=16andeqr14,r7,r0,lsl #20 ;//DCD 0x0007ea00 ] [ ENTRY_BUS_WIDTH=8streqr0,[r0,-r10,ror #1] ;//DCD 0x070000ea ]| bResetHandler ]bHandlerUndef;//handler for Undefined modebHandlerSWI;//handler for SWI interruptbHandlerPabort;//handler for PAbortbHandlerDabort;//handler for DAbortb.;//reservedbHandlerIRQ;//handler for IRQ interrupt bHandlerFIQ;//handler for FIQ interrupt;//@0x20bEnterPWDNChangeBigEndian;//@0x24[ ENTRY_BUS_WIDTH=32 DCD0xee110f10;//0xee110f10 => mrc p15,0,r0,c1,c0,0 DCD0xe3800080;//0xe3800080 => orr r0,r0,#0x80; //Big-endian DCD0xee010f10;//0xee010f10 => mcr p15,0,r0,c1,c0,0][ ENTRY_BUS_WIDTH=16 DCD 0x0f10ee11 DCD 0x0080e380 DCD 0x0f10ee01][ ENTRY_BUS_WIDTH=8 DCD 0x100f11ee DCD 0x800080e3 DCD 0x100f01ee ]DCD 0xffffffff ;//swinv 0xffffff is similar with NOP and run well in both endian mode. DCD 0xffffffffDCD 0xffffffffDCD 0xffffffffDCD 0xffffffffb ResetHandler;//Function for entering power down mode;// 1. SDRAM should be in self-refresh mode.;// 2. All interrupt should be maksked for SDRAM/DRAM self-refresh.;// 3. LCD controller should be disabled for SDRAM/DRAM self-refresh.;// 4. The I-cache may have to be turned on. ;// 5. The location of the following code may have not to be changed.;//void EnterPWDN(int CLKCON); EnterPWDNmov r2,r0;//r2=rCLKCONtst r0,#0x8;//POWER_OFF mode?bne ENTER_POWER_OFFENTER_STOPldr r0,=REFRESHldr r3,[r0];//r3=rREFRESHmov r1, r3orr r1, r1, #BIT_SELFREFRESHstr r1, [r0];//Enable SDRAM self-refreshmov r1,#16 ;//wait until self-refresh is issued. may not be needed.0subs r1,r1,#1bne %B0ldr r0,=CLKCON;//enter STOP mode.str r2,[r0] mov r1,#320subs r1,r1,#1;//1) wait until the STOP mode is in effect.bne %B0;//2) Or wait here until the CPU&Peripherals will be turned-off;// Entering POWER_OFF mode, only the reset by wake-up is available.ldr r0,=REFRESH ;//exit from SDRAM self refresh mode.str r3,[r0]MOV_PC_LRENTER_POWER_OFF;//NOTE.;//1) rGSTATUS3 should have the return address after wake-up from POWER_OFF mode.ldr r0,=REFRESHldr r1,[r0];r1=rREFRESHorr r1, r1, #BIT_SELFREFRESHstr r1, [r0];//Enable SDRAM self-refreshmov r1,#16 ;//Wait until self-refresh is issued,which may not be needed.0subs r1,r1,#1bne %B0ldr r1,=MISCCRldrr0,[r1]orrr0,r0,#(7<<17) ;//Make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE=L during boot-up strr0,[r1]ldr r0,=CLKCONstr r2,[r0] b .;//CPU will die here.WAKEUP_POWER_OFF;//Release SCLKn after wake-up from the POWER_OFF mode.ldr r1,=MISCCRldrr0,[r1]bicr0,r0,#(7<<17) ;//SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:L->Hstrr0,[r1];//Set memory control registers ldrr0,=SMRDATAldrr1,=BWSCON;//BWSCON Addressaddr2, r0, #52;//End address of SMRDATA0 ldrr3, [r0], #4 strr3, [r1], #4 cmpr2, r0bne%B0mov r1,#2560subs r1,r1,#1;//1) wait until the SelfRefresh is released.bne %B0ldr r1,=GSTATUS3 ;//GSTATUS3 has the start address just after POWER_OFF wake-upldr r0,[r1]mov pc,r0LTORG HandlerFIQ HANDLER HandleFIQHandlerIRQ HANDLER HandleIRQHandlerUndef HANDLER HandleUndefHandlerSWI HANDLER HandleSWIHandlerDabort HANDLER HandleDabortHandlerPabort HANDLER HandlePabortIsrIRQ subsp,sp,#4 ;//reserved for PCstmfdsp!,{r8-r9} ldrr9,=INTOFFSETldrr9,[r9]ldrr8,=HandleEINT0addr8,r8,r9,lsl #2ldrr8,[r8]strr8,[sp,#8]ldmfdsp!,{r8-r9,pc};//====================================================================;// ENTRY ;//===================================================================ResetHandlerldrr0,=WTCON ;//watch dog disable ldrr1,=0x0 strr1,[r0]ldrr0,=INTMSKldrr1,=0xffffffff ;//all interrupt disablestrr1,[r0]ldrr0,=INTSUBMSKldrr1,=0x7ff;//all sub interrupt disable, 2002/04/10strr1,[r0][ {FALSE} ;// rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~data & 0xf)<<4); ;// Led_Displayldrr0,=GPFCONldrr1,=0x5500strr1,[r0]ldrr0,=GPFDATldrr1,=0x10strr1,[r0]];//To reduce PLL lock time, adjust the LOCKTIME register. ldrr0,=LOCKTIMEldrr1,=0xffffffstrr1,[r0] [ PLL_ON_START;//Configure MPLLldrr0,=MPLLCON ldrr1,=((0xa1<<12)+(3<<4)+0x1) ;//Fin=12MHz,Fout=50MHzstrr1,[r0]];//Check if the boot is caused by the wake-up from POWER_OFF mode.ldrr1,=GSTATUS2ldrr0,[r1]tstr0,#0x2 ;//In case of the wake-up from POWER_OFF mode, go to POWER_OFF_WAKEUP handler. bneWAKEUP_POWER_OFFEXPORT StartPointAfterPowerOffWakeUpStartPointAfterPowerOffWakeUp;//Set memory control registers ldrr0,=SMRDATAldrr1,=BWSCON;//BWSCON Addressaddr2, r0, #52;//End address of SMRDATA0 ldrr3, [r0], #4 strr3, [r1], #4 cmpr2, r0bne%B0 ;//Initialize stacksblInitStacks ;// Setup IRQ handlerldrr0,=HandleIRQ ;//This routine is neededldrr1,=IsrIRQ ;//if there isn"t "subs pc,lr,#4" at 0x18, 0x1cstrr1,[r0];//Copy and paste RW data/zero initialized dataldrr0, =|Image$$RO$$Limit| ; Get pointer to ROM dataldrr1, =|Image$$RW$$Base| ; and RAM copyldrr3, =|Image$$ZI$$Base| ;//Zero init base => top of initialised datacmpr0, r1 ;// Check that they are differentbeq%F21 cmpr1, r3 ;// Copy init dataldrccr2, [r0], #4 ;//--> LDRCC r2, [r0] + ADD r0, r0, #4 strccr2, [r1], #4 ;//--> STRCC r2, [r1] + ADD r1, r1, #4bcc%B12 ldrr1, =|Image$$ZI$$Limit| ;// Top of zero init segmentmovr2, #03 cmpr3, r1 ;// Zero initstrccr2, [r3], #4bcc%B3;//呼叫主應(yīng)用程序b UARTUART ldr r0, =GPHCON ;//設(shè)置RxD0,TxD0引腳 ldr r1, =0x2afaaa str r1, [r0] ldr r0, =GPHUP ldr r1, =0x7ff str r1, [r0] ; // The pull up function is disabled GPH[10:0] ldr r0, =UFCON0 ;//禁用FIFO ldr r1, =0x0 str r1, [r0] ldr r0, =UMCON0 ;//禁用AFC ldr r1, =0x0 str r1, [r0] ldr r0, =ULCON0 ;//設(shè)置線寄存器 ldr r1, =0x3 ; //UART LINE CONFIG 正常模式,無奇偶校驗,一個停止位,8個數(shù)據(jù)位 str r1, [r0] ldr r0, =UCON0 ;//設(shè)置Uart0控制器 ldr r1, =0x245;//RX邊沿觸發(fā),TX電平觸發(fā),禁用延時中斷,使用RX 錯誤中斷,正常操作模式,中斷請求或表決模式 str r1, [r0] ldr r0, =UBRDIV0 ;//設(shè)置波特率為115200 ldr r1, =0x1a ;//int(50700000 / 16 / 115200) - 1 = 26 str r1, [r0] mov r1, #100Delay sub r1, r1, #0x1 bne Delay ;//開中斷 ldr r0, =INTMSK ldr r1, [r0] and r1, r1, #0xefffffff str r1, [r0] MOV R5 , #127 ;//設(shè)置要打印的字符的個數(shù) MOV R1 , #0x0 ;//設(shè)置要打印的字符LOOP LDR R3 , =UTRSTAT0 LDR R2 , [R3] TST R2 ,#0x04 ;//判斷發(fā)送緩沖區(qū)是否為空 BEQ LOOP ;//為空則執(zhí)行下邊的語句,不為空則跳轉(zhuǎn)到LOOP LDR R0 , =UTXH0 STR R1 ,[R0] ;//向數(shù)據(jù)緩沖區(qū)放置要發(fā)送的數(shù)據(jù) ADD R1, R1, #1 SUB R5 ,R5, #0x01 ;//計數(shù)器減一 CMP R5 ,#0x0 BNE LOOP LOOP2 B LOOP2 ; /*; pclk = PCLK;; rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disable; rUFCON1 = 0x0; //UART channel 1 FIFO control register, FIFO disable; rUFCON2 = 0x0; //UART channel 2 FIFO control register, FIFO disable; rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disable; rUMCON1 = 0x0; //UART chaneel 1 MODEM control register, AFC disable ;//UART0; rULCON0 = 0x3; //Line control register : Normal,No parity,1 stop,8 bits; // [10] [9] [8] [7] [6] [5] [4] [3:2] [1:0]; // Clock Sel, Tx Int, Rx Int, Rx Time Out, Rx err, Loop-back, Send break, Transmit Mode, Receive Mode; // 0 1 0 , 0 1 0 0 , 01 01; // PCLK Level Pulse Disable Generate Normal Normal Interrupt or Polling; rUCON0 = 0x245; // Control register;// rUBRDIV0=( (int)(pclk/16./baud) -1 ); //Baud rate divisior register 0; rUBRDIV0=( (int)(pclk/16./baud+0.5) -1 ); //Baud rate divisior register 0 ;//UART1; rULCON1 = 0x3;; rUCON1 = 0x245;; rUBRDIV1=( (int)(pclk/16./baud) -1 );; ;//UART2; rULCON2 = 0x3;; rUCON2 = 0x245;; rUBRDIV2=( (int)(pclk/16./baud) -1 ); ;; for(i=0;i<100;i++);; ; */;//END OF UART HERE;//function initializing stacksInitStacks;//Don"t use DRAM,such as stmfd,ldmfd......;//SVCstack is initialized before;//Under toolkit ver 2.5, "msr cpsr,r1" can be used instead of "msr cpsr_cxsf,r1"mrsr0,cpsrbicr0,r0,#MODEMASKorrr1,r0,#UNDEFMODE|NOINTmsrcpsr_cxsf,r1;//UndefModeldrsp,=UndefStackorrr1,r0,#ABORTMODE|NOINTmsrcpsr_cxsf,r1;//AbortModeldrsp,=AbortStackorrr1,r0,#IRQMODE|NOINTmsrcpsr_cxsf,r1;//IRQModeldrsp,=IRQStack orrr1,r0,#FIQMODE|NOINTmsrcpsr_cxsf,r1;//FIQModeldrsp,=FIQStackbicr0,r0,#MODEMASK|NOINTorrr1,r0,#SVCMODEmsrcpsr_cxsf,r1;//SVCModeldrsp,=SVCStack;//USER mode has not be initialized.movpc,lr ;//The LR register won"t be valid if the current mode is not SVC mode.LTORG; incbin ..\..\Font\Hzk16.binSMRDATA DATA;// Memory configuration should be optimized for best performance ;// The following parameter is not optimized. ;// Memory access cycle parameter strategy;// 1) The memory settings is safe parameters even at HCLK=75Mhz.;// 2) SDRAM refresh period is for HCLK=75Mhz. DCD (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)) DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;//GCS0 DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;//GCS1 DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;//GCS2 DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ;//GCS3 DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ;//GCS4 DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ;//GCS5 DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;//GCS6 DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;//GCS7 DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) DCD 0x32 ;//SCLK power saving mode, BANKSIZE 128M/128M DCD 0x30 ;//MRSR6 CL=3clk DCD 0x30 ;//MRSR7;// DCD 0x20 ;//MRSR6 CL=2clk;/// DCD 0x20 ;//MRSR7 ALIGN AREA RamData, DATA, READWRITE ^ _ISR_STARTADDRESSHandleReset # 4HandleUndef # 4HandleSWI # 4HandlePabort # 4HandleDabort # 4HandleReserved # 4HandleIRQ # 4HandleFIQ # 4;//Don"t use the label "IntVectorTable",;//The value of IntVectorTable is different with the address you think it may be.;//IntVectorTableHandleEINT0 # 4HandleEINT1 # 4HandleEINT2 # 4HandleEINT3 # 4HandleEINT4_7# 4HandleEINT8_23# 4HandleRSV6# 4HandleBATFLT # 4HandleTICK # 4HandleWDT# 4HandleTIMER0 # 4HandleTIMER1 # 4HandleTIMER2 # 4HandleTIMER3 # 4HandleTIMER4 # 4HandleUART2 # 4HandleLCD # 4HandleDMA0# 4HandleDMA1# 4HandleDMA2# 4HandleDMA3# 4HandleMMC# 4HandleSPI0# 4HandleUART1# 4HandleRSV24# 4HandleUSBD# 4HandleUSBH# 4HandleIIC # 4HandleUART0 # 4HandleSPI1 # 4HandleRTC # 4HandleADC # 4 END