深入了解STM32内核架构——Cortex M3

目录

前言

一、STM32系统架构

二、Cortex M3内核

1、NVIC(嵌套向量中断控制器)

2、存储器保护单元(MPU)

3、总线接口

4、寄存器(重点)

通用寄存器

特殊功能寄存器

5、流水线

三、存储结构(重点)

1、存储器空间分配

2、位带操作

3、端模式

4、非对齐访问

 四、工作模式和工作等级

1、工作等级

2、工作模式

3、比较与切换

五、堆栈(主要说的是栈)

1、堆栈的基本操作

2、双堆栈机制

六、异常与中断(重点)

1、异常

2、Cortex-M3 异常的特点:

1、优先级

2、向量表​​​​​​​

3、高级中断技术

七、复位序列和启动

完结



前言

本文主要介绍STM32的内核——Cortex M3,同时STM32的处理器(CPU)就位于其中。由于不同系列的STM32单片机有不同的内核,本文以STM32F1系列为主,即内核为Cortex M3。在阅读本文之前可以先看看 

51单片机内核及其工作原理

以此来理解STM32的内容,因为STM32的内核比较复杂,且内容很多,不能一一详解。前后关联内容较多,不一定遵从文章顺序阅读。


一、STM32系统架构

其他以Cortex M3为内核的微处理器的主体架构都相同,下面以STM32为例,STM32单片机的基本架构如下:

其中Cortex M3内核和调试系统由ARM公司设计,但是其公司不生产芯片,只售卖知识产权。而芯片主要由各个芯片制造商设计开发,基于此内核开发芯片的各种功能外设等,ST(意法半导体)公司就是一个比较出名的芯片制造商,而STM32系列单片机就是由此公司生产的。

继续细化上面的结构,如STM32一般系列的内部:

其中,四个驱动单元是:

内核
DCode
总线
;

系统总线
;

通用
DMA1;

通用
DMA2。

四被动单元是:

AHB

APB
的桥:连接所有的
APB
设备;

内部
FlASH
闪存;

内部
SRAM

FSMC。

图中几个总线:


ICode
总线:该总线将
M3
内核指令总线和闪存指令接口相连,指令的预取在该总线上面完成。


DCode
总线:该总线将
M3
内核的
DCode
总线与闪存存储器的数据接口相连接,常量加载和调试访问在该总线上面完成。

③ 系统总线:该总线连接
M3
内核的系统总线到总线矩阵,总线矩阵协调内核和
DMA
间访问。


DMA
总线:该总线将
DMA

AHB
主控接口与总线矩阵相连,总线矩阵协调
CPU
的DCode 和
DMA

SRAM,
闪存和外设的访问。

⑤ 总线矩阵:总线矩阵协调内核系统总线和
DMA
主控总线之间的访问仲裁,仲裁利用轮换算法。


AHB/APB

:
这两个桥在
AHB

2

APB
总线间提供同步连接,
APB1
操作速度限于36MHz,APB2 操作速度全速。


二、Cortex M3内核

Cortex-M3内核基于哈佛结构的三级流水线,采用ARMv7-M架构,使用Thumb-2指令集,集成了分支预测、单周期乘法、硬件除法等功能。

官方介绍:

        Cortex‐M3是一个
32位处理器内核

内部的数据路径是32位的,寄存器是 32 位的,存储器接口也是 32 位的

CM3
采用了
哈佛结构
拥有独立的指令总线和数据总线,可以让取指与数据访问 同时进行。这样一来数据访问不再占用指令总线,从而提升了性能。为实现这个特性, CM3
内部 含有好几条总线接口,每条都为自己的应用场合优化过,并且它们可以并行工作。但是另一方面,
指令总线和数据总线共享同一个存储器空间(一个统一的存储器系统)
。换句话说,不是因为有两 条总线,可寻址空间就变成 8GB
了。

        比较复杂的应用可能需要更多的存储系统功能,为此 CM3
提供一个可选的
MPU
,而且在需要的情况下也可以使用外部的 cache
。另外在
CM3
中,
Both
小端模式和大端模式都是支持的。 CM3 内部还附赠了好多调试组件,用于在硬件水平上支持调试操作,如指令断点,数据观察点 等。另外,为支持更高级的调试,还有其它可选组件,包括指令跟踪和多种类型的调试接口。

Cortex-M3内核的核心系统(也就是平常所说的CPU),包括指令取指单元、译码单元、寄存器组和运算器等。

具有以下特性:
(1)采用ARM v7-M架构的哈佛处理器架构;
(2)三级流水线;
(3)中断响应快速且支持多级中断嵌套,中断延迟短;
(4)32位单周期乘法,硬件除法指令;
(5)具有分组的堆栈指针;
(6)处理模式(handler mode)和线程模式(thread mode);
(7)Thumb状态和调试状态;
(8)功耗低;
(9)具有门数目少 (价格低)、调试成本低 ;
(10)支持非对齐访问。

1、NVIC(嵌套向量中断控制器)

嵌套向量中断控制器:(Nested Vector Interrupt Controller,NVIC)NVIC是Cortex-M3内建的中断控制器,与CPU紧密耦合实现低延迟中断处理。它包含众多控制寄存器,支持中断嵌套模式,提供向量中断处理机制等功能。

具有以下特性:

(1)外部中断可配置为1~240个;
(2)优先级位可配置为3~8位;
(3)中断优先级可动态地重新配置;
(4)优先级分组,分为占先中断等级和非占先中断等级;
(5)支持咬尾技术(tail-chaining)和迟来(late arrival)中断; 
(6)处理器状态在进入中断时自动保存,中断退出时自动恢复

(在异常和中断部分会有介绍)

2、存储器保护单元(MPU)

        Cortex‐M3 有一个可选的
存储器保护单元

配上它之后,就可以对特权级访问和用户级访问分别施加不同的访问限制。当检测到犯规(violated)时,MPU 就会产生一个 fault 异常,可以由 fault异常的服务例程来分析该错误,并且在可能时改正它。

        MPU 有很多玩法。最常见的就是由操作系统使用
MPU
,以使特权级代码的数据,包括操作系统本身的数据不被其它用户程序弄坏。MPU
在保护内存时是按区管理的
(
“区”的原文是
region
,以后不再中译此名词——译注)
。它可以把某些内存
region
设置成只读,从而避免了那里的内容外被更改;还可以在多任务系统中把不同任务之间的数据区隔离。一句话,它会使嵌入式系统变得更加健壮,更加可靠(很多行业标准,尤其是航空的,就规定了必须使用 MPU
来行使保护职能—译 注)。

3、总线接口

Cortex‐M3 内部有若干个总线接口,以使 CM3 能同时取址和访内(访问内存)
,它们是:

1、 指令存储区总线(两条)
有两条代码存储区总线
负责对代码存储区的访问,分别是
I‐Code
总线

D‐Code
总线
。前者用于取指,后者用于查表等操作,它们按最佳执行速度进行优化。

2、 系统总线: 系统总线用于访问内存和外设,覆盖的区域包括 SRAM
,片上外设,片外
RAM
,片外扩展设备,以及系统级存储区的部分空间。

3、私有外设总线:私有外设总线
负责一部分私有外设的访问,主要就是访问调试组件。它们也在系统级存储区。

       ​​​​​​​

下图为STM32F1系列单片机的总线矩阵,其中,I-Code总线主要负责0x00000000~0x1FFFFFFF之间的取指操作,以字的长度执行。D-Code总线主要负责在0x00000000~0x1FFFFFFF之间的数据访问操作。系统总线负责在0x20000000~0xDFFFFFFF和0xE0100000~0xFFFFFFFF之间的所有数据传送。私有外设总线:外部私有外设总线,0xE0040000~0xE00FFFFF,包括ETM,TPIU等;内部私有外设总线,0xE000000~0xE003FFFF,包括NVIC,MPU等。

4、寄存器(重点)

包含13个通用的32位寄存器(R0~R12)、链接寄存器(LR)、程序计数器(PC)、程序状态寄存器(xPSR)、两个分组的SP寄存器等。

通用寄存器

低寄存器:r0-r7可以被指定通用寄存器的所有指令访问;

高寄存器:r8-r12可以被指定通用寄存器的所有32位指令访问,不能被16位指令访问。

分组的堆栈指针(SP):由于SP忽略了写入位[1:0]的值,即把管SP值的低两位,因此它自动与字,即4字节边界对齐

特点:

1、Cortex-M3内核有两个堆栈指针:MSP(主堆栈)和PSP(进程堆栈);
2、结束复位后,所有代码都使用主堆栈 ;
3、所有异常都使用主堆栈 ;
4、异常处理程序(例如SVC)可以通过改变其在退出时使用的EXC_RETURN值来改变线程模式使用的堆栈;

5、在线程模式中,使用MSR指令对CONTROL[1]执行写操作也可以从主堆栈切换到进程堆栈; 

注意:一般通过中断返回进行堆栈切换,MSR指令切换用的极少。
6、堆栈指针r13是分组寄存器,在SP_main和SP_process之间切换,在任何时候,进程堆栈和主堆栈中只有一个是可见的,由r13指示。

链接寄存器(LR):在执行分支(branch)和链接(BL)指令或带有交换的分支和链接指令(BLX)时,LR用于保存PC的返回地址。主要用于保存子程序的返回地址。LR也用于异常返回。例如:

其中,当调用子程序delay时,LR寄存器将保存好主程序中下一条指令的地址(返回地址),在执行完子程序后,便跳转到LR寄存器中的地址所在的地方继续执行。

程序计数器(PC):程序计数器总是指向正在取指的指令,决定程序的执行流向。因为 CM3 内部 使用了指令流水线,读 PC 时返回的值是当前指令的地址+4。如果向 PC 中写数据,就会引起一次程序的分支(但是不更新 LR 寄存器。CM3 中的指令至少是半字对齐的,所以 PC 的 LSB(最低位) 总是读回 0。然而,在分支时,无论是直接写 PC 的值还是使用分支指令,都必须保证加载到 PC 的数值是奇数(即 LSB=1),用以表明这是在Thumb 状态下执行。倘若写了 0,则视为企图转入 ARM模式,CM3 将产生一个fault异常。 ​​​​​​​

特殊功能寄存器

三类特殊功能寄存器:
(1)程序状态寄存器(ProgramStatusRegister,PSRs):用于指示程序的运行状态。

(2)中断屏蔽寄存器(PRIMASK、FAULTMASK和BASEPRI)。
(3)控制寄存器(CONTROL)。

对程特殊功能寄存器的访问只能使用MRS和MSR指令
MRS<reg>,<special_reg>;将特殊功能寄存器(Special_reg)的值读到通用寄存器(Reg)。
MSR<special_reg>,<reg>;将通用寄存器(Reg)的值写到特殊功能寄存器(Special_reg)。

如下:从特殊功能寄存器中读出数据并存入到通用寄存器中。

应用状态寄存器(APSR):应用状态寄存器(APSR)包含条件代码标志。在进入异常之前,Cortex-M3处理器将条件代码标志保存在堆栈内(硬件压栈)。如下:

中断状态寄存器(IPSR):中断状态寄存器(IPSR)包含当前激活的异常的ISR编号。

执行状态寄存器(EPSR):为什么需要执行状态寄存器EPSR?因为LDM、STM和If-then指令,为多周期指令,如果在执行以上多周期指令时发生异常,处理器会暂时停止以上指令的操作,进入异常,这时需要保护现场。

注:ICI区和IT区是重叠的,因此,If-Then模块内的多寄存器加载或存储操作不具有可中断-可继续功能。

ICI:可中断-可继续的指令位。如果在执行LDM或STM操作时产生一次中断,则LDM或STM操作暂停。EPSR使用位[15:12]来保存该操作中下一个寄存器操作数的编号。在中断响应之后,处理器返回由[15:12]指向的寄存器并恢复操作。如果ICI区指向的寄存器不在指令的寄存器列表中,则处理器对列表中的下一个寄存器(如果有)继续执行LDM/STM操作。

IT:If-Then位。它们是If-Then指令的执行状态位。包含If-Then模块的指令数目和它们的执行条件。

T:用于指示处理器当前是ARM状态还是Thumb状态。由于ARMv7-M架构仅仅支出Thumb指令,所以T位一直为1。操作EPSR寄存器时必须注意,不能清零T位,否则会引起INVSTATE异常。

不能直接访问EPSR,若想修改EPSR必须发生以下两个事件之一:在执行LDM或STM指令时产生一次中断或执行If-Then指令;如果出现下列情况,LDM/STM操作重新开始而不是继续执行:
LDM/STM错误或LDM/STM指令位于IT内。

中断屏蔽寄存器( PRIMASK ):相当于中断总开关,为1,所有中断被屏蔽;为0,中断能正常响应。只有最低位有效。

 BASEPRI:可屏蔽等于和低于某个优先级的中断。例如,把BASEPRI设置为0X40(即2<<5),
则2和2以上优先级的中断被屏蔽,只有0和1优先级的中断不被屏蔽。

注: BASEPRI与优先级分组有关,stellaris系列处理器使用高3位来配置。

BASEPRI_MAX:用于设置BASEPRI的最大值。

控制寄存器( CONTROL):

5、流水线

支持三级流水线,分别为:

如下,在第一个周期,PC指向指令1,此时指令1进入三级流水线的取指阶段;在第二个周期,PC指向指令2,此时指令1进入三级流水线的译码阶段,同时取出指令2;在第三个周期,PC指向指令3,此时指令1进入三级流水线的执行阶段,指令2进入译码阶段,取出指令3;在第四个周期,指令1执行完成,指令2和指令3的流水线推进一个阶段,同时开始指令4的取指操作。

注意:执行的时候遇到跳转指令时则清空流水线,如果带分支预测,跳转指令在译码时就会被识别,取指流水线自动加载跳转后的指令。即使产生了中断,一条处于“执行”阶段的指令也将会执行完成,流水线里其他的指令将会被放弃,而处理器将从向量表的合适入口开始填充流水线。


三、存储结构(重点)

Crotex-M3支持访问4GB存储空间,即有32条地址线,寻址空间为2的32次方,也就是4GB的空间,是有一个单一固定的存储器映射。寻址空间的大小等内容很重要,相关内容可以参考51单片机内核及其工作原理这篇文章,里面有说明。

其结构如下:

特点:
(1)存储器映射是预定义的,并且还规定好了哪个位置使用哪条总线。
(2)支持位带(Bit Band)操作。通过它,实现了对单一比特(某个位)的原子操作。位带操作仅适用于一些特殊的存储器区域。
(3)支持非对齐访问和互斥访问。
(4)支持小端模式和大端模式。

1、存储器空间分配

(1)代码区(0x00000000~0xlFFFFFFF,共512MB)。主要用于存放程序代码。
(2)片上SRAM区(0x20000000~0x3FFFFFFF,共512MB)。
(3)片上外设区(0x40000000~0x5FFFFFFF,共512MB)。
(4)外部RAM区(0x60000000~0x9FFFFFFF,共1GB)和外部设备区(0xA0000000~0xDFFFFFFF,共1GB)。
(5)私有外设总线区(0xE0000000~0xE00FFFFF,共1MB)。
(6)芯片厂商指定区(0xE0100000~0xFFFFFFFF,共511MB)。

2、位带操作

通过位带操作,用户可以使用普通的加载(Load)/存储(Store)指令对单一的位进行读写。在Cortex-M3中,有两个区中实现了位带:一个是内部SRAM区的最低1MB空间, 另一个是片上外设区的最低1MB空间。位带别名区把每个位膨胀成一个32位的字,当访问位带别名区中的字时,就和访问原始比特一样。即可以按字寻址(一个字等于四个字节,也就是说位地址是以四个字节为一个单位),找到字地址之后可以进行按位操作。

如下,位带区与位带别名区的膨胀对应关系:

①对于内部SRAM位带区的某个位,记它所在字节地址为A,位序号为n(0≤n≤7),则该比特在别名区的地址为:AliasAddr=0x22000000+((A-0x20000000)╳8+n)╳4=0x22000000+(A-0x20000000)╳32+n╳4

②对于片内外设位带区的某个位,记它所在字节的地址为A,位序号为n(0≤n≤7),则该比特在别
名区的地址为:AliasAddr=0x42000000+((A-0x40000000)╳8+n)╳4=0x42000000+(A-0x40000000)╳32+n╳4

如正点原子的sys.h文件中就有该操作,使用位带操作便可以直接就行端口的读写:

位带操作的好处:通过位带操作实现互锁访问,从而避免紊乱现象。

3、端模式

Cortex-M3同时支持小端模式和大端模式。在绝大多数的情况下,基于Cortex-M3的微控制器都是用小端模式(即数据的高位字节保存在高位地址,数据的低位字节保存在低位地址)。假设0x12345678保存在0x4000开始的存储器单元,如下:

4、非对齐访问

ARMCortex-M3支持非对齐访问,提高存储器使用率。


 四、工作模式和工作等级

1、工作等级

特权访问:特权执行可以访问所有资源。

用户访问:非特权执行时对有些资源的访问受到限制或不允许访问。如部分指令的使用(设置FAULTMASK和PRIMASK的CPS指令)对系统控制空间(SCS)的大部分寄存器的访问。

2、工作模式

处理模式:出现异常时处理器进入处理模式;在处理模式中,所有代码都是特权访问的。

线程模式:在复位时处理器进入线程模式;异常返回时处理器进入线程模式;特权和用户(非特权)代码能够在线程模式下运行。

3、比较与切换

三种执行模式的比较:

工作模式和工作等级的切换:

CONTROL[0]=0时,中断前后的状态转换,

CONTROL[0]=1时,中断前后的状态转换。


五、堆栈(主要说的是栈)

1、堆栈的基本操作

堆栈操作就是对内存的读写操作,但是其地址由专门的寄存器——堆栈指针(SP)给出,其数据操作模式满足先进后出(FILO)的规则。Cortex-M3使用的是“向下生长的满栈”模型。堆栈是按字操作的,即每次入栈和出栈都是32位数据,因此SP值总是执行自增4/减4操作,而不是加1和减1。
在Cortex-M3中,采用PUSH(入栈)指令和POP(出栈)指令进行入栈和出栈操作。PUSH操作时,SP先自减4,再存入数据到SP所指存储器位置;POP操作正好相反,先从SP所指存储器位置读出数据,SP再自增4。

2、双堆栈机制

Cortex-M3的堆栈有两个:主堆栈(MSP)和进程堆栈(PSP),MSP和PSP都被称为R13,在程序中可以通过MRS/MSR指令设置CONTROL[1]来指定选用的堆栈指针。其实和工作等级相关,特权级下使用MSP,非特权级(用户级)下使用PSP:

CONTROL[1]=0时,堆栈指针的使用情况,

CONTROL[1]=1时,堆栈指针的使用情况。

双堆栈指针在OS(操作系统)环境中的应用:

MSP:用于OS内核和异常处理;

PSP:用于应用任务。

双堆栈指针的初始化:在系统复位时,从0x00000000处读MSP的初始值,在OS初始化时,对PSP进行初始化。

指针在不同任务间的切换:PSP用任务A的SP执行入栈操作,并保存任务A的SP;设置PSP指向任务B的栈空间,用任务B的SP执行出栈,随后开始执行任务B。

(PSP堆栈指针主要用于操作系统,普通操作,特别是用高级语言开发时,基本不用管双堆栈指针的问题。)


六、异常与中断(重点

1、异常

什么是异常?只要正常的程序被暂时中止,处理器就进入异常模式。异常包括复位、系统故障、外设中断(中断的内容可以查阅什么是中断这篇博客)等事件。 ARMCortex-M3处理器的所有异常可以通过NVIC(嵌套向量中断控制器)进行控制,通过NVIC可以设置各个异常的优先等级并对异常进行处理。所有异常都在处理器模式(Handler Mode)中处理。  

NVIC的功能:Cortex-M3内核集成了中断控制器——嵌套向量中断控制器。NVIC具有以下功能:
1)可嵌套中断支持。
2)向量中断支持。
3)动态优先级调整支持。
4)中断延迟大大缩短。
5)中断可屏蔽。             

异常种类:Cortex-M3处理器(STM32F1系列)中存在多种异常类型,系统复位、NMI(不可屏蔽中断)、硬件故障、存储器管理、总线故障、使用故障、SVCall(软件中断)、调试监控和IRQ中断等。IRQ中断也分为CortexM3内自带的PendSV(系统服务请求)、SysTick(系统节拍定时器-嘀嗒时钟-高精度系统时钟),和与芯片外设相关的外部中断

编号为1~15异常时系统异常;大于等于16的异常则全部是外部中断,当异常产生后,处理器根据中断号从在向量表中取出异常处理函数入口(函数指针)。​​​​​​​

2、Cortex-M3 异常的特点:

1、自动的状态保存和恢复。处理器在进入ISR之前将状态寄存器和部分寄存器自动压栈,退出ISR之后它们自动出栈,不需要多余的指令。自动读取代码存储器或SRAM中包含ISR地址的向量表入口。该操作与状态保存同时执行。
2、支持末尾连锁,在末尾连锁中,处理器在两个ISR之间不需要再对寄存器进行出栈和压栈操作的情况下处理背对背中断。
3、中断优先级可动态重新设置。
4、Cortex-M3与NVIC之间采用紧耦合(closely-coupled)接口,通过该接口可以及早地对中断和高优先级的迟来中断进行处理。
5、中断数目可配置为1~240。
6、中断优先级的数目可配置为1~8位(1~256级)。处理模式和线程模式具有独立的堆栈和特权等级。

1、优先级

在Cortex-M3中,优先级对于异常来说很关键,它会影响一个异常能否被响应,以及何时可以得到响应。优先级的数值越小,优先级越高。用户可设置的最高优先级为0号优先级,其仅次于复位,NMI以及硬件故障的第4优先级。

注意:0号优先级也是所有可调整优先级的默认优先级。如果将两个或更多的中断指定为相同的优先级(例如优先级全为0),那么它们的硬件优先级(位置编号越高优先级越低)就决定了处理器激活这些中断的顺序(硬件优先级不能嵌套,只是在同时激活时优先响应)。例如,如果PendSV和SysTick的优先级都为0,那么PendSV的优先级更高。

NVIC支持由软件指定的可配置的优先级(称为软件优先级)。通过对中断优先级寄存器的8位PRI_N区执行写操作。硬件优先级随着中断号的增加而降低。0优先级最高,255优先级最低。指定软件优先级后,硬件优先级无效。

注:软件优先级的设置对复位,NMI,和硬故障无效。它们的优先级始终比外部中断要高。

优先级分组:为了对具有大量中断的系统加强优先级控制,NVIC支持优先级分组机制。可以使用应用中断和复位控制寄存器中的PRIGROUP区来将每个PRI_N中的值分为占先优先级区次优先级区(子优先级)。将占先优先级称为组优先级。占先优先级高的可以打断占先优先级低的,可以嵌套;占先优先级相同时,看次优先级,只有同时发生时,次优先级高的先执行,不能打断,不能嵌套;当都相同时,就看异常编号,编号越小,优先级越高,同样不能嵌套。

注意:STM32F1只使用了四位来进行分组,可以分为5个组

如果八位都用,则如下:

2、向量表

上电后的向量表如下,在0x00000000处存放的是MSP的初始值,即主堆栈指针的地址,在0x00000004的地方存放着复位向量的地址(复位也可以看成一个异常,而这个异常的服务程序就是我们的主程序),每次单片机都是从复位向量开始执行,所以该地址也是PC计数器的初始值。

每个异常都定义在向量表中,每次进入异常就需要从向量表中异常的入口地址进入,如下进入异常时的具体步骤:

进入异常的过程由硬件自动完成,仅需12个时钟周期

异常退出步骤:

3、高级中断技术

末尾连锁:末尾连锁是处理器用来加速中断响应的一种机制。在结束ISR时,如果存在一个挂起中断,其优先级高于正在返回的ISR或线程,那么就会跳过出栈操作,转而将控制权让给新的ISR。 

末尾连锁,为什么会不需要压栈:

返回:在没有挂起异常或没有比被压栈的ISR优先级更高的挂起异常时,处理器执行出栈操作,并返回到被压栈的ISR或线程模式。在响应ISR之后,处理器通过出栈操作自动将处理器状态恢复为进入ISR之前的状态。如果在状态恢复过程中出现一个新的中断,并且该中断的优先级比正在返回的ISR或线程更高,则处理器放弃状态恢复操作并将新的中断作为末尾连锁来处理。 

迟来:迟来是处理器用来加速占先的一种机制。如果在保存前一个占先的状态时出现一个优先级更高的中断,则处理器转去处理优先级更高的中断,开始该中断的取向量操作。状态保存不会受到迟来的影响。因为被保存的状态对于两个中断都是一样的,状态保存继续执行不会被打断。处理器对迟来中断进行管理,直到ISR的第一条指令进入处理器流水线的执行阶段。返回时,采用常规的末尾连锁技术。 


七、复位序列和启动

        在离开复位状态后,CM3
做的第一件事就是读取下列两个
32
位(前两个字)整数的值:

从地址 0x0000,0000 处取出 MSP 的初始值。

从地址 0x0000,0004 处取出 PC 的初始值——这个值是复位向量,LSB 必须是 1。然后从这个值所对应的地址处取指
(复位其实也可以理解为一个异常,而复位程序就是我们的主程序)

 
注意:
这与传统的 ARM
架构不同——其实也和绝大多数的其它单片机不同。传统的ARM 架构总是从
0
地址开始执行第一条指令。它们的
0
地址处总是一条跳转指令。在
CM3中,0
地址处提供
MSP
的初始值,然后就是向量表(向量表在以后还可以被移至其它位置)。向量表中的数值是 32
位的地址,而不是跳转指令。向量表的第一个条目指向复位后应执行的第一条指令。

        STM32F1系列单片机上有三块可以用于启动的存储器的物理地址,但是由Boot引脚决定。如下:

1、片上SRAM起始地址:0x20000000;

2、片上用户闪存起始地址:0x08000000;

3、片上系统闪存(bootloader)起始地址:0x1FFF0000;

具体如何启动,可以查阅这篇博客——STM32如何启动-CSDN博客。

程序执行流程:

        因为CM3
使用的是向下生长的满栈,所以
MSP
的初始值必须是
堆栈内存的末地址加 1
。举例来说,如果你的堆栈区域在 0x20007C00‐0x20007FFF
之间,那么
MSP
的初始值就必须是0x20008000。 向量表跟随在 MSP
的初始值之后——也就是第
2
个表目。要注意因为
CM3
是在
Thumb态下执行,所以向量表中的每个数值都必须把 LSB

1
(也就是奇数)。正是因为这个原因, 图
中使用
0x101
来表达地址
0x100
。当
0x100
处的指令得到执行后,就正式开始了程序的执行。在此之前初始化 MSP
是必需的,因为可能第
1
条指令还没执行就会被
NMI
或是其它 fault
打断。
MSP
初始化好后就已经为它们的服务例程准备好了堆栈。对于不同的开发工具,需要使用不同的格式来设置 MSP
初值和复位向量——有些则由开发工具自行计算。


完结

本文内容较多,且比较杂,无法再进行详写,有疑问或者是遇到陌生名词就多查查吧。

可以在Cortex M3权威指南上学习,上面内容详尽

有误之处望指正,谢谢。

物联沃分享整理
物联沃-IOTWORD物联网 » 深入了解STM32内核架构——Cortex M3

发表评论