mcu 执行代码流程

2021-09-23  本文已影响0人  wjundong
LR_IROM1 0x08000000 0x00080000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00080000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x20000000 0x00010000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

LR_IROM1 == Load region Internal ROM 1,表示第一个内部 ROM 加载域。
ER_IROM1 == Execution region Internal ROM 1, 表示第一个内部 ROM 运行域。

可以看到, (RESET, +First) 指定了Flash 加载顺序将以 RESET 区域开始
最简单的程序:


    AREA    RESET, DATA, READONLY
        DCD 0x1234
        DCD Reset_Handler
    
    AREA    |.text|, CODE, READONLY
        
Reset_Handler   PROC 
                MOV R0,#0x666
                B   .
                ENDP
                    
    END

该程序首先声明一个只读的 DATA 区,DATA 区定义两个32位数据, 然后声明一个代码区, 里面定义一个子函数Reset_Handler;

因为复位后CPU会从 Flash 起始地址的第二个32位取数据, 因此将通过 DCD Reset_Handler 将 Reset_Handler 地址写到该区域让cpu复位后立刻转跳到 Reset_Handler 以执行复位代码。

下面是官方提供的启动文件:


;*******************************************************************************
; 申明堆区
;*******************************************************************************
Heap_Size       EQU     0x00000200
                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit


;*******************************************************************************
; 申明栈区
;*******************************************************************************
Stack_Size      EQU     0x00000500

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

                PRESERVE8
                THUMB

;*******************************************************************************
; 向量表区
;*******************************************************************************
                AREA    RESET, DATA, READONLY
                DCD __initial_sp
                DCD Reset_Handler
                ; ... 此处省略许多中断入口

;*******************************************************************************
; 代码区
;*******************************************************************************
                AREA    |.text|, CODE, READONLY
        
Reset_Handler   PROC 
                MOV R0,#0x666
                PUSH {R0}
                POP {R1}
                B .
                ENDP
                    

;*******************************************************************************
; 用户堆栈初始化
;*******************************************************************************
                 IF      :DEF:__MICROLIB    ; 如果使用 MicroLib 则只需导出堆栈的关键变量
                
                 EXPORT  __initial_sp
                 EXPORT  __heap_base
                 EXPORT  __heap_limit
                
                 ELSE                       ; 否则需要导出 __user_initial_stackheap 子函数用于初始化堆栈
                
                 IMPORT  __use_two_region_memory
                 EXPORT  __user_initial_stackheap
                 
__user_initial_stackheap

                 LDR     R0, =  Heap_Mem
                 LDR     R1, =(Stack_Mem + Stack_Size)
                 LDR     R2, = (Heap_Mem +  Heap_Size)
                 LDR     R3, = Stack_Mem
                 BX      LR

                 ALIGN

                 ENDIF

                 END


上一篇下一篇

猜你喜欢

热点阅读