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

ARM Cortex-M3/M4 权威指南 笔记【二】架构

一、架构

1.1 架构简介

Cortex-M3/M4 处理器都基于 ARMv7-M 架构。最初的 ARMv7-M 架构是随着 Cortex-M3 处理器一同引入的,而在 Cortex-M4 发布时,架构中又额外增加了新的指令和特性,改进后的架构有时也被称为 ARMV7E-M。要了解 ARM7-M 和 ARMV7E-M 的特性。

二、编程模型

2.1 操作模式和状态

Cortex-M3/M4 处理器有两种操作状态和两个模式。另外,处理器还可以区分特权和非特权访问等级,特区访问等级可以处理器所有的资源,而非特权访问等级意味着有些储存器区域是不能访问的,有些操作也是无法使用的。

2.1.1 操作状态

调试状态:当处理器被暂停后(例如,通过调试器或断点触发后),就会进入调试状态并停止指令运行。

Thumb 状态:若处理器正在执行程序代码(Thumb指令),他就会处于 Thumb 状态。

2.1.2 操作模式

处理模式:执行中断服务程序(ISR)等异常处理。在处理模式下,处理器总是具有特权访问等级。

线程模式:在执行普通的应用程序代码时,处理器可以处于特权访问等级,也可以处于非特权访问等级。实际的访问等级由特殊寄存器 control 控制。

三、寄存器

与其他几乎所有的处理器类似,Cortex-M3/M4 处理器在处理器内核中都有多个执行数据处理和控制的寄存器,这些寄存器大都以寄存器组的形式进行了分组。每个数据处理指令都指定了所需的操作和源寄存器,而且若需要,还有目的寄存器。

对于ARM 架构,若处理的是存储器中的数据,就需要将其从存储器加载到寄存器组中的寄存器里。在处理器内处理完后,若有必要,还要写回存储器,这种方式一般被称作“加载一存储架构”。由于寄存器组中有丰富的寄存器,这种设计使用起来非常方便,而且可以用 C 编译器生成高效的程序代码。例如,在进行其他的数据处理时,寄存器组中可以临时存储一些数据变量,而无须更新到系统存储器及在使用时将它们读回。

Cortex-M3/M4 处理器的寄存器组中有 16 个寄存器,其中 13 个为 32 位通用目的寄存器,其他 3 个则有特殊用途。

3.1 R0~R12 寄存器

寄存器 R0~R12 为通用目的寄存器,前 8 个 (R0~R7) 也被称作低寄存器。

由于指令中可用的空间有限,许多 16 位指令只能访问低寄存器。高寄存器 (R8~R12) 则可以用于 32 位指令和几个 16 位指令,如 MOV(move)。R0~R12 的初始值是未定义的。

3.2 R13 栈指针 (SP)

R13 为栈指针,可通过 push 和 pop 操作实现栈存储的访问。

物理上存在两个栈指针:

  • 主栈指针(MSP):为默认的栈指针,在复位后或处理器处于处理模式时,其会被处理器选择使用。
  • 进程栈指针(PSP):栈指针,其只能用于线程模式。

栈指针的选择由特殊寄存器 control 决定,对于一般的程序,这两个寄存器只会有一个可见。MSP 和 PSP 都是 32 位的,不过指针(MSP 或 PSP)的最低两位总是为 0,对这两位的写操作不起作用。对于 ARMCortex-M 处理器,push 和 pop 总是 32 位的,栈操作的地址也必须对齐到 32 位的字边界上。

大多情况下,若应用不需要嵌入式 OS,PSP 也没必要使用。许多简单的应用可以完全依赖于MSP,一般在用到嵌入式 OS 时才会使用 PSP。此时 OS 内核同应用任务的栈是相互独立的。PSP 的初始值未定义,而 MSP 的初始值则需要在复位流程中从存储器的第一个字中取出。

3.3 R14 链接寄存器 (LR)

R14 也被称作链接寄存器 (LR),用于函数或子程序调用时返回地址的保存。

在函数或子程序结束时,程序控制可以通过将 LR 的数值加载程序计数器 (PC) 中返回调用程序处并继续执行。当执行了函数或子程序调用后,LR 的数值会自动更新。若某函数需要调用另外一个函数或子程序,则它需要首先将 LR 的数值保存在栈中,否则,当执行了函数调用后,LR 的当前值会丢失。

在异常处理期间,IR 也会被自动更新为特殊的 EXCRETURN(异常返回)数值,之后该数值会在异常处理结束时触发异常返回。尽管 Cortex-M 处理器中的返回地址数值总是偶数(由于指令会对齐到半字地址上,因此,第 0 位为 0),LR 的第 0 位为可读可写的,有些跳转/调用操作需要将 LR (或正使用的任何寄存器)的第 0 位置 1 以表示 Thumb 状态。

3.4 R15 程序计数器 (PC)

R15 为程序计数器(PC),是可读可写的,读操作返回当前指令地址加 4,写 PC(例如,使用数据传输/处理指令)会引起跳转操作。

由于指令必须要对齐到半字或字地址,PC 的最低位(ISB)为 0。不过,在使用一些跳转/读存储器指令更新 PC 时,需要将新 PC 值的 LSB 置 1 以表示 Thumb 状态,否则就会由于试图使用不支持的 ARM 指令(如 ARM7TDMI 中的 32 位 ARM 指令)而触发错误异常。对于高级编程语言(包括C和C++),编译器会自动将跳转目标的 LSB 置位。多数情况下,跳转和调用由专门的指令实现,利用数据处理指令更新PC的情况较为少见。

多数情况下,跳转和调用由专门的指令实现,利用数据处理指令更新PC的情况较为少见。不过,在访问位于程序存储器中的字符数据时,PC的数值非常有用,因此,会经常发现存储器读操作将 PC 作为基地址寄存器,而地址偏移则由指令中的立即数生成。

3.5 程序中使用的寄存器名

对于多数汇编工具,在访问寄存器组中的寄存器时可以使用多种名称。在一些汇编工具中,如 ARM 汇编(被 DS-5 Professional和Keil MDK-ARM 支持),可以使用大写、小写或者大小写混合。

3.6 特殊寄存器

除了寄存器组中的寄存器外,处理器中还存在多个特殊寄存器,这些寄存器表示处理器状态、定义了操作状态和中断/异常屏蔽。在使用 C 等高级编程语言开发简单的应用时,需要访问这些寄存器的情形不多。不过,在开发嵌入式 OS 或需要高级中断屏蔽特性时,就要访问它们。

特殊寄存器未经过存储器映射,可以使用 MSR 和 MRS 等特殊寄存器访问指令来进行访问。

MRS<reg>,<special reg> ;将特殊寄存器读入寄存器
MSR<special reg>,<reg> ;写入特殊寄存器

CMSIS-Core 也提供了几个用于访问特殊寄存器的 C 函数。不要把特殊寄存器和其他微控制器架构中的“特殊功能寄存器(SFR)”搞混淆了,它们一般指的是用于 I/O 控制的寄存器。 

3.6.1 程序状态寄存器

程序状态寄存器包括以下三个状态寄存器:

  • 应用 PSR(APSR)
  • 执行 PSR(EPSR)
  • 中断 PSR(IPSR)

这三个寄存器可以通过一共寄存器组访问,有些被称之为 xPSR。访问方式如下:

MRS r0, PSR    ;读组合程序状态字
MSR PSR, r0     ;写组合程序状态字

还可以单独访问每个PSR:例如:

MRS r0,APSR    ;将标志状态读入R0
MRS r0,IPSR    ;读取异常/中断状态
MSR APSR,r0    ;写标志状态

软件代码无法直接使用 MRS(读出为0) 

 

 

3.6.2 PRIMASK、FAULTMASK 和 BASEPRI 寄存器

PRIMASK、FAULTMASK 和 BASEPRI 寄存器都用于异常或中断屏蔽,每个异常(包括中断)都具有一个优先等级,数值小的优先级高,而数值大的则优先级低。这些特殊寄存器可基于优先等级屏蔽异常,只有在特权访问等级才可以对它们进行操作(非特权状态下的写操作会被忽略,而读出则会返回 0)。它们默认全部为 0,也就是屏蔽(禁止异常/中断)不起作用。

1.PRIMASK 寄存器:

为 1 位宽的中断屏蔽寄存器。在置位时,它会阻止不可屏蔽中断(NMI)和HardFault 异常之外的所有异常(包括中断)。实际上,它是将当前异常优先级提升为 0,这也是可编程异常/中断的最高优先级。

PRIMASK 最常见的用途为,在时间要求很严格的进程中禁止所有中断,在该进程完成后,需要将PRIMASK 清除以重新使能中断。

2.FAULTMASK 和 PRIMASK 寄存器:

他们非常类似,不过它还能屏蔽 HardFault 异常,它实际上是将异常优先级提升到了-1。错误处理代码可以使用 FAULTMASK 以免在错误处理期间引发其他的错误(只有几种)。例如,FAULTMASK 可用于旁路 MPU 或屏蔽总线错误(这些都是可配置的),这样,错误处理代码执行修复措施也就更加容易了。与 PRIMASK 不同 FAULTMASK 在异常返回时会被自动清除。

3.6.3 在特权状态下访问这些寄存器

待补充

3.6.5 CONTROL 寄存器

待补充

3.6.6 浮点寄存器

Cortex-M4 具有可选的浮点单元,其提供了浮点数据处理用的一些寄存器以及浮点状态和控制寄存器(FPSCR)。

1.S0~S31 和 D0~D15 寄存器

S0~S31(S) 都为 32 位寄存器,而且每个都可以通过浮点指令访问,或者利用符号 D0~D15(D 代表双字/双精度)成对访问。例如,S0 和 S1 成对组成 D0,而 S3 和 S2 则成对组成 D1。尽管Cortex-M4 中的浮点单元不支持双精度浮点运算,在传输双精度数据时仍可使用浮点指令。

2.浮点状态和控制寄存器(FPSCR)

由于下面的几个原因,FPSCR 中包含多个位域

  • 定义一些浮点运算动作。
  • 提供浮点运算结果的状态信息。

浮点控制默认被配置为符合 IEEE754 单精度运算。在普通应用中,浮点运算控制的设置也无须修改。列出了 FPSCR 的位域描述。

3.7 应用程序寄存器

3.7.1 整数状态标志

待补充

3.7.2 Q 状态标志

待补充

3.7.3 GE 位

待补充

四、储存器系统

4.1 储存器系统特性

Cortex-M3 和 Cortex-M4 处理器具有以下存储器系统特性:

4GB 线性地址空间:

通过32位寻址,ARM处理器可以访问多达4GB的存储器空间尽管许多嵌入式系统需要的存储器都不超过1MB,32位的寻址能力可以确保将来升级和扩展的可能。Cortex-M3和Cortex-M4处理器用AHBLITE总线协议提供了32位总线,利用合适的存储器接口控制器,可以将32/16/8位处理器连接到总线上。

架构定义的存储器映射:

4GB的存储器空间被划分为多个区域,用于预定义的存储器和外设,以优化处理器设计的性能。例如,Cortex-M3/M4处理器具有多个总线接口,允许对程序代码用的CODE区域的访问和对SRAM或外设区域的数据操作同时进行。

支持小端和大端的存储器系统:

Cortex-M3/M4 处理器可以使用小端或大端的存储器系统。实际上,微控制器产品一般会被设计成只具有一种端配置。位段访问(可选)。当包含位段特性时(由微控制器/片上系统供应商决定),存储器映射中的两个1MB区域可以通过两个位段区域进行位寻址,这样可以实现对SRAM或外设地址空间中单独位的原子操作。

写缓冲:

若对可缓冲存储器区域的写传输需要花费几个周期,Cortex-M3/M4 处理器内的写缓冲可能会将本次传输缓存起来,处理器可以继续执行下一条指令如果可能的话,这样可以提高程序的执行速度。

存储器保护单元(MPU):

MPU定义了各存储器区域的访问权限,且为可编程的。Cortex-M3和Cortex-M4处理器中的MPU支持8个可编程区域,可在嵌入式OS中提高系统的健壮性。

非对齐传输支持:

ARMv7-M架构的所有处理器(包括Cortex-M3和Cortex-M4处理器)都支持非对齐传输。

Cortex-M 处理器的总线接口为通用总线接口,可通过不同的存储器控制器被连接至不同类型和大小的存储器。微控制器存储器系统中的存储器一般为两种或更多:程序代码用的 Flash 存储器、数据用的静态 RAM(SRAM),有时还会有电可擦除只读存储器 (EEPROM)。大多情况下,这些存储器位于芯片内部,实际的存储器接口细节对软件开发人员是不可见的。因此,软件开发人员只需了解程序存储器和 SRAM 的地址和大小即可。

4.2 储存器映射

4.3 栈存储

同几乎所有的处理器架构一样,Cortex-M 处理器在运行时需要栈存储和栈指针(R13)在栈这种存储器使用机制中,存储器的一部分可被用作后进先出的数据存储缓冲。ARM 处理器将系统主存储器用于栈空间操作,且使用 PUSH 指令往栈中存储数据以及 POP 指令从栈中提取数据。每次PUSH 和 POP 操作后,当前使用的指针都会自动调整。

栈可用于:

  • 当正在执行的函数需要使用寄存器(寄存器组中)进行数据处理时,临时存储数据的初始值。这数据在函数结束时可以被恢复出来,以免调用函数的程序丢失数据。
  • 往函数或子程序中的信息传递。
  • 用于存储局部变量。
  • 在中断等异常产生时保存处理器状态和寄存器数值。

Cortex-M 处理器使用的栈模型被称作 “满递减”。处理器启动后,SP 被设置为栈存储空间最后的位置。对于每次 PUSH 操作,处理器首先减小 SP 的值,然后将数据存储在 SP 指向的存储器位置。在操作期间,SP 指向上一次数据被存储在栈中的位置,对于POP操作,SP指向的存储器位置的数据被读出,然后SP的数值会自动减小。PUSH和POP指令最常见的用法为,在执行函数或子程序调用时保存寄存器组中的内容。在函数调用开始时,有些寄存器的内容可以通过PUSH指令保存在栈中,而后在函数调用结束时通过POP恢复为它们的初始值。例如,中的一个名为 functionl 的简单函数/子程序被主程序调用,由于function1需要在数据处理时使用并修改R4、R5和R6,而这些

4.4 储存器保护单元(MPU)

MPU在Cortex-M3/M4 处理器中是可选的,因此并不是所有的Cortex-M3/M4 微控制器都有 MPU 特性。多数应用不会用到 MPU,因此可以忽略。在需要高可靠性的嵌人式系统中,MPU 可以通过定义特权和非特权访问权限,来保护存储器区域,MPU 是可编程的,而且Cortex-M3/M4 处理器中的 MPU 支持 8 个可编程区域。MPU 可以有多种用法。有些情况下,MPU 由嵌人式 OS 控制,每个任务都被配置了存储器访问权限;而对于其他情况,MPU 被配置为只保护某一特定存储器区域,如将某存储器区域设置为只读。

五、异常和中断

5.1 什么是异常

异常是会改变程序流的事件,当其产生时,处理器会暂停当前正在执行的任务,转而执行一段被称作异常处理的程序。在异常处理执行完后,处理器会继续正常地程序执行。对于ARM架构,中断就是异常的一种,它一般由外设或外部输入产生,有时也可以由软件触发。中断的异常处理也被称作中断服务程序(ISR)。

NVIC 处理异常。NVIC 可以处理多个中断请求(IRQ)和一个不可屏蔽中断(NMI)请求,IRQ 一般由片上外设或外部中断输入通过 I/O 端口产生,NMI 可用于看门狗定时器或掉电检测(一种电压监视单元,在电压低到一定程度时会给处理器产生警告)。处理器内部也有名为 SysTick 的定时器,它可以产生周期性的定时中断请求,可用于嵌人式 OS 计时或没有 OS 的应用中的简单定时控制。
处理器自身也是一个异常事件源,其中包括表示系统错误状态的错误事件以及软件产生、支持嵌入式 OS 操作的异常。

异常编号CMSIS 中断编号异常类型优先级功能
1复位—3
2—14NMI—2
3—13硬件错误—1
4—12MemManage 错误可设置
5—11总线错误可设置
6—10使用错误可设置
7-10
11—5SVC可设置
12—4调试错误可设置
13
14—2PendSV可设置
15—1SYSTICK可设置
16~2550~239IRQ可设置

每个异常源都有一个异常编号,编号 1~15 被归为系统异常,16 号及其之上的则用于中断。Cortex-M3/M4 处理器在设计上支持最多 240 个中断输人,不过实际实现的中断数量要小得多,一般在16~100 之间,这样可以减小硅片面积,同时也会降低功耗。

异常编号在多个寄存器中都有所体现,其中包括用于确定异常向量地址的 IPSR。异常向量存储在向量表中,在异常入口流程中,处理器会读取这个表格以确定异常处理的起始地址。注意,异常编号的定义和 CMSIS 的设备驱动库中的中断编号定义不同。在 CMSIS 的设备驱动库中,中断编号从 0开始,系统异常编号则为负值。

与ARM7TDMI 等经典 ARM 处理器相比,Cortex-M 处理器中没有 FIQ(快速中断)。不过,Cortex-M3/M4 的中断等待非常小,只有 12 个周期,因此这也不会引起什么问题。

复位是一种特殊的异常,当处理器从复位中退出时,就会在线程模式(而不是其他异常时的处理模式)下执行复位处理。IPSR 中的异常编号读出也是 0。

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

NVIC 为 Cortex-M 处理器的一部分,它是可编程的,且寄存器位于存储器映射的系统控制空间(SCS)NVIC处理异常和中断配置、优先级以及中断屏蔽。NVIC具有以下特性:

  • 灵活的异常和中断管理
  • 支持嵌套异常/中断
  • 向量化的异常/中断入口
  • 中断屏蔽

1.灵活的中断和异常:

管理每个中断(除了NMI)都可以被使能或禁止而且都具有可由软件设置或清除的挂起状态

NVIC 可以处理多种类型的中断源:

  • 脉冲中断请求:中断请求至少持续一个时钟周期,当 NVIC 在某中断输入收到一个脉冲时,挂起状态就会置位且保持到中断得到处理。
  • 电平触发中断请求:在中断得到处理前需要将中断源的请求保持为高。

NVIC 输人信号为高有效。不过,实际微控制器中的外部中断输人的设计可能会有所不同,会被片上系统逻辑转换为有效的高电平信号。

2.嵌套向量/中断支持:

每个异常都有一个优先级,中断等一些异常具有可编程的优先级,而其他的则可能会有固定的优先级。当异常产生时,NVIC 会将异常的优先级和当前等级相比较,若新异常的优先级较高,当前正在执行的任务就会暂停,有些寄存器则会被保存在栈空间,而且处理器会开始执行新异常的异常处理,这个过程叫作"抢占”。当更高优先级的异常处理完成后,它就会被异常返回操作终止,处理器自动从栈中恢复寄存器内容,并且继续执行之前的任务。利用这种机制,异常服务嵌套不会带来任何软件开销。

3.向量化的异常/中断入口:

当异常发生时,处理器需要确定相应的异常处理入口的位置。对于 ARM7TDMI 等 ARM 处理器,这一操作由软件实现,Cortex-M 处理器则会从存储器的向量表中自动定位异常处理的入口。因此,这样也降低了从异常产生到异常处理执行间的延时。

4.中断屏蔽:

Cortex-M3/M4 处理器中的 NVIC 提供了多个中断屏蔽寄存器,如 PRIMASK 特殊寄存器。利用PRIMASK 寄存器,可以禁止除 HardFault 和 NMI 外的所有异常。这种屏蔽对不应被中断的操作非常有用,如时序关键控制任务或实时多媒体编解码器。另外,还可以使用 BASEPRI 寄存器来选择屏蔽低于特定优先级的异常或中断。CMSIS-Core 提供了一组可以很方便访问各种中断控制功能的函数。NVIC 的灵活性和能力还使得 Cortex-M 处理器非常易于使用,而且通过降低中断处理的软件开销,在减小了代码体积的同时,还提高了系统的响应速度。

5.3 向量表

当异常事件产生且被处理器内核接受后,相应的异常处理就会执行。要确定异常处理的起始地址,处理器利用了一种向量表机制。向量表为系统存储器内的字数据数组,每个元素都代表一个异常类型的起始地址。向量表是可以重定位的,重定位由 NVIC 中名为向量表偏移寄存器(VTOR)的可编程寄存器控制。复位后,VTOR 默认为 0,向量表则位于地址 0x0 处。

例如:若复位为异常类型 1,则复位向量的地址为 1X4(每个字为4字节),也就是0x00000004;NMI 向量(类型2)则是位于 2X4=0x00000008。地址0x00000000处存放的是MSP的初始值。

每个异常向量的最低位表示异常是否在 Thumb 状态下执行,由于Cortex-M 处理器只支持 Thumb指令,因此,所有异常向量的最低位都应该为 1。

5.4 错误处理

Cortex-M3/M4 处理器中有几个异常为错误处理异常。处理器检测到错误时就会触发错误异常,检测到的错误包括执行未定义的指令以及总线错误对存储器访问返回错误的响应等。错误异常机制使得错误可以被快速发现,软件因此也可以执行相应的修复措施。

总线错误、使用错误以及存储器管理错误默认都是禁止的,且所有的错误事件都会触发 HardFault异常。不过,这些配置都是可编程的,可以单独使能这三个错误异常,以处理不同类型的错误。HardFault 异常总是使能的。错误异常也可在软件调试时使用。例如,在错误产生时,错误异常可以自动收集信息及通知用户或其他系统错误已产生,并能够提供调试信息。Cortex-M3/M4 处理器中有多个可用的错误状态寄存器,它们提供了错误源等信息。开发人员可以在软件开发过程中利用调试器检查这些错误状态寄存器。

六、系统控制块(SCB)

SCB 为处理器的一部分,位于 NVIC 中。SCB 包含寄存器,用于:

  • 控制处理器配置(如低功耗模式)
  • 提供错误状态信息(错误状态寄存器)
  • 向量表重定位(VTOR)

SCB 经过了存储器映射与 NVIC 寄存器类似,SCB 寄存器可以从系统控制空间(SCS)访问。

七、调试

由于软件越来越复杂,调试特性在现代处理器架构中也变得越来越重要。尽管设计非常紧凑,Cortex-M3/M4 处理器中包含了多种经过精心设计的调试特性,其中包括暂停和步进等程序执行控制、指令断点、数据监视点、寄存器和存储器访问、概况及跟踪等。

Cortex-M 处理器提供了两种接口:调试和跟踪。利用调试接口,调试适配器可以连接到 Cortex-M 微控制器上以控制调试特性和访问片上的存储器空间。Cortex-M 处理器支持传统的使用 4 或 5 个引脚的 JTAG 协议,以及名为串行线调试(SWD)的 2 针协议。SWD 协议由 ARM 开发。可以仅使用两个引脚实现和 JTAG 相同的调试特性,而且不会损失调试性能。许多商业调试适配器,如 Keil 的 ULINK2 或 ULINKPro 产品,都支持两种协议。这两种协议可以使用相同的接头,其中 JTAG、TCK 和串行线时钟共用 JTAG、TMS 则与串行线数据共用,数据引脚是双向的。多家公司提供的不同调试适配器都支持这两种协议。

八、复位和复位流程

对于典型的Cortex-M微控制器,复位类型共有三种:

  • 上电复位:复位微控制器中的所有部分,其中包括处理器、调试支持部件和外设等
  • 系统复位:只会复位处理器和外设,不包括处理器的调试支持部件。
  • 处理器复位:只复位处理器。

在系统调试或处理器复位操作过程中,Cortex-M3/M4 处理器中的调试部件不会复位,这样可以保持调试主机(如运行在计算机上的调试器软件)和微控制器间的连接。调试主机可以通过系统控制块(SCB)中的寄存器产生系统复位或处理器复位。

上电复位和系统复位的持续时间取决于实际的微控制器设计。有些情况下,由于复位控制器需要等待晶体振荡器等时钟源稳定下来,因此,复位要持续若干毫秒。

在复位后以及处理器开始执行程序前,Cortex-M 处理器会从存储器中读出头两个字,向量表位于存储器的开头部分,它的头两个字为主栈指针(MSP)的初始值,以及代表复位处理起始地址的复位向量。处理器读出这两个字后,就会将这些数值赋给 MSP 和程序计数器(PC)。

MSP 的设置是非常必要的,这是因为在复位的很短时间内有产生 NMI 或 HardFault 的可能,在异常处理前将处理器状态压栈时需要栈储存和 MSP。

注意:对于多数 C 开发环境,C 启动代码会在进入主程序 main() 前更新 MSP 的数值通过这两次对栈的设置,具有外部存储器的微控制器可以将外部存储器用作栈。例如,启动时栈可能位于片上SRAM,在复位处理中初始化外部存储器后执行C启动代码,此时会将栈设置为外部存储器。

ARM7TDMI 等经典的 ARM 处理器的栈初始化处理是不同的,在复位时处理器会从地址 0 处开始执行指令,栈指针必须要由软件初始化。对于经典的 ARM 处理器,向量表中为指令代码而不是地址值。

由于 Cortex-M3/M4 中的栈操作基于满递减的栈(SP在存储前减小),SP的初始值应该被设置为栈区域顶部的第一个位置。例如,若存储器区域为 0x20007C00~0x20007FFF(1KB),所示,初始的指针就应该为 0x20008000。

对于 Cortex-M 处理器,向量表中向量地址的最低位应该为 1,以表示它们为 Thumb 代码。正是由于这个原因,复位向量为 0x101,而启动代码从 0x100 处开始。在取出复位向量后,Cortex-M 处理器就可以从复位向量地址处执行程序,并开始正常操作。


http://www.kler.cn/a/544147.html

相关文章:

  • 哈希表-两个数的交集
  • 8.flask+websocket
  • Dockerfiles 的 Top 10 常见 DevOps/SRE 面试问题及答案
  • .NET Web-静态文件访问目录浏览
  • 使用 Flask 构建流式返回服务
  • Vim操作笔记
  • GitCode 助力 Dora SSR:开启游戏开发新征程
  • 4-电脑一连接上自动弹框到路由器web配置页面
  • react 创建项目报错(react19)详细解决办法
  • forwardRef
  • 朝天椒USB服务器让RPA机器人远程连接网银U盾
  • DeepSeek 的 API 服务引入 WPS Office
  • ?.、??、||分别是什么,又有哪些区别???
  • Linux部署DeepSeek r1 模型训练
  • 开启AI绘画的魔法大门!探索Stable Diffusion的无限魅力~
  • k8s之亲和性和反亲和性
  • 【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第一节】
  • UNITY计算fps时应忽略掉time.timescale的影响
  • [Linux][问题处理]修改密码报You must wait longer to change your password
  • 人生的转折点反而迷失了方向
  • 游戏内常见加密
  • Unity 卡死排查方法(游戏死循环、打包卡死)
  • python+unity落地方案实现AI 换脸融合
  • Spring 项目接入 DeepSeek,分享两种超简单的方式!
  • HTML之JavaScript函数声明
  • 【AI学习】DeepSeek-R1-Distill的意义和影响