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

浅谈MCU的启动

目前正在学习STM32F407芯片, 我们通过KEIL将代码生成Application.bin后,通过JFLASH烧录到0x08000000, 然后重新上电MCU就开始工作了。

那APPlication.bin烧录到FLASH后,程序是如何开始工作的?
image

我们找打开bin文件,着重关注前两个32字节, 由于我们MCU是小端存储,可以确定这个两个值是0x200112e0 和0x080001a1。
其实,这两个地址是特殊意义:0x200112e0代表初始化堆栈的地址,而0x080001a1程序执行的第一条指令。

确实,在STM32中,RAM的地始地址是0x20000000, ROM的地始地址是0x08000000,看起来好像是正常的。而且我们知道,当复位MCU时,程序第一条执行的指令是Reset_Handler。 难道0x080001a1就表示Reset_Handler的入口?

但是这里有问题必须得搞清楚,STM32F407是32位的MCU,指令地址应该是4的倍数才对,而此处的0x080001a1明显不是4的倍数。为何会这样呢?
为什么 0x080001A1 不是 4 的倍数?

  • 可能的原因:
    • 硬件设计问题:某些硬件设计可能会使用特殊的启动逻辑,但这非常罕见。
    • 启动代码错误:可能是启动代码写错了,或者在烧录过程中出现了错误。
    • 指令集特性:在某些情况下,ARM Cortex-M 支持从 Thumb 指令集启动,而 Thumb 指令集的地址是 2 字节对齐的。不过,这通常不会导致地址的最低位为 1。
  • 实际原因:
    在 ARM Cortex-M 架构中,程序计数器(PC)的初始值通常会加上 1,以指示处理器从 Thumb 指令集开始执行。这是因为 ARM Cortex-M 架构默认从 Thumb 指令集启动。
    因此,0x080001A1 实际上是一个有效的地址,表示程序从 0x080001A0 开始执行,但最低位被设置为 1,以指示处理器从 Thumb 指令集开始执行。

终于搞清楚了,由于设计原因,原来此处真正的值为 0x080001A0。 那 0x080001A0确实是Reset_Handler的入口地址吗?

两种确认方式:

  1. 使用map文件查看
    image
    然后我们将找到的文件进行反汇编即可确认。

  2. 直接仿真程序
    image

    我们从上面的仿真程序可以清楚的看到,Reset_Handler的入口地址就是0x080001A0。 从寄存器列表也可以发现,PC指针寄存器的值就是0x080001A0, 而SP堆栈寄存器的值就是0x200112e0。

知道了上面的工作原理,我们可以将程序随意烧到FLASH的地方,通过跳转就可以让程序起来了(甚至可以让程序加载到内存,然后再跳转从内存里执行)。
// 定义跳转到 APP 的函数

void JumpToApp(uint32_t app_address)
{typedef void (*APP_START)(void); // 定义函数指针类型uint32_t *p_stack = (uint32_t *)app_address; // APP 的起始地址uint32_t *p_reset = (uint32_t *)(app_address + 4); // APP 的复位向量地址// 检查 APP 的栈指针和复位向量是否有效if ((*p_stack != 0) && (*p_reset != 0)){// 关闭所有中断__disable_irq();// 设置 MSP 栈指针__set_MSP(*p_stack);// 设置 PC 指针到 APP 的入口地址((APP_START)(*p_reset))();}else{// 如果无效,可以在调试中添加错误处理while (1); // 无限循环}
}
http://www.vanclimg.com/news/392.html

相关文章:

  • KMU — Key management unit 作用
  • NRF54L15 GRTC 优点;
  • MS14-019漏洞修复:通过.cmd或.bat文件实现二进制劫持的解决方案
  • 浅谈北京市海淀区七年级下册期末数学试卷T16第二小问
  • 利用Amazon Bedrock生成AI增强设备维护建议
  • SAP为何将S/4HANA更名为SAP Cloud ERP?
  • NRF54L15 关机状态功耗;
  • JUC学习-22-浅谈线程池参数原理
  • C/C++环境搭建
  • 记录Mysql主从
  • To do list
  • 我的博客
  • 基于帧差法与Vibe算法的matlab前景提取
  • Coze开源版?别吹了!
  • 信创是什么.240501
  • Java内存马查杀
  • 同网段 IP 建立数据链路层连通性调试位置IP设备
  • Linux 系统的网络接口命名规则演变
  • 浅聊MySQL和postgreSQL
  • 为什么企业需要员工自助入职录入系统?
  • NRF54L15 RRAM的优点;
  • 树剖学习笔记
  • clickhouse重启,以及修改数据存储目录后重启失败的解决办法
  • 身份证,港澳通行证,台胞证,记一下三个常用的正则判断
  • 接收解析封装H264为PS数据的RTP包
  • Zabbix优化参考1
  • hi
  • 框幅式高光谱文献数据库,换“新”看!科研效率Up Up!
  • vxe-table 实现服务端筛选、分页筛选
  • 函数参数为字符串类型时,默认值设为NULL会报错