keil RealViewMDK STM32F10x.s启动流程分析

先说说RealViewMDK build project的连接选项,点击小魔棒,切到Linker,可知armlink的选项:
-device DARMSTM *.o --strict --scatter "TEST.sct" --autoat --summary_stderr --info summarysizes --map --xref --callgraph --symbols --info sizes --info totals --info unused --info veneers --list ".\TEST.map" -o "TEST.axf"
--map --xref --callgraph --symbols会生成object文件的信息到--list ".\TEST.map中。TEST.axf是生成的ELF文件。对它执行
fromelf -c TEST.axf > disasm.txt
进行反汇编并保存结果到disasm.txt。至此。我们得到TEST.map和disasm.txt,再加上STM32F10x.s TEST.sct,开始我的分析。
scatter文件包含以下几行:

LR_IROM1 0x08000000 0x00020000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00005000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

TEST.axf的image结构也截出来

Memory Map of the image
  Image Entry point : 0x080000ed
  Load Region LR_IROM1 (Base: 0x08000000, Size: 0x00000dac, Max: 0x00020000, ABSOLUTE)
    Execution Region ER_IROM1 (Base: 0x08000000, Size: 0x00000d9c, Max: 0x00020000, ABSOLUTE)
    Base Addr    Size         Type   Attr      Idx    E Section Name        Object
    0x08000000   0x000000ec   Data   RO            3    RESET               stm32f10x.o
    0x080000ec   0x00000000   Code   RO          136  * .ARM.Collect$$$$00000000  entry.o(mc_w.l)
    0x080000ec   0x00000004   Code   RO          412    .ARM.Collect$$$$00000001  entry2.o(mc_w.l)
    0x080000f0   0x00000004   Code   RO          415    .ARM.Collect$$$$00000004  entry5.o(mc_w.l)
    0x080000f4   0x00000008   Code   RO          416    .ARM.Collect$$$$00000007  entry7.o(mc_w.l)
    0x080000fc   0x00000004   Code   RO          413    .ARM.Collect$$$$00002712  entry2.o(mc_w.l)

可见程序上电后,从RESET这个section开始执行。它在STM32F10x.s中,
               AREA    RESET, DATA, READONLY
                EXPORT  __Vectors
__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler

主要定义了一个Vectors table,最开始部分初始化主堆栈指针MSP,
Stack_Size      EQU     0x00000200
                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

之后执行Reset_Handler,
Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  __main
                LDR     R0, =__main
                BX      R0
                ENDP
可见是跳转到__main,通过TEST.map中的symbols信息,很容易找到其位置
Image Symbol Table
 Local Symbols
 Symbol Name Value Ov Type Size Object(Section)
 ... 
Global Symbols
 Symbol Name Value Ov Type Size Object(Section)...
 __main 0x080000ed Thumb Code 0 entry.o(.ARM.Collect$$$$00000000)

再结合Memory Map of the image的信息,一切都对的上了。不多说,单刀直入,由disasm.txt中的汇编看流程:
    .ARM.Collect$$$$00000000
    .ARM.Collect$$$$00000001
    __main
    _main_stk
        0x080000ec:    f8dfd00c    ....    LDR      sp,__lit__00000000 ; [0x80000fc] = 
    .ARM.Collect$$$$00000004
    _main_scatterload
        0x080000f0:    f000fd36    ..6.    BL       __scatterload ; 0x8000b60
    __lit__00000000
        0x080000fc:    20000310    ...     DCD    536871696
接着跳转到__scatterload,
    __scatterload
    __scatterload_rt2
        0x08000b60:    4c06        .L      LDR      r4,[pc,#24] ; [0x8000b7c] = 0x8000d7c
        0x08000b62:    4d07        .M      LDR      r5,[pc,#28] ; [0x8000b80] = 0x8000d9c
        0x08000b64:    e006        ..      B        0x8000b74 ; __scatterload + 20
        0x08000b66:    68e0        .h      LDR      r0,[r4,#0xc]
        0x08000b68:    f0400301    @...    ORR      r3,r0,#1
        0x08000b6c:    e8940007    ....    LDM      r4,{r0-r2}
        0x08000b70:    4798        .G      BLX      r3
        0x08000b72:    3410        .4      ADDS     r4,r4,#0x10
        0x08000b74:    42ac        .B      CMP      r4,r5
        0x08000b76:    d3f6        ..      BCC      0x8000b66 ; __scatterload + 6
        0x08000b78:    f7fffabc    ....    BL       __main_after_scatterload ; 0x80000f4
        0x08000b7c:    08000d7c    |...    DCD    134221180
        0x08000b80:    08000d9c    ....    DCD    134221212
    Region$$Table$$Base
        0x08000d7c:    08000d9c    ....    DCD    134221212
        0x08000d80:    20000000    ...     DCD    536870912
        0x08000d84:    00000010    ....    DCD    16
        0x08000d88:    08000ba4    ....    DCD    134220708
        0x08000d8c:    08000dac    ....    DCD    134221228
        0x08000d90:    20000010    ...     DCD    536870928
        0x08000d94:    00000300    ....    DCD    768
        0x08000d98:    08000bb4    ....    DCD    134220724
    Region$$Table$$Limit
分析:
1. 加载[0x8000b7c] = 0x8000d7c到r4 
2. 加载[0x8000b80] = 0x8000d9c到r5 
3. 跳转到0x8000b74 
4. 比较r4和r5,运算r4-r5 
5. 若借位(carry clear),跳转到0x8000b66。否则继续往下执行 
6. 0x08000b66处,加载RW输出域的地址到r0=08000ba4 
7. 设置r0的最低bit,将结果保存到r3 
8. 加载[0x08000d7c]3个32bits数据到r0-r2,作为参数传递给子程序 
9. 跳转到r3 
10.接下来,
    i.__scatterload_copy
    __scatterload_copy
        0x08000ba4:    e002        ..      B        0x8000bac ; __scatterload_copy + 8
        0x08000ba6:    c808        ..      LDM      r0!,{r3}
        0x08000ba8:    1f12        ..      SUBS     r2,r2,#4
        0x08000baa:    c108        ..      STM      r1!,{r3}
        0x08000bac:    2a00        .*      CMP      r2,#0
        0x08000bae:    d1fa        ..      BNE      0x8000ba6 ; __scatterload_copy + 2
        0x08000bb0:    4770        pG      BX       lr
实现的是拷贝r0指向的域到r1指向的域,共r2个字。此处RW共16个字。
11. 接下来又是一个循环针对,
    i.__scatterload_zeroinit
    __scatterload_zeroinit
        0x08000bb4:    2000        .       MOVS     r0,#0
        0x08000bb6:    e001        ..      B        0x8000bbc ; __scatterload_zeroinit + 8
        0x08000bb8:    c101        ..      STM      r1!,{r0}
        0x08000bba:    1f12        ..      SUBS     r2,r2,#4
        0x08000bbc:    2a00        .*      CMP      r2,#0
        0x08000bbe:    d1fb        ..      BNE      0x8000bb8 ; __scatterload_zeroinit + 4
        0x08000bc0:    4770        pG      BX       lr此处拷贝ZI数据,共16#16*3 = 768 = r2个字。
12. 跳转到__main_after_scatterload,
   __main_after_scatterload
    _main_init
        0x080000f4:    4800        .H      LDR      r0,[pc,#0] ; [0x80000f8] = 0x8000121
        0x080000f6:    4700        .G      BX       r0
    $d
        0x080000f8:    08000121    !...    DCD    134218017
可见它又向08000121处跳转
13. 接着向main函数跳转,进入主函数执行
   .text
    main
        0x08000120:    b570        p.      PUSH     {r4-r6,lr}
        0x08000122:    2600        .&      MOVS     r6,#0
        0x08000124:    2009        .       MOVS     r0,#9
        0x08000126:    f000fa27    ..'.    BL       Stm32_Clock_Init ; 0x8000578
因为在编译时给armcc指定-D:__MICROLIB,所以__user_initial_stackheap并没有定义。所以下文叙述的内容不适用于这种情况
http://blog.csdn.net/wangfoquan/article/details/7650988">http://blog.csdn.net/wangfoquan/article/details/7650988 
对应STM32F10x.s如下语句
 IF      :DEF:__MICROLIB
                
                EXPORT  __initial_sp
                EXPORT  __heap_base
                EXPORT  __heap_limit
                
                ELSE
                
                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
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Version: 2.15.0 (2020-09-28) Keil.STM32F4xx_DFP.2.15.0.pack Download Updated Pack to STM32Cube_FW_F4 Firmware Package version V1.25.1 using HAL Drivers V1.7.9. STM32CubeMX integration (Version 6.0.1): Added support for Timebase Source TIMx (FrameworkCubeMX_gpdsc.ftl). Removed non-existent include path. CMSIS Flash Algorithm: Corrected STM32F42xxx_43xxx_OPT Algorithm. CMSIS SVD: Updated STM32F42*.svd, STM32F43*.svd files. CMSIS-Driver: I2C: Corrected 2 byte reception in master mode. MCI: Replaced empty delay loops with _NOP(). SPI: Corrected PowerControl function (to return error if Initialize was not called, to abort active transfer if power off was requested). Updated GetDataCount function to give accurate count in DMA mode. Corrected Control function (abort in DMA mode, software controlled slave select in slave mode, TI Frame Format selection, ignore bus speed for slave mode). Corrected Uninitialize function (to power off the peripheral if it is powered). Corrected SPI3_SCK pin configuration. Corrected DMA MemDataAlignment configuration. USART: Corrected DMA MemDataAlignment configuration. USBD_HS/USBH_HS: OTG_HS ULPI clock disabled in low power if internal PHY is used to enable proper operation of OTG_HS port in FS mode during CPU sleep. CAN/EMAC/USBD/USBH: Removed macros already provided by cmsis_compiler.h. Updated Boards Examples: Migrated CubeMX projects to V6.0.1 and updated config files. Changed variant selection to "MDK-Plus" where possible. Updated all USB Host/Device examples with user templates from MDK-Middleware v7.11.1. Terminating app_main thread with osThreadExit() to avoid endless loop Updated MS Windows UBS driver files.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值