4.HAL库启动流程

1.启动文件startup_stm32f429xx.s

启动文件主要工作:
1、初始化堆栈指针 SP=_initial_sp
2、初始化 PC指针=Reset_Handler
3、初始化中断向量表
4、配置系统时钟
5、调用 C库函数_main 初始化用户堆栈,从而最终调用main 函数去C的世界

1.1.Stack-栈

Stack_Size      EQU     0x400;

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

开辟栈的大小为0X00000400(1KB),名字为STACK,8(2^3)字节对齐。栈的作用是用于局部变量,函数调用,函数形参等的开销。标号__initial_sp紧挨着SPACE语句放置,表示栈的结束地址,即栈顶地址,栈是由高向低生长的。

1.2.Heap-堆

Heap_Size      EQU     0x200;

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

开辟堆的大小为0X00000200(512字节),名字为HEAP,NOINIT,8(2^3)字节对齐。__heap_base表示对的起始地址,__heap_limit表示堆的结束地址。堆是由低向高生长的,跟栈的生长方向相反。堆主要用来动态内存的分配,malloc()函数申请的内存就在堆上面。

1.3.向量表

; Vector Table Mapped to Address 0 at Reset
                AREA    RESET, DATA, READONLY
                EXPORT  __Vectors
                EXPORT  __Vectors_End
                EXPORT  __Vectors_Size

定义一个数据段,名字为 RESET,可读。并声明 __Vectors、__Vectors_End 和
__Vectors_Size这三个标号具有全局属性,可供外部的文件调用。
__Vectors为向量表起始地址, __Vectors_End 为向量表结束地址,两个相减即可算出向量表大小。向量表从FLASH的0地址开始放置,以4字节为一个单位,地址0存放的是栈顶地址,0X04存放的是复位程序的地址,以此类推。

1.4.复位程序

Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main

                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

复位子程序是系统上电后第一个执行的程序,调用SystemInit 函数初始化系统时钟,然后调用 C库函数_mian。
SystemInit和__main这两个函数均来自外部的文件。SystemInit()在system_STM32F4xx.c库文件定义。主要作用是配置系统时钟,这里调用这个函数之后,F429的系统时钟配被配置为16M(时钟源HSI)。__main 是一个标准的C库函数,主要作用是初始化用户堆栈,最终调用main函数去到C的世界。

1.5.中断服务程序

在启动文件里面已经帮我们写好所有中断的中断服务函数,这些函数都是空的,真正的中断复服务程序需要在外部的C文件里重新实现,这里只是提前占了一个位置而已。

;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************
                 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
                 END

判断是否定义了__MICROLIB ,如果定义了则赋予标号__initial_sp(栈顶地址)、__heap_base(堆起始地址)、__heap_limit(堆结束地址)全局属性,可供外部文件调用。如果没有定义(实际的情况就是我们没定义__MICROLIB)则使用默认的C库,然后初始化用户堆栈大小,这部分有C库函数__main 来完成,当初始化完堆栈之后就调用main函数。

2.启动模式设置接口

在这里插入图片描述
在这里插入图片描述
一般如果想用用串口下载代码,则必须配置BOOT0为 1,BOOT1为0,而如果想让STM32一按复位键就开始跑代码,则需要配置 BOOT0为0,BOOT1随便设置都可以。

3.启动流程

在这里插入图片描述

  1. 上电后执行启动文件startup_stm32f429xx.s,初始化堆栈指针,PC指针,中断向量表,调用 C库函数_main。
  2. 调用HAL_Init()初始化HAL库,此时默认配置为16M的HIS时钟源;HAL_Init()里设置Systick的中断优先级,初始化Systick(1ms一次中断)。
  3. 调用自己的时钟初始化函数和延时初始化函数。
发布了4 篇原创文章 · 获赞 12 · 访问量 1301

猜你喜欢

转载自blog.csdn.net/weixin_41898804/article/details/105246793