备注:基于正点原子阿波罗STM32F767IGT6开发板,RT-Thread Studio开发环境
目录
1、入口函数的确认
编译工具链为arm-none-eabi,根据链接文件link.lds中的关键字ENTRY可以确认程序的入口地址是Reset_Handler。
/*
* linker script for STM32F767IG with GNU ld
*/
/* Program Entry, set to mark it as "used" and avoid gc */
MEMORY
{
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 1024k /* 1024K flash */
RAM (rw) : ORIGIN = 0x20020000, LENGTH = 384k /* 384K sram */
}
ENTRY(Reset_Handler)
_system_stack_size = 0x400;
2、函数执行流程
一图流,如图2.2.1
图2.2.1
3、关键函数功能详解
函数功能讲解增加到了代码注释中。
3.1 Reset_Handler
主板上电复位后从Reset_Handler开始执行,在进入SystemInit函数前,主要做了如下事情:
3.1.1 设置SP栈指针;
3.1.2 data段数据从flash搬运到SRAM;
3.1.3 bss段清零,然后跳转至SystemInit; 注意:地址相关信息均由link.lds链接文件在编译时确定。
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
ldr sp, =_estack /* set stack pointer initialize, the '_estack' definition in the link file*/
/**
* Data segment: Data stored at compile time (not at runtime) that can be read and written.
* This is also known as static storage,
* where initialized global variables and initialized static variables are stored,
* and where constants are stored
*/
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0 /* save 0 to R1 */
b LoopCopyDataInit
CopyDataInit: /* .data data copy */
ldr r3, =_sidata /* R3 = The .data is at the starting address of Flash */
ldr r3, [r3, r1] /* load the value of the [R3 + R1] address into R3 */
str r3, [r0, r1] /* save the value of R3 to the address of [R0 + R1] */
adds r1, r1, #4 /* R1 = R1 + 4 */
LoopCopyDataInit:
ldr r0, =_sdata /* assign the .data start address into R0 */
ldr r3, =_edata /* assign the .data end address into R3 */
adds r2, r0, r1 /* r2 = r0 + r1, */
cmp r2, r3 /* compare R2 and R3 value */
bcc CopyDataInit /* if R2 and R3 value not equality, jump */
ldr r2, =_sbss /* load the .bss satrt address into R2 */
b LoopFillZerobss /* jump to LoopFillZerobss */
/**
* BSS section:
* Global and static variables defined without initial values are placed in this section
*/
/* Zero fill the bss segment. */
FillZerobss:
movs r3, #0 /* save 0 to R3 */
str r3, [r2], #4 /* save the value of R3 to the address of [R