新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM啟動代碼注釋

        ARM啟動代碼注釋

        作者: 時間:2016-11-11 來源:網絡 收藏
        \\\\\\

        下邊是完整的工程

        本文引用地址:http://www.104case.com/article/201611/316916.htm

        運行平臺:mini2440

        啟動代碼ourdev_444408.rar(文件大小:61K)(原文件名:MicroOS.rar)
        ;---------------------------------------------------------------------
        ;startup.s
        ;系統啟動代碼
        ;起始時間 : 2009.5.7----->2009.5.11
        ;---------------------------------------------------------------------



        ;---------------------------------------------------------------------
        GET ./Include/s3c2440.inc ;寄存器地址信息
        GET ./Include/memcfg.inc ;內存控制器配置信息

        ;處理器模式
        USERMODE EQU 0x10
        FIQMODE EQU 0x11
        IRQMODE EQU 0x12
        SVCMODE EQU 0x13
        ABORTMODE EQU 0x17
        UNDEFMODE EQU 0x1b
        SYSMODE EQU 0x1f
        ;相關掩碼
        MODEMASK EQU 0x1f
        NOINT EQU 0xc0

        ;各個處理器模式下堆棧設置
        _STACK_BASEADDRESS EQU 0x33ff8000 ;BANK664MB頂部
        UserStack 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~

        ;導入操作系統入口函數
        IMPORT OSEntry

        ;導入外部C語言編寫的異常與中斷處理函數
        IMPORT vectorUNDEF
        IMPORT vectorSWI
        IMPORT vectorPABT
        IMPORT vectorDABT
        IMPORT vectorIRQ
        IMPORT vectorFIQ

        ;導入鏡像裝載域段起始地址
        IMPORT|Image$$RO$$Limit|;EndofROMcode(=startofROMdata)
        IMPORT|Image$$RW$$Base|;BaseofRAMtoinitialise
        IMPORT|Image$$ZI$$Base|;Baseandlimitofarea
        IMPORT|Image$$ZI$$Limit|;tozeroinitialise
        ;--------------------------------------------------------------------


        ;------------------------------------------------------
        AREAstartup,CODE,READONLY

        ENTRY

        ;系統向量表

        b vectorRESET ;復位向量
        b vectorUNDEF ;未定義指令
        b vectorSWI ;軟中斷
        b vectorPABT ;預取指終止
        b vectorDABT ;數據終止
        b . ;系統保留
        b vectorIRQ ;外部中斷
        b vectorFIQ ;快速中斷
        ;-------------------------------------------------------

        ;--------------------------------------------------------------------------
        ;復位向量
        ;復位向量是ARM處理器上電后第一個被執行的異常
        ;此時系統處理管理(SVC)模式

        vectorRESET

        ;復位向量有以下六件事要做

        ;第一步 :關閉看門狗定時器屏蔽所有中斷
        ;第二步:配置系統時鐘
        ;第三步 :配置內存控制器
        ;第四步 :配置每種處理器模式下堆棧指針
        ;第五步 :初始化鏡像運行域
        ;第六步 :跳轉到操作系統入口


        ;------------------------------------------
        ;第一步 :關閉看門狗定時器
        ;具體內容請參看s3c2440a數據手冊的第18章
        ldr r0,=WTCON
        ldr r1,=0x0
        str r1,[r0,#0x0]

        ;屏蔽所有中斷
        ldrr0,=INTMSK
        ldrr1,=0xffffffff
        strr1,[r0]
        ;------------------------------------------



        ;------------------------------------------
        ;第二步 :配置系統時鐘
        ;具體內容請看手冊第7章

        ;先減少鎖相環鎖定時間,s3c2440a要求PLL
        ;鎖定時間>300us,在上電時s3c2440a預設值
        ;mpll為晶體頻率,我用的晶體頻率為12MHz
        ;300us*12M=3600設置LOCKTIME=0xfff
        ;足夠了
        ldrr0,=LOCKTIME
        ldrr1,=0xfff0fff0 ;高16為對應UPLL
        ;低16為對應MPLL
        strr1,[r0,#0x0]

        ;根據器件手冊我們還有以下幾個事要做
        ;step1.配置UPLL
        ;step2.配置MPLL
        ;注:手冊要求先配置UPLL后MPLL
        ; 且之間要間隔7NOP
        ; 詳請看手冊第7-21.
        ;step3.配置分頻系數

        ;step1:
        ldrr0,=UPLLCON
        ldrr1,=((56<<12)+(2<<4)+2)
        ldrr1,[r0]

        ;按手冊要求插入7個NOP
        nop
        nop
        nop
        nop
        nop
        nop
        nop

        ;step2:
        ldrr0,=MPLLCON
        ldrr1,=((127<<12)+(2<<4)+1)
        ldrr1,[r0]

        ;step3:
        ldrr0,=CLKDIVN
        ldrr1,=((0<<3)+(2<<2)+1)
        ldrr1,[r0]
        ;------------------------------------------



        ;------------------------------------------
        ;第三步 :配置內存控制器
        ;內存控制內的寄存器器地址是連續分布的
        ;從0x4800_0000--0x4800_0030,所以可以
        ;通過一個循環依次填入各個寄存器的內容

        ldrr0,=SMRDATA ;裝入配置值的地址
        ldrr1,=BWSCON ;裝入起始寄存器地址
        addr2,r0,#0x34 ;計算結束地址

        ;下面是用于向內存控制器
        ;裝入配置信息的循環
        0
        ldrr3,[r0],#4 ;裝入配置值到r3,后變址
        strr3,[r1],#4 ;把r3內包含的配置值寫入
        ;內存控制器的寄存器
        cmpr2,r0 ;結束否?
        bne%B0 ;沒結束則繼續
        ;------------------------------------------



        ;------------------------------------------
        ;第四步 :配置每種處理器模式下堆棧指針
        ;方法與原則:
        ;1: 通過CPSR寄存器切換處理器模式
        ;2: 對CPSR的操作方式為讀-修改-寫回
        ;3: 絕對不要跳到用戶模式,跳過去容易
        ; 回來就難了
        ;4:切到新處理器模式后要屏蔽IRQ和FIQ
        ; 防止在未設置好堆棧前進入中斷處理
        ; 程序,但是在啟動代碼的最先我們已
        ; 經屏蔽了所有的32個中斷源,所以感
        ; 覺是否屏蔽都可以

        ;step1:先把程序狀態寄存器讀到r0
        mrs r0,cpsr

        ;step2:清除處理器模式位(最前面5位)
        bic r0,r0,#MODEMASK

        ;step3: 設置未定義狀態下的堆棧指針
        orr r1,r0,#UNDEFMODE|NOINT
        msr cpsr_cxsf,r1 ;UndefMode
        ldr sp,=UndefStack ;UndefStack=0x33FF_5C00

        ;step4:設置終止狀態下的堆棧指針
        orr r1,r0,#ABORTMODE|NOINT
        msr cpsr_cxsf,r1 ;AbortMode
        ldr sp,=AbortStack ;AbortStack=0x33FF_6000

        ;step5: 設置中斷模式下的堆棧指針
        orr r1,r0,#IRQMODE|NOINT
        msr cpsr_cxsf,r1 ;IRQMode
        ldr sp,=IRQStack ;IRQStack=0x33FF_7000

        ;step6: 設置快速中斷模式下的堆棧指針
        orr r1,r0,#FIQMODE|NOINT
        msr cpsr_cxsf,r1 ;FIQMode
        ldr sp,=FIQStack ;FIQStack=0x33FF_8000

        ;step7:設置管理模式下的堆棧指針
        orr r1,r0,#SVCMODE|NOINT
        msr cpsr_cxsf,r1 ;SVCMode
        ldr sp,=SVCStack ;SVCStack=0x33FF_5800

        ;step8:因為管理模式與用戶模式共用
        ; 堆棧指針,所以借著系統模式
        ; 來設置用戶模式的堆棧指針
        orrr1,r0,#SYSMODE|NOINT
        msrcpsr_cxsf,r1 ;SYSMode
        ldrsp,=UserStack ;SVCStack&USERMode=0x33ff4800

        ;現在處理器處于系統模式
        ;------------------------------------------



        ;------------------------------------------
        ;第五步 :初始化鏡像運行域
        ;復制RW段和ZI段到SDRAM指定地址

        LDRr0,=|Image$$RO$$Limit|;裝入RO段結束地址
        LDRr1,=|Image$$RW$$Base|;裝入RW段起始地址
        LDRr3,=|Image$$ZI$$Base|;裝入ZI段起始地址


        ;|Image$$RO$$Limit|==|Image$$RW$$Base|?跳過RW段復制:復制RW段
        CMPr0,r1
        BEQ%F2

        ;復制RW段
        1
        CMPr1,r3
        LDRCCr2,[r0],#4
        STRCCr2,[r1],#4
        BCC%B1
        2
        LDRr1,=|Image$$ZI$$Limit|
        MOVr2,#0

        ;構造ZI段
        3
        CMPr3,r1
        STRCCr2,[r3],#4
        BCC%B3

        ;------------------------------------------



        ;------------------------------------------
        ;第六步 :跳轉到操作系統入口

        b OSEntry ;不要使用main,因為如果使用main
        ;ads還會調用_main()初始化RW和ZI
        ;段,但是那里的數據和本程序不同

        b .

        ;------------------------------------------

        ;---------------------------------------------------------------------------



        SMRDATADATA

        ;這里是內存控制器的配置數據
        ;配置數據需要根據你使用的存儲器修改
        ;在第三步時會將以下數據寫入
        ;內存控制器的相關寄存器中
        ;共13個寄存器的配置值

        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)
        DCD0x32 ;SCLKpowersavingmode,BANKSIZE128M/128M
        DCD0x30 ;MRSR6CL=3clk
        DCD0x30 ;MRSR7CL=3clk

        ALIGN ;數據邊界對齊

        END


        我在寫一個arm920T的微型OS,主要是想借著寫OS的過程學習ARM的底層編程,然后跳到Linux。啟動代碼是固件的一部分,最經學校要搞個設計,不知OS什么時候能寫好,反正搞定后立即發帖。

        ;*

        ;* 文件名稱 : 2410INIT.S

        ;* 文件功能 : S3C2410 啟動代碼,配置存儲器,ISR,堆棧,初始化C向量地址

        ;* 補充說明 :

        ;*-------------------------------------------- 最新版本信息 -------------------------------------------------

        ;* 修改作者 : ARM開發小組

        ;* 修改日期 : 2004/00/00

        ;* 版本聲明 : V0.1

        ;*-------------------------------------------- 歷史版本信息 -------------------------------------------------

        ;* 文件作者 : kwtark(samsung)

        ;* 創建日期 : 2002/02/25

        ;* 版本聲明 : 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 2410addr.s ;定義了2410各各寄存器的地址

        GET memcfg.s ;定義了2410各內存bank的帶寬值和訪問參數

        BIT_SELFREFRESH EQU(1<<22) ;定義了幾個常數 _STACK_BASEADDRESS EQU 0x33ff8000堆棧基地址

        ; _ISR_STARTADDRESS EQU 0x33ffff00 中斷向量表基地址

        ;Pre-defined constants 處理器模式預定義常量

        USERMODE EQU 0x10

        FIQMODE EQU 0x11

        IRQMODE EQU 0x12

        SVCMODE EQU 0x13

        ABORTMODE EQU 0x17

        UNDEFMODE EQU 0x1b

        MODEMASK EQU 0x1f

        NOINT EQU 0xc0 ;屏蔽中斷位

        ;/*************定義處理器各模式下堆棧地址常量*******************/

        UserStack 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...@ADS1.0) is used. ADS編譯器的檢查 */

        GBLL THUMBCODE

        [ {CONFIG} = 16

        THUMBCODE SETL {TRUE}

        CODE32

        |

        THUMBCODE SETL {FALSE}

        ]

        MACRO

        MOV_PC_LR

        [ THUMBCODE

        bx lr

        |

        movpc,lr

        ]

        MEND

        MACRO

        MOVEQ_PC_LR

        [ THUMBCODE

        bxeq lr

        |

        moveq pc,lr

        ]

        MEND

        ;/*******************************************************************************************************/

        ; 正式代碼的開始,首先是分配中斷向表

        ;/******************************************************************************************************/

        MACRO;先定義了一個負責處理中斷宏

        $HandlerLabel HANDLER $HandleLabel

        $HandlerLabel

        subsp,sp,#4 ;減少sp,保存跳轉地址

        stmfdsp!,{r0} ;PUSH the work register to stack(lr doest push because it return to original address)

        ldr r0,=$HandleLabel ;load the address of HandleXXX to r0

        ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX

        str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack

        ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)

        MEND

        IMPORT |Image$$RO$$Limit| ;End of ROM code (=start of ROM data)

        IMPORT |Image$$RW$$Base| ;Base of RAM to initialise

        IMPORT |Image$$ZI$$Base| ;Base and limit of area

        IMPORT |Image$$ZI$$Limit| ;to zero initialise

        IMPORT Main     ;The main entry of mon program

        ;指示編譯器的符號不是在本源文件中定義的,而是在其他源文件中

        ;定義的,在本源文件中可能引用該符號

        AREA Init,CODE,READONLY ;聲明一個代碼段,名為:Init

        ENTRY;程序的入口點

        ;//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 cant be used here because the linker generates error.

        ASSERT:DEF:ENDIAN_CHANGE ;//斷言已經定義大端模式

        [ ENDIAN_CHANGE

        ASSERT :DEF:ENTRY_BUS_WIDTH

        [ ENTRY_BUS_WIDTH=32

        bChangeBigEndian   ;DCD 0xea000007

        ]

        [ ENTRY_BUS_WIDTH=16

        andeqr14,r7,r0,lsl #20 ;DCD 0x0007ea00

        ]

        [ ENTRY_BUS_WIDTH=8

        streqr0,[r0,-r10,ror #1] ;DCD 0x070000ea

        ]

        |

        bResetHandler

        ]

        bHandlerUndef   ;handler for Undefined mode

        bHandlerSWI   ;handler for SWI interrupt

        bHandlerPabort  ;handler for PAbort

        bHandlerDabort ;handler for DAbort

        b.     ;reserved

        bHandlerIRQ   ;handler for IRQ interrupt

        bHandlerFIQ   ;handler for FIQ interrupt

        ;//@0x20

        bEnterPWDN

        ChangeBigEndian

        ;//@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 0xffffffff

        DCD 0xffffffff

        DCD 0xffffffff

        DCD 0xffffffff

        b 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);

        EnterPWDN

        mov r2,r0      ;r2=rCLKCON

        tst r0,#0x8     ;POWER_OFF mode?

        bne ENTER_POWER_OFF

        ENTER_STOP

        ldr r0,=REFRESH

        ldr r3,[r0]     ;r3=rREFRESH

        mov r1, r3

        orr r1, r1, #BIT_SELFREFRESH

        str r1, [r0]     ;Enable SDRAM self-refresh

        mov r1,#16    ;wait until self-refresh is issued. may not be needed.

        0subs r1,r1,#1

        bne %B0

        ldr r0,=CLKCON    ;enter STOP mode.

        str r2,[r0]

        mov r1,#32

        0subs 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_LR

        ENTER_POWER_OFF

        ;//NOTE.

        ;//1) rGSTATUS3 should have the return address after wake-up from POWER_OFF mode.

        ldr r0,=REFRESH

        ldr r1,[r0]    ;r1=rREFRESH

        orr r1, r1, #BIT_SELFREFRESH

        str r1, [r0]    ;Enable SDRAM self-refresh

        mov r1,#16   ;Wait until self-refresh is issued,which may not be needed.

        0subs r1,r1,#1

        bne %B0

        ldr r1,=MISCCR

        ldrr0,[r1]

        orrr0,r0,#(7<<17) ;Make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE="L" during boot-up

        strr0,[r1]

        ldr r0,=CLKCON

        str r2,[r0]

        b .      ;CPU will die here.

        WAKEUP_POWER_OFF

        ;Release SCLKn after wake-up from the POWER_OFF mode.

        ldr r1,=MISCCR

        ldrr0,[r1]

        bicr0,r0,#(7<<17) ;SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:L->H

        strr0,[r1]

                ;Set memory control registers

        ldrr0,=SMRDATA

        ldrr1,=BWSCON   ;BWSCON Address

        addr2, r0, #52   ;End address of SMRDATA

        0

        ldrr3, [r0], #4

        strr3, [r1], #4

        cmpr2, r0

        bne%B0

        mov r1,#256

        0subs 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-up

        ldr r0,[r1]

        mov pc,r0

        LTORG

        HandlerFIQ HANDLER HandleFIQ

        HandlerIRQ HANDLER HandleIRQ

        HandlerUndef HANDLER HandleUndef

        HandlerSWI HANDLER HandleSWI

        HandlerDabort HANDLER HandleDabort

        HandlerPabort HANDLER HandlePabort

        IsrIRQ

        subsp,sp,#4 ;reserved for PC

        stmfdsp!,{r8-r9}

        ldrr9,=INTOFFSET

        ldrr9,[r9]

        ldrr8,=HandleEINT0

        addr8,r8,r9,lsl #2

        ldrr8,[r8]

        strr8,[sp,#8]

        ldmfdsp!,{r8-r9,pc}

        ;================================================================================================

        ; ENTRY 將看門狗、中斷之類的程序關掉,省得他們來打擾初始化程序的進行

        ;=================================================================================================

        ResetHandler

        ldrr0,=WTCON ;watch dog disable

        ldrr1,=0x0

        strr1,[r0]

        ldrr0,=INTMSK

        ldrr1,=0xffffffff ;all interrupt disable

        strr1,[r0]

        ldrr0,=INTSUBMSK

        ldrr1,=0x7ff   ;all sub interrupt disable, 2002/04/10

        strr1,[r0]

        [ {FALSE}

             ;rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~data & 0xf)<<4);

             ;Led_Display

        ldrr0,=GPFCON

        ldrr1,=0x5500

        strr1,[r0]

        ldrr0,=GPFDAT

        ldrr1,=0x10

        strr1,[r0]

        ]

        ;To reduce PLL lock time, adjust the LOCKTIME register.

        ldrr0,=LOCKTIME

        ldrr1,=0xffffff

        strr1,[r0]

        [ PLL_ON_START

        ;Configure MPLL

        ldrr0,=MPLLCON;//設置時鐘頻率

        ldrr1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ;Fin=12MHz,Fout=50MHz

        strr1,[r0]

        ]

        ;Check if the boot is caused by the wake-up from POWER_OFF mode.

        ldrr1,=GSTATUS2

        ldrr0,[r1]

        tstr0,#0x2

        ;In case of the wake-up from POWER_OFF mode, go to POWER_OFF_WAKEUP handler.

        bneWAKEUP_POWER_OFF

        EXPORT StartPointAfterPowerOffWakeUp

        StartPointAfterPowerOffWakeUp

        ;Set memory control registers

        ldrr0,=SMRDATA

        ldrr1,=BWSCON ;BWSCON Address

        addr2, r0, #52 ;End address of SMRDATA

        0

        ldrr3, [r0], #4

        strr3, [r1], #4

        cmpr2, r0

        bne%B0

        ;Initialize stacks

        blInitStacks

        ;Setup IRQ handler

        ldrr0,=HandleIRQ ;This routine is needed

        ldrr1,=IsrIRQ ;if there isnt subs pc,lr,#4 at 0x18, 0x1c

        strr1,[r0]

                 ;Copy and paste RW data/zero initialized data

        ldrr0, =|Image$$RO$$Limit| ; Get pointer to ROM data

        ldrr1, =|Image$$RW$$Base| ; and RAM copy

        ldrr3, =|Image$$ZI$$Base|

        ;Zero init base => top of initialised data

        cmpr0, r1 ;Check that they are different

        beq%F2

        1

        cmpr1, r3 ;Copy init data

        ldrccr2, [r0], #4 ;--> LDRCC r2, [r0] + ADD r0, r0, #4

        strccr2, [r1], #4 ;--> STRCC r2, [r1] + ADD r1, r1, #4

        bcc%B1

        2

        ldrr1, =|Image$$ZI$$Limit| ;Top of zero init segment

        movr2, #0

        3

        cmpr3, r1 ; Zero init

        strccr2, [r3], #4

        bcc%B3

        [ :LNOT:THUMBCODE

        blMain ;Dont use main() because ......

        b.

        ]

        [ THUMBCODE ;for start-up code for Thumb mode

        orrlr,pc,#1

        bxlr

        CODE16

        blMain ;Dont use main() because ......

        b.

        CODE32

        ]

        ;//function initializing stacks 初始化堆棧

        InitStacks

        ;Dont 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,cpsr

        bicr0,r0,#MODEMASK

        orrr1,r0,#UNDEFMODE|NOINT

        msrcpsr_cxsf,r1    ;UndefMode

        ldrsp,=UndefStack

        orrr1,r0,#ABORTMODE|NOINT

        msrcpsr_cxsf,r1    ;AbortMode

        ldrsp,=AbortStack

        orrr1,r0,#IRQMODE|NOINT

        msrcpsr_cxsf,r1    ;IRQMode

        ldrsp,=IRQStack

        orrr1,r0,#FIQMODE|NOINT

        msrcpsr_cxsf,r1    ;FIQMode

        ldrsp,=FIQStack

        bicr0,r0,#MODEMASK|NOINT

        orrr1,r0,#SVCMODE

        msrcpsr_cxsf,r1    ;SVCMode

        ldrsp,=SVCStack

        ;USER mode has not be initialized.

        movpc,lr

        ;The LR register wont be valid if the current mode is not SVC mode.

        LTORG

        SMRDATA 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_STARTADDRESS

        HandleReset # 4

        HandleUndef # 4

        HandleSWI # 4

        HandlePabort # 4

        HandleDabort # 4

        HandleReserved # 4

        HandleIRQ # 4

        HandleFIQ # 4

        ;//Dont use the label IntVectorTable,

        ;//The value of IntVectorTable is different with the address you think it may be.

        ;//IntVectorTable

        HandleEINT0 # 4

        HandleEINT1 # 4

        HandleEINT2 # 4

        HandleEINT3 # 4

        HandleEINT4_7 # 4

        HandleEINT8_23# 4

        HandleRSV6 # 4

        HandleBATFLT # 4

        HandleTICK # 4

        HandleWDT # 4

        HandleTIMER0 # 4

        HandleTIMER1 # 4

        HandleTIMER2 # 4

        HandleTIMER3 # 4

        HandleTIMER4 # 4

        HandleUART2 # 4

        HandleLCD # 4

        HandleDMA0 # 4

        HandleDMA1 # 4

        HandleDMA2 # 4

        HandleDMA3 # 4

        HandleMMC # 4

        HandleSPI0 # 4

        HandleUART1 # 4

        HandleRSV24 # 4

        HandleUSBD # 4

        HandleUSBH # 4

        HandleIIC # 4

        HandleUART0 # 4

        HandleSPI1 # 4

        HandleRTC # 4

        HandleADC # 4

        END

        ;=========================================

        ; 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

        ;=========================================

        GET option.s

        GET memcfg.s

        GET 2410addr.s

        BIT_SELFREFRESH EQU (1<<22)

        ;ARM異常模式的定義

        ;Pre-defined constants

        USERMODE EQU 0x10

        FIQMODE EQU 0x11

        IRQMODE EQU 0x12

        SVCMODE EQU 0x13

        ABORTMODE EQU 0x17

        UNDEFMODE EQU 0x1b

        MODEMASK EQU 0x1f

        NOINT EQU 0xc0

        ;ARM個異常模式堆棧

        ;The location of stacks

        UserStack 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...@ADS1.0) is used.

        GBLL THUMBCODE

        [ {CONFIG} = 16 ;[ = IF

        THUMBCODE SETL {TRUE}

        CODE32 ; CODE32 表明一下操作都在ARM狀態

        | ;| = ELSE

        THUMBCODE SETL {FALSE}

        ] ;] = ENDIF

        ;宏定義MOV_PC_LR

        MACRO

        MOV_PC_LR

        [ THUMBCODE

        bx lr

        |

        mov pc,lr

        ]

        MEND

        MACRO

        MOVEQ_PC_LR

        [ THUMBCODE

        bxeq lr

        |

        moveq pc,lr

        ]

        MEND

        ;宏定義-進入異常流程

        ;HANDLER-宏的名稱

        ;$HandleLabel-宏的參數

        ;這個宏的作用是把各個中斷程序的地址裝入當前的PC,2410有兩種裝斷模式 一種是沒有中斷向量表,一種是使用中斷向量表的

        ;使用中斷向量表只能是IRQ方式,當使用中斷向量表的時候,中斷發生時由2410的中斷控制器自動跳轉到

        ;相應的位置。

        MACRO

        $HandlerLabel HANDLER $HandleLabel

        $HandlerLabel

        sub sp,sp,#4 ;decrement sp(to store jump address)

        stmfd sp!,{r0} ;PUSH the work register to stack(lr doest push because it return to original address)!表示數據傳送完畢后,將最后的地址寫入基址寄存器

        ldr r0,=$HandleLabel;load the address of Handle1XXX to r0

        ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX

        str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack

        ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)

        MEND

        ;連接器生成的輸出段相關的符號

        ;引入連接器生成的映象文件的各個部分地址。

        ;OR-只讀區域、RW-讀寫區域、ZI-初始化為0的區域。

        IMPORT |Image$$RO$$Base| ; Base of ROM code

        IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)

        IMPORT |Image$$RW$$Base| ; Base of RAM to initialise

        IMPORT |Image$$ZI$$Base| ; Base and limit of area

        IMPORT |Image$$ZI$$Limit| ; to zero initialise

        ;引入外部函數Main,進入C程序。

        IMPORT Main ; The main entry of mon program

        ;IMPORT LEDTEST

        ;定義ARM匯編程序段,段名為SelfBoot,程序段為只讀的代碼段。

        AREA SelfBoot, CODE, READONLY

        ;程序入口地址

        ENTRY

        ResetEntry

        ;程序段執行的第一跳指令,為8個異常中斷處理向量,要按順序放置。

        b ResetHandler

        b HandlerUndef ;handler for Undefined mode

        b HandlerSWI ;handler for SWI interrupt

        b HandlerPabort ;handler for PAbort

        b HandlerDabort ;handler for DAbort

        b . ;reserved

        b HandlerIRQ ;handler for IRQ interrupt

        b HandlerFIQ ;handler for FIQ interrupt

        LTORG ;聲明一個數據緩沖池的開始

        HandlerFIQ HANDLER HandleFIQ

        HandlerIRQ HANDLER HandleIRQ

        HandlerUndef HANDLER HandleUndef

        HandlerSWI HANDLER HandleSWI

        HandlerDabort HANDLER HandleDabort

        HandlerPabort HANDLER HandlePabort

        ;采用INTOFFSET寄存器判定IRQ中斷源

        IsrIRQ

        sub sp,sp,#4

        stmfd sp!,{r8-r9}

        ldr r9,=INTOFFSET

        ldr r9,[r9]

        ldr r8,=HandleEINT0

        add r8,r8,r9,lsl #2

        ldr r8,[r8]

        str r8,[sp,#8]

        ldmfd sp!,{r8-r9,pc}

        ;======================================================

        ; ENTRY

        ;======================================================

        ;初始化程序入口指令

        ResetHandler

        ldr r0,=WTCON ;watch dog disable

        ldr r1,=0x0

        str r1,[r0]

        ldr r0,=INTMSK

        ldr r1,=0xffffffff ;all interrupt disable

        str r1,[r0]

        ldr r0,=INTSUBMSK

        ldr r1,=0x3ff ;all sub interrupt disable

        str r1,[r0]

        ;To reduce PLL lock time, adjust the LOCKTIME register.

        ldr r0,=LOCKTIME

        ldr r1,=0xffffff

        str r1,[r0]

        ;Configure MPLL

        ldr r0,=MPLLCON

        ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ;Fin=12MHz,Fout=50MHz

        str r1,[r0]

        ;設置存儲器控制寄存器。

        ;Set memory control registers

        adr r0, SMRDATA

        ldr r1,=BWSCON ;BWSCON Address

        add r2, r0, #52 ;End address of SMRDATA一共13個寄存器

        0

        ldr r3, [r0], #4

        str r3, [r1], #4

        cmp r2, r0

        bne %B0

        ;禁止Icache和Dcache,禁止MMU

        ;IMPORT MMU_DisableICache

        ;bl MMU_DisableICache ;

        ;IMPORT MMU_DisableDCache

        ;bl MMU_DisableDCache ;

        ;IMPORT MMU_InvalidateICache

        ;bl MMU_InvalidateICache ;

        ;IMPORT MMU_DisableMMU

        ;bl MMU_DisableMMU ;

        ;初始化堆棧

        ;Initialize stacks

        bl InitStacks

        ;建立IRQ中斷

        ; Setup IRQ handler

        ldr r0,=HandleIRQ ;This routine is needed

        ldr r1,=IsrIRQ ;if there isnt subs pc,lr,#4 at 0x18, 0x1c

        str r1,[r0]

        ;===========================================================

        adr r0, ResetEntry

        ldr r2, BaseOfROM

        cmp r0, r2

        ldreq r0, TopOfROM

        beq InitRam

        ldr r3, TopOfROM

        ;將RO區域的代碼copy到RW域中并且將ZI區域初始化為0。

        0

        ldmia r0!, {r4-r7}

        stmia r2!, {r4-r7}

        cmp r2, r3

        bcc %B0

        sub r2, r2, r3

        sub r0, r0, r2

        InitRam

        ldr r2, BaseOfBSS

        ldr r3, BaseOfZero

        0

        cmp r2, r3 ;copy 初始化代碼

        ldrcc r1, [r0], #4

        strcc r1, [r2], #4

        bcc %B0

        mov r0, #0 ;初始化ZI區域為0

        ldr r3, EndOfBSS

        1

        cmp r2, r3

        strcc r0, [r2], #4

        bcc %B1

        bl Main ;bl Main ;Dont use main() because ......

        b .

        ;堆棧初始化

        ;function initializing stacks

        InitStacks

        ;Dont 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

        ;UndefMode堆棧

        mrs r0,cpsr

        bic r0,r0,#MODEMASK

        orr r1,r0,#UNDEFMODE|NOINT

        msr cpsr_cxsf,r1 ;UndefMode

        ldr sp,=UndefStack

        ;AbortMode堆棧

        orr r1,r0,#ABORTMODE|NOINT

        msr cpsr_cxsf,r1 ;AbortMode

        ldr sp,=AbortStack

        ;IRQMode堆棧

        orr r1,r0,#IRQMODE|NOINT

        msr cpsr_cxsf,r1 ;IRQMode

        ldr sp,=IRQStack

        ;FIQMode堆棧

        orr r1,r0,#FIQMODE|NOINT

        msr cpsr_cxsf,r1 ;FIQMode

        ldr sp,=FIQStack

        ;SVCMode堆棧

        bic r0,r0,#MODEMASK|NOINT

        orr r1,r0,#SVCMODE

        msr cpsr_cxsf,r1 ;SVCMode

        ldr sp,=SVCStack

        ;USER mode has not be initialized.

        mov pc,lr

        ;The LR register wont be valid if the current mode is not SVC mode.

        LTORG ;聲明一個數據緩沖池的開始

        SMRDATA 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));BWSCON=0x2211D110

        DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;GCS0 BANK0CON=0x0700

        DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;GCS1 BANK1CON=0x7FFC

        DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;GCS2 BANKCON2=0x0700

        DCD 0x1f7c;((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ;GCS3 BANKCON3=0x0700

        DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ;GCS4 BANKCON4=0x0700

        DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ;GCS5 BANKCON5=0x0700

        DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6 BANKCON6=0x18005

        DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7 BANKCON7=0x18005

        DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) ;REFRESH=0x008E0459

        DCD 0x32 ;SCLK power saving mode, BANKSIZE 128M/128M ;BANKSIZE=0x32

        DCD 0x30 ;MRSR6 CL=3clk ;MRSRB6=0x30

        DCD 0x30 ;MRSR7 ;MRSRB7=0x30

        BaseOfROM DCD |Image$$RO$$Base|

        TopOfROM DCD |Image$$RO$$Limit|

        BaseOfBSS DCD |Image$$RW$$Base|

        BaseOfZero DCD |Image$$ZI$$Base|

        EndOfBSS DCD |Image$$ZI$$Limit|

        ALIGN ;通過添加補丁字節使當前位置滿足一定的對齊方式

        ;可讀寫的數據段

        AREA RamData, DATA, READWRITE

        ;^=MAP:定義一個結構化的內存表(storage map)的首地址,地址為0x33ff8000

        ^ _ISR_STARTADDRESS ;0x33ff8000

        HandleReset # 4 ;#--Field:定義一個結構化內存表中的數據域,該域為4個字節

        HandleUndef # 4

        HandleSWI # 4

        HandlePabort # 4

        HandleDabort # 4

        HandleReserved # 4

        HandleIRQ # 4

        HandleFIQ # 4

        ;Dont use the label IntVectorTable,

        ;The value of IntVectorTable is different with the address you think it may be.

        ;IntVectorTable

        HandleEINT0 # 4

        HandleEINT1 # 4

        HandleEINT2 # 4

        HandleEINT3 # 4

        HandleEINT4_7 # 4

        HandleEINT8_23 # 4

        HandleRSV6 # 4

        HandleBATFLT # 4

        HandleTICK # 4

        HandleWDT # 4

        HandleTIMER0 # 4

        HandleTIMER1 # 4

        HandleTIMER2 # 4

        HandleTIMER3 # 4

        HandleTIMER4 # 4

        HandleUART2 # 4

        HandleLCD # 4

        HandleDMA0 # 4

        HandleDMA1 # 4

        HandleDMA2 # 4

        HandleDMA3 # 4

        HandleMMC # 4

        HandleSPI0 # 4

        HandleUART1 # 4

        HandleRSV24 # 4

        HandleUSBD # 4

        HandleUSBH # 4

        HandleIIC # 4

        HandleUART0 # 4

        HandleSPI1 # 4

        HandleRTC # 4

        HandleADC # 4

        END



        關鍵詞: ARM啟動代

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 达孜县| 松潘县| 拜泉县| 达州市| 灵川县| 天津市| 自贡市| 呼和浩特市| 保定市| 连江县| 宁阳县| 丹巴县| 宜君县| 宁强县| 出国| 香港 | 大悟县| 吉安市| 博罗县| 西吉县| 从江县| 四川省| 汝阳县| 广丰县| 新龙县| 汝州市| 闵行区| 昔阳县| 开阳县| 南漳县| 沽源县| 会东县| 凌源市| 益阳市| 荃湾区| 海城市| 隆回县| 平武县| 波密县| 霍城县| 开化县|