浅谈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 的函数

/* by 01022.hk - online tools website : 01022.hk/zh/keyboardcode.html */
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); // 无限循环
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值