• 注册 / 登录
  • 切换到窄版
  • 查看: 1948|回复: 0

    深入理解MCU启动原理

    [复制链接]

    26

    主题

    26

    帖子

    124

    积分

    注册会员

    Rank: 2

    积分
    124
    发表于 2023-6-25 16:12:58 | 显示全部楼层 |阅读模式

    路线栈欢迎您!

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    1. MCU最开始一启动后去哪里读代码?

    CPU上电启动后被设计为去地址0x00000000位置处读取代码;首先会连续读取两个字,分别是栈指针初始值和复位异常处理函数的地址;然后跳去执行复位异常处理函数。

    1.png

    2.png

    当然在一些早期的ARM处理器设计中,如Arm7TDMI,复位后会直接读取0地址处的代码进行执行,由软件初始化栈指针,0地址处存放的直接就是中断处理函数,而不是函数地址。

    所以我们可以有理由推测出,第一个字是栈地址是因为接下来的复位中断处理函数涉及函数跳转,可能已经需要存放内容在栈里了。

    2. 0x0地址处是bootROM代码吗,还是用户bootloader代码?

    答案是都可以。这其实取决于用户的代码是存放在哪里的。

    比如说对于一些性能强的MCU(如Cortex-A系列)来说,代码本身体积比较大,存放在SD卡里或者QSPI/SPI Flash里都有可能,这些MCU启动一定是先去bootROM执行代码,因为SD卡、SPI Flash的储存不在MCU的统一编址空间里,没初始化这些外设前根本无法访问,bootROM这块Nor Flash就一定是可以被MCU直接通过总线地址访问的,0地址的代码位于bootROM中。代码从bootROM中起来后,通过启动引脚判断从哪个外设中搬用户程序,并去初始化相应外设,将外设中存储的用户代码搬到内部SRAM中执行。后续的启动流程不赘述。

    3.png

    对于一些小容量的MCU来说,比如Cortex-M3/M4,他们的芯片里有内置Flash,这个Flash的特点跟上面说的bootROM很像,是MCU可以直接通过地址总线去访问到的,不需要进行外设初始化的。当然,这些MCU内部也是有bootROM的,因此这些MCU一上电可以选择从bootROM中启动,也可以选择从内置Flash中启动,是通过外部引脚进行选择的,选择了谁,就把谁的起始地址映射到0地址处。

    BOOTI
    BOOTO
    映射到的存储器
    0x00000000
    0x00000004
     
    地址映射到
    地址映射到
    X
    0
    内部FLASH
    0x08000000
    0x08000004
    1
    1
    内部SRAM
    0x20000000
    0x20000004
    0
    1
    系统存储器
    0x1FFFB000
    0x1FFFB004

    3. 类似Cortex-M3/M4是如何保证Flash起始地址是栈指针和复位异常处理函数指针的?

    这一点实际是通过编译的链接文件制定的。比如说如下是我截取的IAR的链接文件.icf。

    5.png


    4. MCU有可能不从0地址开始读代码吗?

    M7内核芯片比较灵活了,改变了固定从0x0000 0000地址读取中断向量表的问题,以STM32H7为例,可以从 0x0000 0000 到 0x3FFF 0000 所有地址进行启动。专门安排了个选项字节来配置。

    END
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    小黑屋|路丝栈 ( 粤ICP备2021053448号 )

    GMT+8, 2024-12-22 15:25 , Processed in 0.076327 second(s), 21 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表