1. Thumb-2
ARM处理器提供了32位指令集,这提供了丰富的指令集,还保证了在涉及算术操作和内核寄存器与SRAM之间的内存传输的指令执行过程中获得最佳性能。32位指令集在固件的存储空间方面具有一定的成本。使用32位指令集架构(ISA)需要更多的闪存存储字节,这对功耗和微控制器的整体成本产生影响(硅晶圆的成本很高,制造商不断缩小芯片尺寸以降低成本)。
为解决上述问题,ARM引入了Thumb 16位指令集,这是最常用的32位指令集的子集。Thumb指令每个都是16位长,并会自动“转换”为具有相同效果的32位ARM指令,这意味着从开发者的角度来看,16位Thumb指令会实时透明地扩展为完整的32位ARM指令,而不会降低性能。Thumb代码通常只有ARM代码大小的65%,在从16位存储系统运行时提供了后者的160%性能;然而,在Thumb中,16位操作码的功能较少。例如,只有分支指令可以是有条件的,而且许多操作码仅限于访问CPU通用寄存器的一半。后来,ARM引入了Thumb-2指令集,这是一个操作状态中混合了16位和32位指令集的变长指令集,相对于Thumb,Thumb-2提供了更多的指令,实现了类似的代码密度。
(Cortex-M3、Cortex-M4和Cortex-M7可以支持完整的Thumb和Thumb-2指令集,(Cortex-M4/7)还支持用于浮点操作和单指令多数据(SIMD)操作(也被称为NEON指令)的其他指令集)
2. 内存对齐
Cortex-M3/Cortex-M4/Cortex-M7核心的另一个功能是能够对非对齐内存进行访问。一般来说,基于ARM的CPU能够访问字节(8位)、半字(16位)和字(32位)的有符号和无符号变量,而不需要增加汇编指令的数量。然而,早期的ARM体系结构无法执行非对齐内存访问,导致浪费了内存位置。
在Cortex-M3/4/7核心中,这个问题得到了解决,它们具有处理非对齐内存访问的能力。这意味着它们可以有效地处理不是以自然字长(32位)对齐的内存位置,这有助于更好地利用内存并提高内存访问的效率。这对于处理各种数据结构和格式的应用非常有用,特别是在嵌入式系统中,通常需要高度的内存效率和数据灵活性。因此,这是Cortex-M3/4/7核心的一项重要特性,有助于提高它们在广泛的应用中的灵活性和性能。
对于没有内存对齐的word,必须要从最开始进行访问,比如word的起始地址为0x20000000, 如果你访问0x20000002,会引发UsageFaults异常。如果进行了内存对齐,就可以将变量存放在0x20000002,然后进行访问。
左边是进行了内存对齐的,右边是没有进行内存对齐的,可以看到,节省了4字节空间。
然而,未对齐访问仅限于以下 ARM 指令:
- LDR, LDRT
- LDRH, LDRHT
- LDRSH, LDRSHT
- STR, STRT
- STRH, STRHT
1. Aligned(对齐的):
- 当数据或对象在内存中的地址是其大小的倍数时,称其为对齐的。
- 例如,如果一个系统使用4字节对齐,则任何4字节大小的数据类型(如`int`或`float`)都应该存储在4字节倍数的地址上。
- 对齐的数据访问可以提高内存访问效率,因为许多处理器和总线系统都是设计为从对齐的地址读取数据以提高性能。
- 对齐还有助于避免数据在内存中的碎片化,这可以提高内存管理的效率。
2. Unaligned(未对齐的):
- 如果数据或对象的地址不是其大小的倍数,则称其为未对齐的。
- 未对齐的数据访问可能会导致性能下降,因为处理器可能需要执行额外的工作来处理跨多个内存地址的数据。
- 在某些体系结构中,未对齐的访问可能会触发异常或错误,要求程序进行特殊的处理。
在嵌入式系统或性能敏感的应用中,数据对齐是一个重要的考虑因素,因为它可以显著影响程序的执行速度和效率。程序员通常需要确保数据结构和变量的声明方式能够满足特定硬件的对齐要求。
3. 流水线技术
CPU在进行指令处理的时候,就会涉及到取指令,解指令,执行三个操作。为了加快这个过程,现代CPU引入了一种方法来并行化这些操作,以增加它们的指令吞吐量(在单位时间内可以执行的指令数量)。基本的指令周期被分成一系列步骤,就像指令沿着一个流水线传输一样。与其依次处理每个指令(一个接一个地完成一个指令,然后开始下一个),每个指令被分成一系列阶段,以便不同的步骤可以并行执行。比如一个三级的流水线
所有基于Cortex-M的微控制器都引入了一种流水线处理形式。最常见的是3级流水线,如上图所示。3级流水线得到了Cortex-M0/3/4的支持。Cortex-M0+核心专门用于低功耗MCU,提供了一个2级流水线(尽管流水线有助于减少与指令的获取/解码/执行周期相关的时间成本,但它引入了一个必须在低功耗应用中最小化的能量成本)。Cortex-M7核心提供了一个6级流水线。不同级别的流水线处理有助于提高指令吞吐量,但也需要权衡能量消耗,特别是在低功耗应用中需要尽量减小功耗。
这种流水线式的处理,分支成为了一个问题。分支会导致流水线流失效,为了尽量减少这种问题,现代处理器通常采取各种技术,比如分支预测(branch prediction)和流水线刷新(pipeline flush),以最大程度地提高分支操作的效率。
4. 中断和异常处理
中断和异常是异步事件,可以改变程序的执行流程。当发生异常或中断时,CPU会暂停当前任务的执行,保存其上下文(即,堆栈指针),然后开始执行一个专门设计用来处理中断事件的例程。在异常的情况下,这个例程被称为异常处理程序(Exception Handler),而在中断的情况下,它被称为中断服务例程(Interrupt Service Routine,ISR)。在处理完异常或中断后,CPU会恢复之前的执行流程,之前的任务可以继续执行。
中断是异常的一种类型。中断通常来自芯片上的外设(例如,定时器)或外部输入(例如,连接到GPIO的触摸开关),在某些情况下,它们也可以由软件触发。相比之下,异常与软件执行有关,CPU本身也可以是异常的来源。这些异常可能是诸如尝试访问无效内存位置之类的错误事件,或者是由操作系统(如果有的话)生成的事件。每个异常(因此也包括中断)都有一个唯一标识它的编号。
不同的中断和异常有不同的编号,用于区分它们的类型。当一个中断或异常发生时,处理器会根据其编号跳转到相应的中断服务例程(ISR)或异常处理程序(Exception Handler)。这些例程负责处理中断或异常,并且在处理完毕后,处理器会返回到之前的执行流程。
在Cortex-M中,有一些预定义的异常,它们对所有Cortex-M都是通用的,以及一些与中断管理相关的用户定义的异常。这个数反映了异常处理程序在向量表中的位置,实际的异常地址存储在其中。例如,15包含了用于处理SysTick中断的异常处理程序的代码区域的内存地址,当SysTick定时器倒计时到零时会生成这个中断。除了前三个(Reset、NMI、HardFault)以外,每个异常都可以分配一个优先级级别,这定义了在并发中断的情况下处理的顺序:数字越低,优先级越高。
向量表是一个存储这些中断处理程序地址的表,处理器会根据中断编号从向量表中找到相应的处理程序地址,以执行中断服务。
异常和中断都由专用单元称为嵌套向量中断控制器(NVIC)进行处理。 NVIC的一个特性是中断处理的确定性延迟,对于所有Cortex-M3/4为12个周期,对于Cortex-M0为15个周期,对于Cortex-M0+为16个周期,无论处理器的当前状态如何。、
5. SysTimer(系统定时器)
STM32都提供了SysTick,SysTick是一个24位的递减计时器,用于为类似FreeRTOS的实时操作系统(RTOS)提供系统滴答。它用于生成定期中断以执行计划的任务。可以通过设置其寄存器来定义SysTick计时器的更新频率。即使我们不使用RTOS,STM32 HAL也使用SysTick计时器来生成精确的延迟。
6. 电源模式
Cortex-M处理器提供了多个级别的电源管理,可以分为两个主要组:固有特性和用户定义的电源模式。固有特性是指在Cortex-M核心和整个微控制器(MCU)的设计过程中定义的与功耗相关的本机能力。例如,Cortex-M0+核心仅定义了两个流水线阶段,以降低在指令预取期间的功耗。与电源管理相关的另一个本机行为是Thumb-2指令集的高代码密度,它使开发人员可以选择具有较小闪存存储器的MCU,以降低功耗需求。
Cortex-M处理器通过系统控制寄存器(SCR)提供用户定义的电源模式。第一个模式是运行模式,在这个模式下,CPU以其全部性能运行。在运行模式下,功耗取决于时钟频率和使用的外围设备。第二个模式是睡眠模式,用于降低功耗。当激活时,大多数功能被暂停,CPU频率降低,其活动被减少到唤醒所必需的活动。第三个模式是深度睡眠模式,所有时钟信号都被停止,CPU需要外部事件才能从这种状态中唤醒。
(STM32Lx系列提供了几个中间功耗级别,允许精确选择首选的电源模式,从而选择MCU的性能和功耗。)
7. TrustZone
ARM最近推出了两个新的Cortex-M处理器内核,命名为Cortex-M23和Cortex-M33,都基于ARMv8-M体系结构。这些新内核继承了已经存在于大多数Cortex-A处理器上的一个特性:ARM TrustZon。TrustZone是一个可选的安全扩展,旨在为各种嵌入式应用中的系统安全提供基础。处理器可以在安全和非安全状态下运行,非安全软件只能访问非安全内存区域。通过调整内存映射配置,可以定义内存地址空间的区域,在这些区域中只有在处理器运行在安全模式下才能访问该区域(无论是执行代码还是访问数据)。ARM TrustZone技术使系统和软件可以划分为安全世界和普通世界。安全软件可以访问安全和非安全内存以及硬件资源,而普通软件只能访问非安全内存和资源。这些安全状态与现有的线程和处理器模式是正交的,使安全和非安全状态下都能同时启用线程和处理器模式。
TrustZone技术并不涵盖安全的所有方面。例如,它不包括加密。在具有ARMv8-M架构和TrustZone的设计中,对系统安全至关重要的组件可以放置在安全世界中。例如,这些关键组件可能包括:
- A Secure boot loader
- Secret keys
- Secret keys
- High value assets
通常,其余的应用程序会放置在普通世界中。这种区分允许将敏感的安全元素与一般应用程序分开,提供更高级别的安全性,以保护关键数据和操作。
8. Cortex-M特性选择
这些提到的一些功能是可选的,在一些MCU中不可用。