当前位置: 首页 > 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.zskr.cn/news/5570.html

相关文章:

  • 网络同步预测-Prediction
  • 集训总结(六)
  • PromptPilot 产品发布:火山引擎助力AI提示词优化的新利器
  • 安装window版本docker
  • python_Day21_mysql(2)
  • .zip用法
  • vue2使用pnpm编译打包时的错误处理
  • 二十四、深入理解CPU控制信号的最终使命
  • 9.15日总结
  • 二十三、流水线的起点为何无需指挥?深入理解IF与ID这两个“公共流水段”
  • nc工具使用 - 谷粒
  • Azure App Service连接Azure SQL MI
  • 将目标数据复制到服务器-ServerSetReplicatedTargetData()
  • 不是说 PHP 不行了吗?为什么 Swoole 还在更新?
  • qoj1831 Bruteforce
  • C++数据结构和算法:链表
  • 详细介绍:Maven入门_简介、安装与配置
  • train-labels.idx1-ubyte里是什么
  • 创建预测窗口-ScopedPredictionWindow();
  • Ability-GetCurrentActorInfo()-IsLocallyControlled()和APawn::IsLocallyControlled()
  • 应该遵守的代码规范与读《数学之美》有感
  • AT_arc171_c [ARC171C] Swap on Tree
  • 新媒体运营用AI排版工具|10分钟搞定公众号图文的全流程指南
  • ctf工具整理
  • 250915 jave se简单过完一遍
  • AT_arc183_b [ARC183B] Near Assignment
  • kubectl 常用命令的分类汇总(一)
  • 完整教程:C3P0连接池适配HGDB
  • kubectl 常用命令的分类汇总(二)
  • ECT-OS-JiuHuaShan框架的逻辑是自洽的,是基于数学表达,不替代现实的苦辣酸甜。