当前位置: 首页 > news >正文

详细介绍:【ARMv7】系统复位上电后的程序执行过程

引子:

对于ARMv7-M系列SOC来说,上电后程序复位执行的过程相对来说比较简单,因为绝大部分芯片,都是XIP(eXecute In Place,就地执行)模式执行程序,不需要通过BooROM->PL(preloader)->SBL(second bootloader)->Kernel这样的复杂加载过程。XIP的工具复位执行的总体流程如下图(以STM32F407为例):

阶段1:硬件自动初始化

1. SOC上电或复位

  • 当STM32F407上电或接收到复位信号时,芯片开始启动过程

  • 内部电压调节器、时钟平台开始工作

2. CPU读取地址 0x0000_0000

  • ARM Cortex-M4内核从内存映射的0x0000_0000地址读取第一个值

  • 在STM32F407中,这个地址映射到Flash存储器起始位置(0x0800_0000)

  • 读取的值被加载到主堆栈指针(MSP)中

3. 加载值到MSP

  • 读取的32位值作为初始堆栈指针值

  • 堆栈通常设置在RAM的起始位置加上栈大小(如0x2000_0000 + RAM大小)

4. CPU读取地址 0x0000_0004

  • CPU继续读取下一个32位地址(0x0000_0004)

  • 这个地址涵盖复位向量的值

5. 加载值到PC(复位向量)

  • 从0x0000_0004读取的值被加载到程序计数器(PC)

  • 这个值指向Reset_Handler函数的地址

  • CPU开始执行Reset_Handler处的代码

阶段2:软件初始化(Reset_Handler)

6. PC跳转到Reset_Handler()

  • CPU开始执行启动资料(如startup_stm32f407xx.s)中的Reset_Handler函数

  • 芯片上电后执行的第一段程序代码就是这

7. 堆栈设置判断

  • 检查是否需要设置多堆栈(进程堆栈PSP)

  • 对于大多数应用,只使用主堆栈(MSP)

8. C环境设置

复制.data段从Flash到RAM
  • 将已初始化的全局变量和静态变量从Flash复制到RAM

  • 采用链接器定义的符号:

    • _sidata: .data段在Flash中的起始地址

    • _sdata: .data段在RAM中的起始地址

    • _edata: .data段在RAM中的结束地址

在RAM中清零.bss段
  • 将未初始化的全局变量和静态变量所在的内存区域清零

  • 使用链接器定义的符号:

    • _sbss: .bss段的起始地址

    • _ebss: .bss段的结束地址

9. 系统初始化

调用SystemInit()函数
  • 在system_stm32f4xx.c文件中定义

  • 关键配置:

    • 时钟配置:启用PLL,设置系统时钟为168MHz

    • 总线分频器:配置AHB、APB1、APB2总线时钟

    • Flash延迟:设置Flash等待状态,确保在高速时钟下可靠运行

    • 电源控制:配置电源管理相关设置

10. (可选)初始化C库

  • 如果需要,初始化C标准库

  • 设置堆(heap)和标准I/O等

阶段3:应用程序启动

11. 跳转到main()函数

  • 所有初始化搞定后,跳转到用户编写的main()函数

  • 此时:

    • 时钟系统已正确配置

    • 内存已正确初始化

    • 外设寄存器处于默认状态

12. C应用程序运行

  • 用户应用程序开始执行

  • 可以安全地初始化外设、创建任务、处理中断等

STM32F407特定细节

  • Flash基地址:0x0800_0000

  • RAM基地址:0x2000_0000(112KB或192KB,取决于型号)

  • 系统时钟:最高168MHz

  • 向量表:位于Flash起始位置,包含中断服务例程的地址

这个启动过程确保了硬件和软件环境在main()函数执行前都已正确初始化,为应用程序提供了稳定可靠的运行基础。

http://www.wxhsa.cn/company.asp?id=5093

相关文章:

  • C#高级语法
  • 配置Maven
  • 那两年的回忆录
  • DDR4基本介绍
  • 网络同步预测-Prediction
  • 二十五、多处理器的基本概念 (SISD/SIMD/MIMD)
  • java课堂问题2
  • 集训总结(六)
  • GAS_Aura-Prediction GAS
  • PromptPilot 产品发布:火山引擎助力AI提示词优化的新利器
  • 安装window版本docker
  • 已严肃完成今日特征多项式大学习
  • docker部署Gitlab社区版,步骤以及外网访问出现502的解决方式 - 实践
  • python_Day21_mysql(2)
  • .zip用法
  • vue2使用pnpm编译打包时的错误处理
  • 中南上课第一天
  • 二十四、深入理解CPU控制信号的最终使命
  • 20250915 - 状压dp 总结
  • PS2025安装包永久免费版下载安装教程Photoshop 2025 v26.0安装包永久免费版下载
  • 学校真是太棒了
  • 如果远程玩家过早结束异步任务,并且具有该集的任务仍在运行,则该任务被杀死-SetWaitingOnRemotePlayerData()
  • 9.15日总结
  • 二十二、流水线CPU的神经脉络:详解控制信号的产生、保存与传递
  • python_Day20_mysql(1)
  • 确定调用 TargetData是否已发送-CallReplicatedTargetDataDelegatesIfSet()
  • 二十三、流水线的起点为何无需指挥?深入理解IF与ID这两个“公共流水段”
  • 来解剖 来平息你的颤抖 叫嚷着还不足够 还需要更多疼痛 才值得温柔
  • 从客户端拿到缓存数据-ConsumeClientReplicatedTargetData()
  • 减少KVCache