STM32启动过程详解

STM32启动过程详解


初始化栈顶指针sp

将0x08000000 - 0x08000003中的值赋值给sp,由硬件自动完成。

执行复位程序Reset_Handler

Reset_Handler中先调用SystemInit进行系统初始化,然后调用__main函数。在__main函数中会初始化RW和ZI段,最后跳转到main函数。

; Reset handler
Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  __main
                IMPORT  SystemInit
                LDR     R0, =SystemInit
                BLX     R0               
                LDR     R0, =__main
                BX      R0
                ENDP

在这里插入图片描述

初始化RW、ZI段

在生成的map文件中有两个符号Region $ $Table $ $Base,Region $ $Table $ $ Limit。这两个符号会在初始化RW和ZI的库函数中使用。
在这里插入图片描述

map文件:

Global Symbols

    Symbol Name                              Value     Ov Type        Size  Object(Section)
    ...                                  ...          ...           ...   ...
Region$$Table$$Base                      0x080008dc   Number         0  anon$$obj.o(Region$$Table)
Region$$Table$$Limit                     0x080008fc   Number         0  anon$$obj.o(Region$$Table)
    ...                                  ...          ...           ...   ...

bin文件:

00000820h: 0C 94 0D 94 00 21 0A A8 0E 94 FF F7 53 FD 10 B0 ;
00000830h: 10 BD 00 00 0D 48 01 68 41 F0 01 01 01 60 41 68 ;
00000840h: 0B 4A 11 40 41 60 01 68 0A 4A 11 40 01 60 01 68 ;
00000850h: 21 F4 80 21 01 60 41 68 21 F4 FE 01 41 60 4F F4 ;
00000860h: 1F 01 81 60 04 49 C0 03 08 60 70 47 00 10 02 40 ;
00000870h: 00 00 FF F8 FF FF F6 FE 08 ED 00 E0 FE E7 09 07 ;
00000880h: 09 0E 00 28 04 DB 00 F1 E0 20 80 F8 00 14 70 47 ;
00000890h: 00 F0 0F 00 00 F1 E0 20 80 F8 14 1D 70 47 02 E0 ;
000008a0h: 08 C8 12 1F 08 C1 00 2A FA D1 70 47 70 47 00 20 ;
000008b0h: 01 E0 01 C1 12 1F 00 2A FB D1 70 47 FF F7 88 FC ;
000008c0h: FF F7 96 FF FF F7 78 FF FE E7 00 00 00 00 00 00 ;
000008d0h: 00 00 01 02 03 04 06 07 08 09 00 00 FC 08 00 08 ;
000008e0h: 00 00 00 20 10 00 00 00 9E 08 00 08 0C 09 00 08 ;
000008f0h: 10 00 00 20 00 04 00 00 AE 08 00 08 01 00 00 00 ;
00000900h: 10 00 00 00 00 00 00 00 00 24 F4 00 ; …$?

Region$$ Table $ $ Base对应表的起始地址,Region $ $ Table $ $ Limit对应终止地址,链接的时候确定这两个值。由于bin文件起始地址是0,所以地址0x080008dc对应0x8dc。表内容:

内容
rw数据在flash中的起始地址080008FC
rw数据在ram中的起始地址20000000
rw数据长度(byte)00000010
拷贝函数起始地址0800089E
rw数据在flash中的终止地址0800090C
ZI段在ram中的起始地址20000010
ZI段长度,包含heap(byte)00000400
ZI段初始化函数起始地址080008AE

初始化RW数据:
在这里插入图片描述
初始化ZI和heap数据:
在这里插入图片描述

__rt_entry

调用以下函数

__user_initial_stackheap()

startup_stm32xxx.s文件中

__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
__rt_stackheap_init()
__rt_lib_init()

rt_misc.h

/*
 * This is the library init function itself, provided just in case
 * a user needs to call it directly. It is called just after
 * __rt_stackheap_init(), and passed an initial chunk of memory to
 * use as a heap. It returns argc and argv ready to be passed to
 * main(). (The __argc_argv structure contains four words rather
 * than just two, in case you need to pass anything else to main()
 * such as the Unix envp.  For AArch64 struct __argc_argv is 8 words
 * (4 registers) and explicit padding is used to ensure argc is in w0.)
 */
struct __argc_argv {
#if (defined(__ARM_64BIT_STATE) || defined(__TARGET_ARCH_AARCH64)) && \
    (defined(__ARM_BIG_ENDIAN) || defined(__BIG_ENDIAN))
    int padding;
#endif
    int argc;
#if (defined(__ARM_64BIT_STATE) || defined(__TARGET_ARCH_AARCH64)) && \
    !(defined(__ARM_BIG_ENDIAN) || defined(__BIG_ENDIAN))
    int padding;
#endif
    char **argv;
    void *r2;
    void *r3;
};
extern __value_in_regs struct __argc_argv
__rt_lib_init(unsigned /*heapbase*/, unsigned /*heaptop*/);
main()

用户主函数

exit()

_regs struct __argc_argv
__rt_lib_init(unsigned /heapbase/, unsigned /heaptop/);




#### main()

用户主函数

#### exit()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值