美文网首页
mcu 执行代码流程

mcu 执行代码流程

作者: wjundong | 来源:发表于2021-09-23 00:44 被阅读0次
    • 为了弄清楚mcu的代码执行流程,我们应当从复位后执行的第一条代码开始解析。这里以STM32F103VE为例。无论是哪款芯片,最应该先了解的是内存分布,去官网查看可以得到STM32F103VE具有512 KB Flash,64 KB SRAM。然后查看其这些存储器被映射到地址空间的什么地方。在目录中很容易找到 Memory mapping 一章,知道了 512KB 的Flash被映射到 0x0800 0000-0x0807 FFFF的地址空间, 64KB SRAM 的地址空间为0x2000 0000-0x2000 FFFF。

    • Flash 是用来保存用户代码的,SRAM是用来存储运行的变量和开始堆栈的,CPU复位后必然会去Flash 加载用户的代码,那么复位后是从哪个地方开始加载呢?根据MDK自动生成的分散加载文件:

    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
    
    
    

    相关文章

      网友评论

          本文标题:mcu 执行代码流程

          本文链接:https://www.haomeiwen.com/subject/wmdngltx.html