深入分析STM32启动流程及底层控制原理

阅读引言: 阅读本文之后, 你将对单片机, 甚至是嵌入式系统, 或者是传统的PC机系统的启动流程有一个大致的了解, 本文更加偏向于单片机的启动流程分析。

目录

一、基础知识

1.STM32系列的微控制器(mcu)使用的计算机体系结构

2.嵌入式系统的存储器

3.CPU是如何控制外设的

二、点亮LED的几种办法

1.使用汇编指令读写指定的地址

2.使用C语言读写指定的地址​​​​​​​

3.其它方法

三、STM32的启动流程

1.引导加载程序(Boot Loard)

2.STM32G431RBT6的启动流程分析

3.stm32启动代码详解



一、基础知识


1.STM32系列的微控制器(mcu)使用的计算机体系结构

        STM32微控制器使用的是哈佛结构。哈佛结构是指指令存储器和数据存储器分开的计算机存储器结构。在STM32微控制器中,指令存储器通常是闪存,而数据存储器通常是SRAM。这种结构可以提高系统的运行效率,并且可以同时访问指令和数据,提高系统的响应速度。

2.嵌入式系统的存储器

        存储装置是计算机不可或缺的组件,用于存储程序代码和数据,它赋予计算机记忆功能。存储装置通常分为主存和外部存储器。主存是电路板上的半导体存储器,而外部存储器包括硬盘、光盘、U盘、闪存卡等。 嵌入式系统的存储器系统与通用计算机系统的设计方法有所不同,嵌入式微处理器芯片上集成了一定数量的存储器,成为构成嵌入式系统硬件的主要组成部分。 存储器性能的一些指标包括易失性、只读性、位容量、速度、功耗、可靠性和价格等因素。嵌入式存储器根据掉电信息的保留情况分为ROM和RAM两类, 大致画了一个思维导图, 总结了一下。

引出这些的目的就是需要知道stm32的程序, 也就是指令是存放在flash中的, 而程序在运行期间的数据是存放在SRAM中的, 关于ROM和RAM大家可以把ROM想象成电脑的硬盘, RAM比喻成内存, 运行程序的地方。

3.CPU是如何控制外设的

  • CPU的组成
  • CPU由以下几部分组成:

    1. 控制单元(Control Unit):负责指令的解码和执行,协调各个部件的工作,控制数据的流动。

    2. 运算单元(Arithmetic Logic Unit,ALU):负责执行算术和逻辑运算,例如加法、减法、乘法、与、或等操作。

    3. 寄存器(Register):用来存放指令、数据和中间结果,包括程序计数器(Program Counter),指令寄存器(Instruction Register),累加器(Accumulator)等。

    4. 时钟(Clock):用来同步各个部件的工作,控制指令和数据的传输和处理速度。

    5. 数据总线(Data Bus):用于传输数据,连接CPU和其他设备或存储器。

    6. 地址总线(Address Bus):用于传输地址信号,指示数据在存储器中的位置。

    7. 控制总线(Control Bus):用于传输控制信号,控制各个部件的工作。

    以上是CPU的主要组成部分,它们协同工作,使得计算机能够执行各种指令和处理数据。

    其实在嵌入式系统中我们熟知的ARM只是为cpu的架构设计提供方案的公司, 或说是一种技术,准确来说我们见到的ST公司生产的芯片都是基于ARM的内核, 然后自己添加了一些硬件控制器在一块芯片里面, 专业术语叫做SOC。

            好了, 言归正传, 只是铺垫得差不多了, 该说说cpu是如何控制外设的了, 比如, cpu控制LED灯的亮灭。这里得提到一个知识点, 指令。

            什么是指令, 其定义是CPU能够识别并执行的机器码, 也就是一些0101的二进制数据, 我们写的代码, 给到交叉编译器编译之后得到的.hex或者.bin文件本质就是机器码, 现在知道为什么cpu能够执行我们写的程序了把, 是编译器的功能, 选择和cpu适配的编译器, 编译出的指令cpu就能识别并执行。、

            cpu执行指令一般分为三个步骤、取值、译码、执行。这些都是由抓门的cpu指令的, 比如通过该cpu的取指的指令给到cpu执行,cpu通过地址总线去内存的指定位置取出指令给到cpu内部的硬件电路去执行。

            编不下去, 直接给大伙看两个汇编指令, LDR, STR, 一个是cpu去指定的地址加载数据到cpu内部, 一个是cpu往指定的地址写数据, 那么, cpu控制LED灯点亮, 大家是不是已经想到答案了, cpu之所以能够控制硬件, 就是其能够通过总线去读写存储器的指定位置。


    二、点亮LED的几种办法


    1.使用汇编指令读写指定的地址

    去芯片厂家提供的地址映射表可以查到对用外设的地址, LTR, STR, MOV,这些指令往控制LED的寄存器的指定的那一个位写值, 即可控制LED

    
    
    LDR R1, [R2]
    STR R1, [R2]

    2.使用C语言读写指定的地址

    假设你知道了控制LED的gpio的数据寄存器的地址, 哪就可以这样干。

    #define LED_DATA (0X48000000)
    
    void led_on(void)
    {
        *(volatile unsigned int *)0x4800000 = *(volatile unsigned int *)0x4800000 | 1 << i
    }
     * 二.C语言访问存储器
     * 	1.读存储器
     * 		data = *ADDR
     * 	2.写存储器
     * 	 	*ADDR = data
     */
    

    3.其它方法

    各个芯片厂家提供的SDK, 其本质就是我上面说的那个, 将地址转换位C语言中的指针, 封装成宏, 结构体等等, 提供接口, 提升开发效率。


    三、STM32的启动流程


    1.引导加载程序(Boot Loard)

            是芯片厂家固化在IROM(内部存储器)的一段代码, 可以和windows中的BIOS对比学, 作用是引导cpu执行程序的, 初始化软硬件, 接着该段程序会去读boot引脚的电平状态, 确定程序的入口地址在哪

    2.STM32G431RBT6的启动流程分析

            上面我们说, cpu之说一能控制硬件, 是因为其有读写存储器的能力, stm32是一个32位的单片机, 那是不是其能够寻址的范围就是0-4G, 这些空间内的存储器都是cpu能够访问到的,芯片厂家会对ARM架构的cpu给出的地址映射范围加上自己的外设。所谓的存储器映射其实就是给存储器分配地址的过程。

    图解:

    跳到flash之后, 开头的前两条指令一般都是固定的, 第一条指令, 赋值cpu内部MSP寄存器的值, 指定主栈的地址, 第二条指令是Reset_Handler这个函数的入口地址, 将这个函数的地址值给CPU内部的PC寄存器, 这样cpu就会去Reset_Handler函数对用的地址空间内取指执行了。

    3.stm32启动代码详解

    给大家写写注释!

    ;*******************************************************************************
    ;* @File Name          : startup_stm32g431xx.s
    ;* @Author             : MCD Application Team
    ;* @Brief              : Vector table for MDK-ARM toolchain
    ;*******************************************************************************
    ;* Description        : STM32G431xx Mainstream devices vector table for
    ;*                      MDK-ARM toolchain.
    ;*                      This module performs:
    ;*                      - Set the initial SP
    ;*                      - Set the initial PC == Reset_Handler
    ;*                      - Set the vector table entries with the exceptions ISR address
    ;*                      - Branches to __main in the C library (which eventually
    ;*                        calls main()).
    ;*                      After Reset the Cortex-M4 processor is in Thread mode,
    ;*                      priority is Privileged, and the Stack is set to Main.
    ;********************************************************************************
    ;* @attention
    ;*
    ;* Copyright (c) 2019 STMicroelectronics.
    ;* All rights reserved.
    ;*
    ;* This software is licensed under terms that can be found in the LICENSE file
    ;* in the root directory of this software component.
    ;* If no LICENSE file comes with this software, it is provided AS-IS.
    ;
    ;*******************************************************************************
    ;* <<< Use Configuration Wizard in Context Menu >>>
    ;
    ; Amount of memory (in bytes) allocated for Stack
    ; Tailor this value to your application needs
    ; <h> Stack Configuration
    ;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
    ; </h>
    
    
    @EQU指令,类似C语言的宏
    Stack_Size		EQU     0x400          
    
                    @定义了一个内存区域,名字STACK,后面是一些属性,没有初始化、可读可写、按照2^3对齐,提高访问效率
                    AREA    STACK, NOINIT, READWRITE, ALIGN=3
                    @用于分配一个连续的地址空间
    Stack_Mem       SPACE   Stack_Size
    __initial_sp    @该空间的其实地址, 也就是栈的起始地址
    
    
    ; <h> Heap Configuration
    ;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
    ; </h>
    
    @和上面栈的定义类似, 如果没有用到malloc relloc calloc类似的函数,可以删除
    Heap_Size      EQU     0x200
    
                    AREA    HEAP, NOINIT, READWRITE, ALIGN=3
    __heap_base
    Heap_Mem        SPACE   Heap_Size
    __heap_limit
    			   @伪指令, 告诉编译器按照8字节对齐
                    PRESERVE8
                    @使用的是thumb指令
                    THUMB
    
    
    ; Vector Table Mapped to Address 0 at Reset
    			   @开辟一段空间, 名字讲座reset,存放指令的,只能读
                    AREA    RESET, DATA, READONLY
                    @export,导出的意思,让别的.c和.s文件能够使用这个符号
                    EXPORT  __Vectors 
                    EXPORT  __Vectors_End
                    EXPORT  __Vectors_Size
    
    @一个标号,用来占位置的
    @DCD,声明一个4个字节的变量
    @看第一条和第二条指令, 就是msp的值和即将要执行的代码
    __Vectors       DCD     __initial_sp               ; Top of Stack
                    DCD     Reset_Handler              ; Reset Handler
                    DCD     NMI_Handler                ; NMI Handler
                    DCD     HardFault_Handler          ; Hard Fault Handler
                    DCD     MemManage_Handler          ; MPU Fault Handler
                    DCD     BusFault_Handler           ; Bus Fault Handler
                    DCD     UsageFault_Handler         ; Usage Fault Handler
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     SVC_Handler                ; SVCall Handler
                    DCD     DebugMon_Handler           ; Debug Monitor Handler
                    DCD     0                          ; Reserved
                    DCD     PendSV_Handler             ; PendSV Handler
                    DCD     SysTick_Handler            ; SysTick Handler
    
                    ; External Interrupts
                    DCD     WWDG_IRQHandler                   ; Window WatchDog
                    DCD     PVD_PVM_IRQHandler                ; PVD/PVM1/PVM2/PVM3/PVM4 through EXTI Line detection
                    DCD     RTC_TAMP_LSECSS_IRQHandler        ; RTC, TAMP and RCC LSE_CSS through the EXTI line
                    DCD     RTC_WKUP_IRQHandler               ; RTC Wakeup through the EXTI line
                    DCD     FLASH_IRQHandler                  ; FLASH
                    DCD     RCC_IRQHandler                    ; RCC
                    DCD     EXTI0_IRQHandler                  ; EXTI Line0
                    DCD     EXTI1_IRQHandler                  ; EXTI Line1
                    DCD     EXTI2_IRQHandler                  ; EXTI Line2
                    DCD     EXTI3_IRQHandler                  ; EXTI Line3
                    DCD     EXTI4_IRQHandler                  ; EXTI Line4
                    DCD     DMA1_Channel1_IRQHandler          ; DMA1 Channel 1
                    DCD     DMA1_Channel2_IRQHandler          ; DMA1 Channel 2
                    DCD     DMA1_Channel3_IRQHandler          ; DMA1 Channel 3
                    DCD     DMA1_Channel4_IRQHandler          ; DMA1 Channel 4
                    DCD     DMA1_Channel5_IRQHandler          ; DMA1 Channel 5
                    DCD     DMA1_Channel6_IRQHandler          ; DMA1 Channel 6
                    DCD     0                                 ; Reserved
                    DCD     ADC1_2_IRQHandler                 ; ADC1 and ADC2
                    DCD     USB_HP_IRQHandler                 ; USB Device High Priority
                    DCD     USB_LP_IRQHandler                 ; USB Device Low Priority
                    DCD     FDCAN1_IT0_IRQHandler             ; FDCAN1 interrupt line 0
                    DCD     FDCAN1_IT1_IRQHandler             ; FDCAN1 interrupt line 1
                    DCD     EXTI9_5_IRQHandler                ; External Line[9:5]s
                    DCD     TIM1_BRK_TIM15_IRQHandler         ; TIM1 Break, Transition error, Index error and TIM15
                    DCD     TIM1_UP_TIM16_IRQHandler          ; TIM1 Update and TIM16
                    DCD     TIM1_TRG_COM_TIM17_IRQHandler     ; TIM1 Trigger, Commutation, Direction change, Index and TIM17
                    DCD     TIM1_CC_IRQHandler                ; TIM1 Capture Compare
                    DCD     TIM2_IRQHandler                   ; TIM2
                    DCD     TIM3_IRQHandler                   ; TIM3
                    DCD     TIM4_IRQHandler                   ; TIM4
                    DCD     I2C1_EV_IRQHandler                ; I2C1 Event
                    DCD     I2C1_ER_IRQHandler                ; I2C1 Error
                    DCD     I2C2_EV_IRQHandler                ; I2C2 Event
                    DCD     I2C2_ER_IRQHandler                ; I2C2 Error
                    DCD     SPI1_IRQHandler                   ; SPI1
                    DCD     SPI2_IRQHandler                   ; SPI2
                    DCD     USART1_IRQHandler                 ; USART1
                    DCD     USART2_IRQHandler                 ; USART2
                    DCD     USART3_IRQHandler                 ; USART3
                    DCD     EXTI15_10_IRQHandler              ; External Line[15:10]
                    DCD     RTC_Alarm_IRQHandler              ; RTC Alarm (A and B) through EXTI Line
                    DCD     USBWakeUp_IRQHandler              ; USB Wakeup through EXTI line
                    DCD     TIM8_BRK_IRQHandler               ; TIM8 Break, Transition error and Index error Interrupt
                    DCD     TIM8_UP_IRQHandler                ; TIM8 Update Interrupt
                    DCD     TIM8_TRG_COM_IRQHandler           ; TIM8 Trigger, Commutation, Direction change and Index Interrupt
                    DCD     TIM8_CC_IRQHandler                ; TIM8 Capture Compare Interrupt
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     LPTIM1_IRQHandler                 ; LP TIM1 interrupt
                    DCD     0                                 ; Reserved
                    DCD     SPI3_IRQHandler                   ; SPI3
                    DCD     UART4_IRQHandler                  ; UART4
                    DCD     0                                 ; Reserved
                    DCD     TIM6_DAC_IRQHandler               ; TIM6 and DAC1&3 underrun errors
                    DCD     TIM7_IRQHandler                   ; TIM7
                    DCD     DMA2_Channel1_IRQHandler          ; DMA2 Channel 1
                    DCD     DMA2_Channel2_IRQHandler          ; DMA2 Channel 2
                    DCD     DMA2_Channel3_IRQHandler          ; DMA2 Channel 3
                    DCD     DMA2_Channel4_IRQHandler          ; DMA2 Channel 4
                    DCD     DMA2_Channel5_IRQHandler          ; DMA2 Channel 5
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     UCPD1_IRQHandler                  ; UCPD1
                    DCD     COMP1_2_3_IRQHandler              ; COMP1, COMP2 and COMP3
                    DCD     COMP4_IRQHandler                  ; COMP4
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     CRS_IRQHandler                    ; CRS Interrupt
                    DCD     SAI1_IRQHandler                   ; Serial Audio Interface 1 global interrupt
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     FPU_IRQHandler                    ; FPU
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     RNG_IRQHandler                    ; RNG global interrupt
                    DCD     LPUART1_IRQHandler                ; LP UART 1 interrupt
                    DCD     I2C3_EV_IRQHandler                ; I2C3 Event
                    DCD     I2C3_ER_IRQHandler                ; I2C3 Error
                    DCD     DMAMUX_OVR_IRQHandler             ; DMAMUX overrun global interrupt
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     DMA2_Channel6_IRQHandler          ; DMA2 Channel 6
                    DCD     0                                 ; Reserved
                    DCD     0                                 ; Reserved
                    DCD     CORDIC_IRQHandler                 ; CORDIC
                    DCD     FMAC_IRQHandler                   ; FMAC
    
    __Vectors_End
    
    @计算出向量表的大小
    __Vectors_Size  EQU  __Vectors_End - __Vectors
    
                    AREA    |.text|, CODE, READONLY
    
    @复位函数的入口
    Reset_Handler    PROC       @proc, 可以看作是C语言中的{ , endp可以看作是}
                     EXPORT  Reset_Handler             [WEAK]
            IMPORT  SystemInit   @导入别的文件中的这个符号
            IMPORT  __main       @导入编译器生成的__main函数, 具体作用后面说
    				
    				@将SystemInit函数的地址加载到R0寄存器
                     LDR     R0, =SystemInit
                     @跳转到R0中的地址出执行, 保存返回地址, 以便执行完SystemInit函数后返回到下一条指令执行
                     BLX     R0
                     @加载__main的地址到R0寄存器
                     LDR     R0, =__main
                     @跳转到R0寄存器中的地址执行,不返回
                     BX      R0
                     ENDP
    
    ; Dummy Exception Handlers (infinite loops which can be modified)
    
    
    @下面就是各个异常的默认处理, 都是 [WEAK]虚符号, 当出现强符号的时候会覆盖掉它
    NMI_Handler     PROC
                    EXPORT  NMI_Handler                [WEAK]
                    B       .
                    ENDP
    HardFault_Handler\
                    PROC
                    EXPORT  HardFault_Handler          [WEAK]
                    B       .
                    ENDP
    MemManage_Handler\
                    PROC
                    EXPORT  MemManage_Handler          [WEAK]
                    B       .
                    ENDP
    BusFault_Handler\
                    PROC
                    EXPORT  BusFault_Handler           [WEAK]
                    B       .
                    ENDP
    UsageFault_Handler\
                    PROC
                    EXPORT  UsageFault_Handler         [WEAK]
                    B       .
                    ENDP
    SVC_Handler     PROC
                    EXPORT  SVC_Handler                [WEAK]
                    B       .
                    ENDP
    DebugMon_Handler\
                    PROC
                    EXPORT  DebugMon_Handler           [WEAK]
                    B       .
                    ENDP
    PendSV_Handler  PROC
                    EXPORT  PendSV_Handler             [WEAK]
                    B       .
                    ENDP
    SysTick_Handler PROC
                    EXPORT  SysTick_Handler            [WEAK]
                    B       .
                    ENDP
    
    Default_Handler PROC
    
            EXPORT     WWDG_IRQHandler                   [WEAK]
            EXPORT     PVD_PVM_IRQHandler                [WEAK]
            EXPORT     RTC_TAMP_LSECSS_IRQHandler        [WEAK]
            EXPORT     RTC_WKUP_IRQHandler               [WEAK]
            EXPORT     FLASH_IRQHandler                  [WEAK]
            EXPORT     RCC_IRQHandler                    [WEAK]
            EXPORT     EXTI0_IRQHandler                  [WEAK]
            EXPORT     EXTI1_IRQHandler                  [WEAK]
            EXPORT     EXTI2_IRQHandler                  [WEAK]
            EXPORT     EXTI3_IRQHandler                  [WEAK]
            EXPORT     EXTI4_IRQHandler                  [WEAK]
            EXPORT     DMA1_Channel1_IRQHandler          [WEAK]
            EXPORT     DMA1_Channel2_IRQHandler          [WEAK]
            EXPORT     DMA1_Channel3_IRQHandler          [WEAK]
            EXPORT     DMA1_Channel4_IRQHandler          [WEAK]
            EXPORT     DMA1_Channel5_IRQHandler          [WEAK]
            EXPORT     DMA1_Channel6_IRQHandler          [WEAK]
            EXPORT     ADC1_2_IRQHandler                 [WEAK]
            EXPORT     USB_HP_IRQHandler                 [WEAK]
            EXPORT     USB_LP_IRQHandler                 [WEAK]
            EXPORT     FDCAN1_IT0_IRQHandler             [WEAK]
            EXPORT     FDCAN1_IT1_IRQHandler             [WEAK]
            EXPORT     EXTI9_5_IRQHandler                [WEAK]
            EXPORT     TIM1_BRK_TIM15_IRQHandler         [WEAK]
            EXPORT     TIM1_UP_TIM16_IRQHandler          [WEAK]
            EXPORT     TIM1_TRG_COM_TIM17_IRQHandler     [WEAK]
            EXPORT     TIM1_CC_IRQHandler                [WEAK]
            EXPORT     TIM2_IRQHandler                   [WEAK]
            EXPORT     TIM3_IRQHandler                   [WEAK]
            EXPORT     TIM4_IRQHandler                   [WEAK]
            EXPORT     I2C1_EV_IRQHandler                [WEAK]
            EXPORT     I2C1_ER_IRQHandler                [WEAK]
            EXPORT     I2C2_EV_IRQHandler                [WEAK]
            EXPORT     I2C2_ER_IRQHandler                [WEAK]
            EXPORT     SPI1_IRQHandler                   [WEAK]
            EXPORT     SPI2_IRQHandler                   [WEAK]
            EXPORT     USART1_IRQHandler                 [WEAK]
            EXPORT     USART2_IRQHandler                 [WEAK]
            EXPORT     USART3_IRQHandler                 [WEAK]
            EXPORT     EXTI15_10_IRQHandler              [WEAK]
            EXPORT     RTC_Alarm_IRQHandler              [WEAK]
            EXPORT     USBWakeUp_IRQHandler              [WEAK]
            EXPORT     TIM8_BRK_IRQHandler               [WEAK]
            EXPORT     TIM8_UP_IRQHandler                [WEAK]
            EXPORT     TIM8_TRG_COM_IRQHandler           [WEAK]
            EXPORT     TIM8_CC_IRQHandler                [WEAK]
            EXPORT     LPTIM1_IRQHandler                 [WEAK]
            EXPORT     SPI3_IRQHandler                   [WEAK]
            EXPORT     UART4_IRQHandler                  [WEAK]
            EXPORT     TIM6_DAC_IRQHandler               [WEAK]
            EXPORT     TIM7_IRQHandler                   [WEAK]
            EXPORT     DMA2_Channel1_IRQHandler          [WEAK]
            EXPORT     DMA2_Channel2_IRQHandler          [WEAK]
            EXPORT     DMA2_Channel3_IRQHandler          [WEAK]
            EXPORT     DMA2_Channel4_IRQHandler          [WEAK]
            EXPORT     DMA2_Channel5_IRQHandler          [WEAK]
            EXPORT     UCPD1_IRQHandler                  [WEAK]
            EXPORT     COMP1_2_3_IRQHandler              [WEAK]
            EXPORT     COMP4_IRQHandler                  [WEAK]
            EXPORT     CRS_IRQHandler                    [WEAK]
            EXPORT     SAI1_IRQHandler                   [WEAK]
            EXPORT     FPU_IRQHandler                    [WEAK]
            EXPORT     RNG_IRQHandler                    [WEAK]
            EXPORT     LPUART1_IRQHandler                [WEAK]
            EXPORT     I2C3_EV_IRQHandler                [WEAK]
            EXPORT     I2C3_ER_IRQHandler                [WEAK]
            EXPORT     DMAMUX_OVR_IRQHandler             [WEAK]
            EXPORT     DMA2_Channel6_IRQHandler          [WEAK]
            EXPORT     CORDIC_IRQHandler                 [WEAK]
            EXPORT     FMAC_IRQHandler                   [WEAK]
    
    WWDG_IRQHandler
    PVD_PVM_IRQHandler
    RTC_TAMP_LSECSS_IRQHandler
    RTC_WKUP_IRQHandler
    FLASH_IRQHandler
    RCC_IRQHandler
    EXTI0_IRQHandler
    EXTI1_IRQHandler
    EXTI2_IRQHandler
    EXTI3_IRQHandler
    EXTI4_IRQHandler
    DMA1_Channel1_IRQHandler
    DMA1_Channel2_IRQHandler
    DMA1_Channel3_IRQHandler
    DMA1_Channel4_IRQHandler
    DMA1_Channel5_IRQHandler
    DMA1_Channel6_IRQHandler
    ADC1_2_IRQHandler
    USB_HP_IRQHandler
    USB_LP_IRQHandler
    FDCAN1_IT0_IRQHandler
    FDCAN1_IT1_IRQHandler
    EXTI9_5_IRQHandler
    TIM1_BRK_TIM15_IRQHandler
    TIM1_UP_TIM16_IRQHandler
    TIM1_TRG_COM_TIM17_IRQHandler
    TIM1_CC_IRQHandler
    TIM2_IRQHandler
    TIM3_IRQHandler
    TIM4_IRQHandler
    I2C1_EV_IRQHandler
    I2C1_ER_IRQHandler
    I2C2_EV_IRQHandler
    I2C2_ER_IRQHandler
    SPI1_IRQHandler
    SPI2_IRQHandler
    USART1_IRQHandler
    USART2_IRQHandler
    USART3_IRQHandler
    EXTI15_10_IRQHandler
    RTC_Alarm_IRQHandler
    USBWakeUp_IRQHandler
    TIM8_BRK_IRQHandler
    TIM8_UP_IRQHandler
    TIM8_TRG_COM_IRQHandler
    TIM8_CC_IRQHandler
    LPTIM1_IRQHandler
    SPI3_IRQHandler
    UART4_IRQHandler
    TIM6_DAC_IRQHandler
    TIM7_IRQHandler
    DMA2_Channel1_IRQHandler
    DMA2_Channel2_IRQHandler
    DMA2_Channel3_IRQHandler
    DMA2_Channel4_IRQHandler
    DMA2_Channel5_IRQHandler
    UCPD1_IRQHandler
    COMP1_2_3_IRQHandler
    COMP4_IRQHandler
    CRS_IRQHandler
    SAI1_IRQHandler
    FPU_IRQHandler
    RNG_IRQHandler
    LPUART1_IRQHandler
    I2C3_EV_IRQHandler
    I2C3_ER_IRQHandler
    DMAMUX_OVR_IRQHandler
    DMA2_Channel6_IRQHandler
    CORDIC_IRQHandler
    FMAC_IRQHandler
    
                    B       .
    
                    ENDP
    
                    ALIGN
    
    ;*******************************************************************************
    ; 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
    
    

  • 编译器的__main函数干了那些事
  • 在 STM32 的启动代码中,`__main` 是一个由编译器生成的函数,它是程序的入口点。`__main` 函数在启动代码中被调用,在处理器初始化和启动期间执行一些必要的任务,然后进入主程序。

    `__main` 函数通常会执行以下几个重要的任务:

    1. 设置堆栈指针(Stack Pointer,SP):在启动代码中,首先会设置堆栈指针,即将 SP 寄存器设置为存放堆栈顶端地址的值。通过这个设置,程序可以正确使用堆栈来保存临时变量、函数调用的返回地址等。

    2. 初始化数据段:启动代码将会负责把程序的初始化数据段(.data 段)从 ROM 复制到 RAM。这包括全局变量和静态变量的初始值。这样,程序在执行时就可以使用这些变量了。 3. 清零未初始化数据段:启动代码也会负责把程序的未初始化数据段(.bss 段)清零,以确保所有未初始化的全局变量和静态变量都被初始化为 0 值。

    4. 初始化系统时钟和外设:启动代码可能会进行一些初始化工作,如配置系统时钟和外设的寄存器。这些初始化工作可能包括配置时钟源、设置时钟分频器、配置中断向量表等。

    5. 调用 C/C++ 运行时库的初始化函数:如果使用了 C/C++ 运行时库,启动代码会在主程序执行之前调用一些运行时库的初始化函数,以确保所需的运行环境被正确设置。

    6. 调用主程序(`main` 函数):启动代码结束之前,会最后调用主程序函数 `main`,开始执行主要的应用逻辑。 总的来说,`__main` 函数在 STM32 启动代码中负责执行一系列的初始化工作,以确保系统正确地启动并进入主程序。这些初始化工作包括设置堆栈指针、初始化数据段、清零未初始化数据段、初始化系统时钟和外设等。

    然后,`__main` 函数会调用主程序函数 `main`,将控制权转交给主程序,开始执行应用逻辑。

    够了够了, 再多就撑爆了, 希望大家有收获, 不懂异常向量表的作用的可以去翻翻我老久之前写的文章http://t.csdnimg.cn/Ac0ws

    作者:@daiwei

    物联沃分享整理
    物联沃-IOTWORD物联网 » 深入分析STM32启动流程及底层控制原理

    发表评论