MCU启动流程

MCU启动流程

  • MCU启动流程
  • 1 MCU的启动方式
  • 2 MCU程序启动执行过程
  • 3 启动过程的执行工作
  • 4 keil调式过程验证
  • 5 调试文件map
  • 1 MCU的启动方式

    单片机的启动方式,以stm32为例,如下:
    不同的下载方式对应的不同的启动方式,stm32主要有三种启动方式:flash memory、system memory、Embedded SRAM

    flash启动(最常用):stm32的flash能够擦写数十万次,用户通过JTAG或SWD模式,将程序下载至此,重新启动从此处启动
    sytem memory (系统存储器启动):系统存储器是芯片内的一块特定的区域,系统存储器中预置了一段bootloader,bootloder将程序下载到flash区,通过flash启动
    内嵌SRAM启动:从内存中直接启动代码,避免因小修改反复擦写flash内存,一般用于高速调试

    2 MCU程序启动执行过程

    MCU上电,根据BOOT的引脚(BOOT0、BOOT1)电平,来确定启动地址。一般地址是0x0000000,个别如stm32的启动地址是0x8000000(flahs区启动)。
    stm32内部闪存的起始地址为0x8000000,程序从此处写入,中断向量表位于该位置,首先从0x8000000取出MSP的栈顶指针(设置堆栈),然后从中断向量表中取出复位中断向量,并执行复位中断程序来完成启动。
    程序执行过程如图:
    1、STM32复位后,会从地址为0x8000004处取出复位中断向量的地址,并跳转执行复位中断服务程序,如图1中标号1️⃣​所示。
    2、复位中断服务程序执行的最终结果是跳转至C程序的main函数,如上图中标号2️⃣所示,而main函数应该是一个死循环,是一个永不返回的函数。
    3、在main函数执行的过程中,发生了一个中断请求,此时STM32的硬件机制会将PC指针强制指回中断向量表处,如图中标号3️⃣所示。
    4、根据中断源进入相应的中断服务程序,如图1中标号5️⃣所示。
    5、中断服务程序执行完毕后,程序再度返回至main函数中执行,如图中标号6️⃣所示。

    3 启动过程的执行工作

    启动过程主要完成两部分工作:硬件环境、软件环境
    硬件环境操作:
    初始化时钟:初始化内核时钟,主时钟和各个外设的时钟
    关闭看门狗:看门狗用来检测应用程序异常跑飞而复位CPU,在初始化阶段,没有“喂狗“的动作,有可能导致CPU 不断的复位,此处需要关闭看门狗
    建立中断向量表:中断向量表作为中断源的识别标志,可以形成相应的中断入口地址,或者中断服务程序的入口地址的偏移量和段基值。CPU利用中断向量表转入中断服务程序处理相关到事务
    初始化堆栈:堆栈的作用就是保护现场(上下文),函数调用或中断发生时,将当前执行地址压栈,调用完再返回执行此次的地址。在启动阶段,初始化堆栈的寄存器、堆栈大小、起始地址等
    内存初始化:选择内部或外部RAM
    软件环境操作:
    把RO、RW从它们的加载域复制到运行域
    初始化ZI域
    初始化堆栈指针:包括C库所需要的内存空间、程序执行的所需资源、C库初始化

    4 keil调式过程验证

    进入调试模式,首先进入一个启动文件starup_ARMCM4.s的启动文件,运行指示光标,会停在SystemInit上:

    starup_ARMCM4.s代码的前面是:栈大小stack size设置、堆大小 heap size的设置、一堆中断向量表 Vect Table
    当前运行所在处为Reset_Handle处,在执行main 之前还需要执行 SystemInit,SystemInit在system_ARMCM4.c文件中,如下跳转至system_ARMCM4.c中的SystemInit函数

    执行完SystemInit,将执行__main函数

    参考:单片机启动过程: main之前干了啥

    5 调试文件map

    xxx.map文件是一种通过编译得到的调试输出信息文件,通过map文件可以了解函数的大小,入口地址、变量、参数的大小位置等一些列信息,用于解决内存越界以及数据溢出等问题。
    map文件是在配置页面的Linker Listing选项卡进行配置:

    map文件分析:map文件主要分为5大类,如下:

    Section Cross References:模块、段(入口)交叉引用
    配置勾选—–>Cross Reference

    针对第四条内容:
    startup_armcm4.o(RESET) refers to startup_armcm4.o(STACK) for __initial_sp
    表示startup_armcm4.o中的RESET段引用了startup_armcm4.o中的STACK段中的一个全局变量(或函数)__initial_sp
    Removing Unused input sections from the image:移除未调用模块
    配置勾选—–>Unused Section Info
    显示的是编译时从映像中被移除的未调用模块,以及它们的大小及总体统计内容

    Image Symbol Table:映射符号表
    配置勾选—–>Symbols
    该部分显示符号映射表,包括两个部分:Local Symbol(局部变量)和Global Symbol(全局变量)

    Memory Map of the image:内存(映射)分布
    配置勾选—–>Memory Map

    Image Entry point : 0x000000c1 映射入口地址
    Load Region LR_IROM1 (Base: 0x00000000, Size: 0x0000026c, Max: 0x00040000, ABSOLUTE):指加载区域位于LR_IROM1开始地址0x00000000,大小有0x0000026c,这块区域最大为0x00040000
    Execution Region ER_IROM1 (Base: 0x08000000, Size: 0x00001188, Max: 0x00080000, ABSOLUTE)

    Execution Region RW_IRAM1 (Exec base: 0x20000000, Load base: 0x00000268, Size: 0x00001068, Max: 0x00020000, ABSOLUTE)

    首先就是映像的入口地址0x000000c1,然后可以知道加载域的起始地址,大小,最后知道执行域ROM和RAM的起始地址和大小,其中0x20000000是RAM起始地址,0x00000000是ROM起始地址,在这里也就是flash。一些被丢弃掉的数据,比如没有使用的变量被优化后是不会在表中显示出来的。
    Image component sizes:存储组成大小
    配置勾选—–>Size Info

    Code:代码数据
    RO-data:指只读数据,除了内联数据之外的常量数据
    RW-data:指可读写、已初始化变量
    ZI-data:为初始化变量

    上面显示的几个区域的总体占用大小,其中:
    Code、Ro-data:位于FLASH
    Rw-data、ZI-data:位于RAM中
    RW-data已初始化的数据会存储在Flash中,上电会从FLASH搬移至RAM
    Total ROM Size就是下载到flash中的程序大小

    物联沃分享整理
    物联沃-IOTWORD物联网 » MCU启动流程详解

    发表评论