GD32F4系列微控制器上电启动流程

根据提供的《GD32F4xx用户手册》及相关文档,GD32F470系列微控制器(基于ARM Cortex-M4内核)的上电启动过程是硬件和软件协同工作的结果。以下是详细的启动步骤,直到执行用户程序的main函数。

核心启动流程概览

整个过程可以分为三个阶段:

  1. 硬件复位与内核启动:芯片上电,硬件逻辑将CPU从复位状态释放,内核从固定的存储地址开始执行预置代码。
  2. 启动程序(Bootloader / 启动文件)执行:这通常由固化在芯片内部或用户编写的汇编启动代码完成,负责初始化最基本的系统环境。
  3. C运行时环境建立与跳转 :初始化C语言的运行环境(如堆栈、全局变量),最后跳转到用户编写的main函数。

详细步骤分解

第一阶段:硬件复位与内核启动
  1. 上电复位

    • 当给芯片提供稳定的电源(VDD/VDDA)后,内部的上电复位(POR) 电路会产生一个复位信号,将芯片(除备份域外)的所有逻辑复位到初始状态。
    • 如果使能了欠压复位(BOR),电源电压需高于设定的阈值,才会释放复位信号。
  2. 引导配置(Boot Configuration)

    • 在复位信号释放后的第四个系统时钟(CK_SYS)上升沿,芯片会锁存 BOOT0BOOT1 引脚的电平状态。这两个引脚决定了CPU从哪个存储空间开始取指(引导源)。根据手册 表1-3. 引导模式
      • BOOT0=0:从主FLASH存储器 启动(地址 0x0800 0000)。这是最常见的用户程序运行模式。
      • BOOT0=1, BOOT1=0:从系统存储器 (Bootloader)启动(地址 0x1FFF 0000)。
      • BOOT0=1, BOOT1=1:从片上SRAM 启动(地址 0x2000 0000)。
  3. 映射与取向量

    • 根据选择的引导模式,相应的存储空间会被映射到引导存储空间 (即从 0x0000 0000 开始的地址空间)。例如,当选择从主FLASH启动时,FLASH的起始地址 0x0800 0000 被映射到 0x0000 0000
    • Cortex-M4内核0x0000 0000 地址读取数据,并将其作为栈顶指针(MSP) 的初始值。
    • 紧接着,内核从 0x0000 0004 地址读取数据,并将其作为复位向量,即复位后要执行的第一条指令的地址。
第二阶段:启动程序执行
  1. 跳转到复位处理函数

    • CPU跳转到复位向量指向的代码地址,这个地址通常是启动文件(startup_gd32f470.s)中的Reset_Handler函数入口。
  2. Reset_Handler执行

    这个函数是启动程序的核心,主要执行以下操作:

    • 系统时钟初始化 :调用SystemInit函数。该函数配置时钟控制单元(RCU),将系统时钟从默认的内部16MRC振荡器(IRC16M) 切换到用户配置的时钟源(如外部高速晶体振荡器(HXTAL)锁相环(PLL)),最终设置到最高频率(例如200MHz)。这一步在手册第4章"复位和时钟单元(RCU)"中有详细说明。
    • 中断向量表重定位 :如果程序在SRAM中运行或需要重定位中断向量表,SystemInit或后续代码会配置中断向量表偏移量寄存器(VTOR),将其指向正确的位置。
    • 初始化静态数据
      • 已初始化的全局变量和静态变量.data段)从FLASH复制到SRAM中。
      • 未初始化的全局变量和静态变量.bss段)所在的SRAM区域清零。
    • 初始化堆和栈 :为C语言的运行库设置堆栈指针(SP),并可能初始化堆内存(用于malloc等动态内存分配)。
第三阶段:进入用户程序
  1. 跳转到__main

    • Reset_Handler函数的最后一步通常是跳转到C库的入口函数__main(注意,不是用户写的main)。
  2. C库初始化

    • __main函数负责完成C运行时环境的最后设置,例如初始化C库函数所需的资源。
  3. 执行用户main函数

    • C库初始化完成后,最终会调用用户程序中的main函数。至此,用户程序开始执行。

总结图示

关键点总结

  • 启动文件 :整个过程的核心是启动文件(通常由芯片厂商提供),它包含了Reset_HandlerSystemInit函数的汇编/C实现。
  • 向量表 :存储在FLASH起始位置(0x0800_0000)的向量表是程序正确运行的基石。第一个字是栈顶地址,第二个字是Reset_Handler的地址。
  • SystemInit :在进入用户main函数之前,一个稳定且高效的时钟配置是必需的。SystemInit函数正是为此而设。你可以在system_gd32f4xx.c文件中找到它并进行配置。
  • 用户入口点 :尽管启动过程复杂,但最终目标就是可靠地跳转到你编写的main函数,开始应用程序的逻辑。
相关推荐
daad7771 小时前
记录一次ardupilot_sitl调试longitude的输入数据流
单片机·嵌入式硬件
搁浅小泽1 小时前
电子负载的作用
单片机·嵌入式硬件
周周记笔记3 小时前
【元器件专题】MOS管上下桥设计详解(死区时间)
单片机·嵌入式硬件
RFID舜识物联网4 小时前
耐高温RFID:让喷涂线从“数据断点”走向“全链贯通”
大数据·人工智能·嵌入式硬件·物联网·汽车
2601_958352904 小时前
A-59双麦模块实战:打造面对面双人独立拾音与实时翻译系统,全双工无串扰
人工智能·嵌入式硬件·语音识别·回音消除·音频处理模块
天月风沙4 小时前
基于机器视觉的实验室器件仓储系统设计——内蒙古自治区国家级大创——使用指南
嵌入式硬件
电子科技圈4 小时前
边缘AI赋能物联网,芯科科技推动智能边缘创新
人工智能·嵌入式硬件·物联网·智能家居·健康医疗·智能硬件·交通物流
jing.wang_20255 小时前
TI TMS320C6678芯片实现IP及端口在线修改并生效
网络·嵌入式硬件·tcp/ip·dsp开发
CET中电技术5 小时前
不用外挂传感器、不用停机检测——CET中电技术如何重构电动机运维范式?
单片机·嵌入式硬件