0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

分析ARM Cortex-M内核复位启动过程

STM32嵌入式开发 来源:gaomf.cn 2023-03-20 09:58 次阅读

ARM Cortex-M内核的复位启动过程也被称为复位序列(Reset sequence),下面就来简要总结分析下这一过程。

ARM Cortex-M内核的复位启动过程与其他大部分CPU不同,也与之前的ARM架构(ARM920T、ARM7TDMI等)不相同。大部分CPU复位后都是从0x0000_0000处取得第一条指令开始运行的,然而在ARM Cortex-M内核中并不是这样的。其复位序列为:

1.从地址0x0000_0000处取出MSP的初始值;

2.从地址0x0000_0004处取出PC的初始值,然后从这个值对应的地址处取指。

即下图所示过程:

5071c8e2-c4c5-11ed-bfe3-dac502259ad0.png   

事实上,地址0x0000_0004开始存放的就是默认中断向量表(有些资料中将地址0x0000_0000处的MSP指针初始值也算作中断向量表的一部分,这个说法似乎不太妥当),ARM Cortex-M内核的中断向量表布局情况如下图所示:
50bc09f2-c4c5-11ed-bfe3-dac502259ad0.png     

注意:中断向量表的位置可以改变,此处是默认情况下的设置。

值得注意的是,在ARM Cortex-M内核中,发生异常后,并不是去执行中断向量表中对应位置处的代码,而是将对应位置处的数据存入PC中,然后去此地址处进行取指。简而言之,在ARM Cortex-M的中断向量表中不应该放置跳转指令,而是该放置ISR程序的入口地址。

有了上面的分析就很好理解复位序列了,复位其实就相当于发生了一次Reset异常,而从图中可以看到,地址0x0000_0004处存放的正是Reset异常对应的中断处理函数入口地址。

另外还有两个细节问题需要注意:

1. 0x0000_0000处存放的MSP初始值最低三位需要是0;

2.0x0000_0004处存放的地址最低位必须是1。

第一个问题是因为ARM AAPCS中对栈使用的约定是这样的:
5.2.1.1
Universal stack constraints
At all times the following basic constraints must hold:
Stack-limit < SP <= stack-base. The stack pointer must lie within the extent of the stack.
SP mod 4 = 0. The stack must at all times be aligned to a word boundary.
5.2.1.2
Stack constraints at a public interface
The stack must also conform to the following constraint at a public interface:
SP mod 8 = 0. The stack must be double-word aligned.
简而言之,规约规定,栈任何时候都必须4字节对齐,在调用入口需8字节对齐,而且SP的最低两位在硬件上就被置为0了。


第二个问题与ARM模式与Thumb模式有关。ARM中PC中的地址必须是32位对齐的,其最低两位也被硬件上置0了,故写入PC中的数据最低两位并不代表真实的取址地址。ARM中使用最低一位来判断这条指令是ARM指令还是Thumb指令,若最低位为0,代表ARM指令;若最低位为1,代表Thumb指令。在Cortex-M内核中,并不支持ARM模式,若强行切换到ARM模式会引发一个Hard Fault。


最后写一段小程序来验证下以上分析。这段程序基于STM32F4系列单片机,作用是让PA0管脚输出高电平。这应该也是实现这一目的最精简的写法了。


rAHB1ENR        EQU     0x40023830
AHB1ENRValue    EQU     0x00000001
    
rMODER          EQU     0x40020000
MODERValue      EQU     0xA8000001
    
rODR            EQU     0x40020014
ODRVaule        EQU     0x00000001


    AREA RESET, DATA, READONLY
    DCD 0x00000400
    DCD Start


    AREA |.text|, CODE, READONLY
    ENTRY


Start
    LDR R0, =rAHB1ENR
    LDR R1, =AHB1ENRValue
    STR R1, [R0]
    
    LDR R0, =rMODER
    LDR R1, =MODERValue
    STR R1, [R0]
    
    LDR R0, =rODR
    LDR R1, =ODRVaule
    STR R1, [R0]


    B .  
    END

第11行使用DCD伪指令分配了4个字节的存储空间,并将其值设置为0x0000_0400;第12行同理,将Start标号处的地址放置在偏移量为4字节的位置处;第17行Start标号之后的部分就是程序主体,依次完成了GPIOA端口RCC时钟使能、PA0设置为输出模式、PA0置高这三个步骤。


程序在链接时会将RESET段放置在目标文件开头,故相当于在地址0x0000_0000处的数据为0x0000_0400,在地址0x0000_0004处的数据为Start部分的入口地址。


不过需要指出的是,实际上在STM32F4芯片中,内部Flash的地址是从0x0800_0000处开始的,在BOOT管脚设置为Flash启动的时候,芯片内部会自动将0x0000_00000 0x000F_FFFF区域映射至0x0800_0000 0x080F_FFFF处,此时可以视为二者是等价的。
使用Debug模式进行调试,复位后CPU寄存器的值如下所示:

50ee5d76-c4c5-11ed-bfe3-dac502259ad0.png     

Flash中的数据如图:
5100dc1c-c4c5-11ed-bfe3-dac502259ad0.png   

可以看到,编译器很智能的将0x0800_0004处的数据设置为了0x0800_0009,而不是Start标号真实的地址值,这说明了这是一条Thumb-2指令。复位后PC中的值是0x0800_0008,SP中的值是0x0000_0400,与预期结果完全相同。

最后顺便提一下,上面那段简单的程序有个问题,实际上Start部分的程序是占用了中断向量表的空间,这在没有异常发生的时候是没有问题的,不过一旦有异常发生,显然程序执行是会出错的。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ARM
    ARM
    +关注

    关注

    134

    文章

    8653

    浏览量

    361822
  • 内核
    +关注

    关注

    3

    文章

    1309

    浏览量

    39848
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10444

    浏览量

    206566
  • 中断
    +关注

    关注

    5

    文章

    884

    浏览量

    41025
  • Cortex-M
    +关注

    关注

    2

    文章

    224

    浏览量

    29574

原文标题:分析ARM Cortex-M内核复位启动过程

文章出处:【微信号:c-stm32,微信公众号:STM32嵌入式开发】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    STM32H7的启动过程分析

    本章教程主要跟大家讲STM32H7的启动过程,这里的启动过程是指从CPU上电复位执行第1条指令开始(汇编文件)到进入C程序main()函数入口之间的部分。
    的头像 发表于 10-17 14:42 1637次阅读

    ARM Cortex-M0 DesignStart系列--4启动过程分析

    书接上文《ARM_Cortex-M0 DesignStart系列--3rtl仿真过程的详细分析》,本文基于hello这个case,对Cortex M0的
    的头像 发表于 11-10 09:05 2224次阅读
    <b class='flag-5'>ARM</b> <b class='flag-5'>Cortex</b>-M0 DesignStart系列--4<b class='flag-5'>启动过程</b><b class='flag-5'>分析</b>

    专家揭秘:STM32启动过程全解

    电子发烧友网核心提示: 本文主要阐述了STM32启动过程全面解析,包括启动过程的介绍、启动代码的陈列以及深入解析。 相对于ARM上一代的主流ARM
    发表于 09-10 08:50 5.3w次阅读
    专家揭秘:STM32<b class='flag-5'>启动过程</b>全解

    基于ARM Cortex-M内核的STM32 Nucleo开发板

    。 STM32 Nucleo开发板 基于ARM Cortex-M内核的STM32 Nucleo开发板为用户提供了一个经济实惠且灵活的方式以供用户尝试新的想法,并能与任何STM32微控制
    发表于 08-06 08:52

    Cortex-M内核的GCC编译器

    下载ARM官方对应Cortex-M内核的GCC编译器
    发表于 08-24 06:44

    ARM Cortex-M堆栈机制介绍

      大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是ARM Cortex-M堆栈机制。  今天给大家分享的这篇依旧是2016年之前痞子衡写的技术文档,花了点时间重新编排了一下
    发表于 12-16 06:26

    ARM Cortex-M内核的相关资料推荐

      大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是ARM Cortex-M功能模块,不过侧重点是三款安全特性处理器。  ARM Cortex-M处理器家族发展至今(2
    发表于 12-27 07:21

    ARM Cortex-M内核的相关资料下载

    相关知识STM32,是意法半导体公司推出的基于ARM Cortex-M内核的通用型单片机。意法半导体(STMicroelectronics)是世界最大的半导体公司之一,于1987年6月成立,是由
    发表于 02-07 08:48

    stm32(CortexM3)程序的启动过程是怎样的

    3)程序的启动过程一上电就会触发复位异常。并且会跳转到中断向量表 特定偏移位置,然后获取里面的内容。修改复位异常内的内容,就可以让处理器去执用户指定的操作。启动文件(.s)做了如下四个
    发表于 02-28 06:31

    ARM Cortex-M 开发实战指南入门篇(二)

    、Readme、User。CMSIS 用来存放库为我们自带的启动文件和一些 Cortex-M系列的通用文件,CMSIS文件里存放的文件适合任何Cortex-M内核的单片机,CMSIS
    发表于 04-19 17:24

    如何使用Ozone分析Cortex-M故障?

    Thumb 指令。查看Ozone的寄存器窗口,寄存器UFSR确认CPU已发出INVSTATE UsageFault。使用跟踪功能分析故障在不确定的故障情况下,Cortex-M 内核无法提供故障指令
    发表于 09-23 11:26

    嵌入式uCLinux内核启动过程分析

    分析uCLinux的启动过程,可以加快系统启动速度、正确建立应用环境。本文要研究的就是uCLinux操作系统内核启动过程
    发表于 08-15 16:51 731次阅读

    详解bootloader的执行流程与ARM Linux启动过程分析

    以S3C2410 ARM处理器为例,详细分析了系统上电后 bootloader的执行流程及 ARM Linux的启动过程
    的头像 发表于 12-21 09:24 1w次阅读
    详解bootloader的执行流程与<b class='flag-5'>ARM</b> Linux<b class='flag-5'>启动过程</b><b class='flag-5'>分析</b>

    一文知道MCU上电复位启动过程

    MCU上电(复位)时,从固定的地址启动,一般是地址0x00000000,如ARM7;个别特殊的如STM32默认启动地址为0x8000000(flash区
    的头像 发表于 10-08 10:37 1.2w次阅读

    美信cortex-m3内核芯片的启动过程及连接文件介绍

    本文以美信cortex-m3内核某型号芯片以及eclipse开发环境介绍芯片启动过程以及连接文件。
    的头像 发表于 03-01 11:39 1036次阅读
    美信<b class='flag-5'>cortex</b>-m3<b class='flag-5'>内核</b>芯片的<b class='flag-5'>启动过程</b>及连接文件介绍