對ARM7 LPC2210的Bootloader源碼分析

對周立功公司開發板EasyARM LPC2210開發板Chenmingji寫的Bootlaoder進行分析和解讀。

一、變(常)量聲明
    首先聲明堆棧大小
          ;define the stack size
    ;定義堆棧的大小
    SVC_STACK_LEGTH         EQU         0
    FIQ_STACK_LEGTH         EQU         0
    IRQ_STACK_LEGTH         EQU         256    ;IRQ中斷堆棧
    ABT_STACK_LEGTH         EQU         0
    UND_STACK_LEGTH         EQU         0
  處理器模式聲明
    NoInt       EQU 0x80

    USR32Mode   EQU 0x10
    SVC32Mode   EQU 0x13
    SYS32Mode   EQU 0x1f
    IRQ32Mode   EQU 0x12
    FIQ32Mode   EQU 0x11
  外部存儲器配置聲明
    PINSEL2     EQU 0xE002C014

    BCFG0       EQU 0xFFE00000
    BCFG1       EQU 0xFFE00004 
    BCFG2       EQU 0xFFE00008
    BCFG3       EQU 0xFFE0000C

    IMPORT __use_no_semihosting_swi
    IMPORT __use_two_region_memory

    ;The imported labels
;引入的外部標號在這聲明
    IMPORT  FIQ_Exception                   ;Fast interrupt exceptions handler 快速中斷異常處理程序
    IMPORT  __main                          ;The entry point to the main function C語言主程序入口
    IMPORT  TargetResetInit                 ;initialize the target board 目標板基本初始化

;The emported labels
;給外部使用的標號在這聲明
    EXPORT  bottom_of_heap                  ;heap的底部
    EXPORT  bottom_of_Stacks                ;stack的底部
    EXPORT  top_of_heap                     ;heap的頂部
    EXPORT  StackUsr                       
   
    EXPORT  Reset                           ;復位
    EXPORT __user_initial_stackheap         ;用戶初始化堆棧和堆

二、建立中斷向量表(向量表所有數據32位累加和爲0)
    Reset
        LDR     PC, ResetAddr               ;復位後開始的執行地址
        LDR     PC, UndefinedAddr           ;未定義指令異常          
        LDR     PC, SWI_Addr                ;軟件中斷
        LDR     PC, PrefetchAddr            ;預取中止
        LDR     PC, DataAbortAddr           ;預取數據中止
        DCD     0xb9205f80                  ;保留的異常
        LDR     PC, [PC, #-0xff0]           ;IRQ ( 該指令會讀取VICVectAddr寄存器的值,然後放入PC指針 )
        LDR     PC, FIQ_Addr                ;FIQ

    ;給每一個向量分配連續的字存儲單元
    ResetAddr           DCD     ResetInit
    UndefinedAddr       DCD     Undefined
    SWI_Addr            DCD     SoftwareInterrupt
    PrefetchAddr        DCD     PrefetchAbort
    DataAbortAddr       DCD     DataAbort
    Nouse               DCD     0
    IRQ_Addr            DCD     0
    FIQ_Addr            DCD     FIQ_Handler

    ;發生以下異常時程序暫停( 除了FIQ )
    ;未定義指令
    Undefined
            B       Undefined

    ;軟中斷
    SoftwareInterrupt   
            B       SoftwareInterrupt 

    ;取指令中止
    PrefetchAbort
            B       PrefetchAbort

    ;取數據中止
    DataAbort
            B       DataAbort

    ;快速中斷
    FIQ_Handler
            STMFD   SP!, {R0-R3, LR}            ;把R0-R3,LR的值存入堆棧
            BL      FIQ_Exception               ;跳轉到FIQ中斷程序
            LDMFD   SP!, {R0-R3, LR}            ;恢復R0-R3,LR的值
            SUBS    PC,  LR,  #4                ;PC指針跳轉到LR-4

三、復位程序
    根據外部存儲器控制器的引腳接法,對GPIO進行設置(外部存儲器所接引腳與P1,P2,P3口的GPIO功能複用),之後對用到的四組存儲器組進行設置.
    ResetInit
    ;Initial extenal bus controller.
    ;初始化外部總線控制器,根據目標板決定配置

            LDR     R0, =PINSEL2
        IF :DEF: EN_CRP
            LDR     R1, =0x0f814910
        ELSE
            LDR     R1, =0x0f814914
        ENDIF
            STR     R1, [R0]
    ;設置四組存儲器配置
            LDR     R0, =BCFG0
            LDR     R1, =0x1000ffef
            STR     R1, [R0]

            LDR     R0, =BCFG1
            LDR     R1, =0x1000ffef
            STR     R1, [R0]

    ;        LDR     R0, =BCFG2                 ;該開發板沒有用到後面兩組存儲器接口  
    ;        LDR     R1, =0x2000ffef
    ;        STR     R1, [R0]

    ;        LDR     R0, =BCFG3
    ;        LDR     R1, =0x2000ffef
    ;        STR     R1, [R0]

            BL      InitStack               ;初始化堆棧 Initialize the stack
            BL      TargetResetInit         ;目標板基本初始化 Initialize the target board
                                            ;跳轉到c語言入口 Jump to the entry point of C program
        B       __main

四、堆棧初始化
    初始化各模式堆棧

InitStack   
        MOV     R0, LR
;Build the SVC stack
;設置管理模式堆棧
        MSR     CPSR_c, #0xd3  
        LDR     SP, StackSvc
;Build the IRQ stack   
;設置中斷模式堆棧
        MSR     CPSR_c, #0xd2
        LDR     SP, StackIrq
;Build the FIQ stack
;設置快速中斷模式堆棧
        MSR     CPSR_c, #0xd1
        LDR     SP, StackFiq
;Build the DATAABORT stack
;設置中止模式堆棧
        MSR     CPSR_c, #0xd7
        LDR     SP, StackAbt
;Build the UDF stack
;設置未定義模式堆棧
        MSR     CPSR_c, #0xdb
        LDR     SP, StackUnd
;Build the SYS stack
;設置系統模式堆棧
        MSR     CPSR_c, #0xdf             ;修改爲0x5d將打開IRQ中斷
        LDR     SP, =StackUsr

        MOV     PC, R0                    ;子程序返回

五、目標板初始化
        void TargetResetInit(void)
{
// 設置存儲器映射方式,這必須根據硬件來設置. 這裏是ADS1.2中的設置.
#ifdef __DEBUG   
    MEMMAP = 0x3;                   //remap
#endif

#ifdef __OUT_CHIP   
    MEMMAP = 0x3;                   //remap
#endif

#ifdef __IN_CHIP   
    MEMMAP = 0x1;                   //remap
#endif

/* 設置系統各部分時鐘 */
    PLLCON = 1;
#if (Fpclk / (Fcclk / 4)) == 1
    VPBDIV = 0;
#endif
#if (Fpclk / (Fcclk / 4)) == 2
    VPBDIV = 2;
#endif
#if (Fpclk / (Fcclk / 4)) == 4
    VPBDIV = 1;
#endif

#if (Fcco / Fcclk) == 2
    PLLCFG = ((Fcclk / Fosc) - 1) | (0 << 5);
#endif
#if (Fcco / Fcclk) == 4
    PLLCFG = ((Fcclk / Fosc) - 1) | (1 << 5);
#endif
#if (Fcco / Fcclk) == 8
    PLLCFG = ((Fcclk / Fosc) - 1) | (2 << 5);
#endif
#if (Fcco / Fcclk) == 16
    PLLCFG = ((Fcclk / Fosc) - 1) | (3 << 5);
#endif
    PLLFEED = 0xaa;
    PLLFEED = 0x55;
    while((PLLSTAT & (1 << 10)) == 0);
    PLLCON = 3;                                // 按照特定的設置方式對PLL控制寄存器進行設置
    PLLFEED = 0xaa;
    PLLFEED = 0x55;
   
    /* 設置存儲器加速模塊 */
    MAMCR = 0;
#if Fcclk < 20000000
    MAMTIM = 1;
#else
#if Fcclk < 40000000
    MAMTIM = 2;
#else
    MAMTIM = 3;
#endif
#endif
    MAMCR = 2;
   
    /* 初始化VIC */
    /* initialize VIC*/
    VICIntEnClr = 0xffffffff;
    VICVectAddr = 0;
    VICIntSelect = 0;

}

六、其它

;/*********************************************************************************************************
;** unction name  函數名稱:  __user_initial_stackheap
;** Descriptions  功能描述:  Initial the function library stacks and heaps, can not deleted!  
;**                                     庫函數初始化堆和棧,不能刪除
;** input parameters  輸 入:    reference by function library 參考庫函數手冊
;** Returned value    輸 出 :   reference by function library 參考庫函數手冊
;** Used global variables 全局變量:  None 無
;** Calling modules  調用模塊:  None 無
;********************************************************************************************************/
__user_initial_stackheap   
    LDR   r0,=bottom_of_heap
;    LDR   r1,=StackUsr
    LDR   r2,=top_of_heap
    LDR   r3,=bottom_of_Stacks
    MOV   pc,lr


StackSvc           DCD     SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4
StackIrq           DCD     IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
StackFiq           DCD     FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4
StackAbt           DCD     AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4
StackUnd           DCD     UndtStackSpace + (UND_STACK_LEGTH - 1)* 4

;/*********************************************************************************************************
;** unction name  函數名稱:  CrpData
;** Descriptions  功能描述:  encrypt the chip
;** input parameters  輸 入:    None 無
;** Returned value    輸 出 :   None 無
;** Used global variables 全局變量:  None 無
;** Calling modules  調用模塊:  None 無
;********************************************************************************************************/
    IF :DEF: EN_CRP
        IF  . >= 0x1fc
        INFO    1,"/nThe data at 0x000001fc must be 0x87654321./nPlease delete some source before this line."
        ENDIF
CrpData
    WHILE . < 0x1fc
    NOP
    WEND
CrpData1
    DCD     0x87654321          ;/*When the Data is 爲0x87654321,user code be protected. 當此數爲0x87654321時,用戶程序被保護 */
    ENDIF
   
;/* 分配堆棧空間 */
        AREA    MyStacks, DATA, NOINIT, ALIGN=2
SvcStackSpace      SPACE   SVC_STACK_LEGTH * 4  ;Stack spaces for Administration Mode 管理模式堆棧空間
IrqStackSpace      SPACE   IRQ_STACK_LEGTH * 4  ;Stack spaces for Interrupt ReQuest Mode 中斷模式堆棧空間
FiqStackSpace      SPACE   FIQ_STACK_LEGTH * 4  ;Stack spaces for Fast Interrupt reQuest Mode 快速中斷模式堆棧空間
AbtStackSpace      SPACE   ABT_STACK_LEGTH * 4  ;Stack spaces for Suspend Mode 中止義模式堆棧空間
UndtStackSpace     SPACE   UND_STACK_LEGTH * 4  ;Stack spaces for Undefined Mode 未定義模式堆棧


        AREA    Heap, DATA, NOINIT
bottom_of_heap      SPACE   1

        AREA    StackBottom, DATA, NOINIT
bottom_of_Stacks    SPACE   1

        AREA    HeapTop, DATA, NOINIT
top_of_heap

        AREA    Stacks, DATA, NOINIT
StackUsr

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章