选择最适处理器核心架构 嵌入式应用提高性价比
备份暂存器
本文引用地址:https://www.eepw.com.cn/article/201605/291453.htm图5显示ARMv7-M和AArch32的备份暂存器。可看出,许多暂存器为共有,因为这两种架构均是沿袭自ARMv6及先前的架构。

图5 ARMv7-M登录集
多数指令可存取十三个通用型的暂存器r0-r12。在这两种架构中,r13保留为Stack Pointer(SP),r14保留为Link Register(LR),r15则保留为Program Counter(PC)。在ARMv7-M中,这些特殊暂存器的存取仅限于某些反映这些暂存器功能的特定使用状况;在AArch32中,这些暂存器的存取则类似任何其他通用的暂存器(虽然变更Program Counter的数值可能造成非预期的副作用)。
ARMv7-M指定小部分额外特殊用途的暂存器PRIMASK、FAULTMASK、xPSR、CONTROL和BASEPRI,用于控制及设定处理器,及用于管理异常处理。
指令集
图5与图6分别是ARMv7-M与AArch32登录集,两相比较可看出AArch32也提供许多与特定作业模式关联的暂存器。这些暂存器会在进入相关的模式时与其在User模式下的暂存器交换。除了少数特殊指令,其他指令均无法存取这些暂存器,但也无法直接存取。其数值在模式变更时亦会保留,有助于处理异常。每个异常模式皆有自己的专属SP,每个异常均可在独立的堆叠上处理,因此异常处理的程式设计更为稳固且安全。取得异常时,相关模式下的LR设定为异常传回位址。

图6 AArch32登录集
每个异常模式下会出现的还有叫SPSR的额外暂存器。SPSR用于在进入例外时取得目前CPSR数值的快照,搭配LR使用下,可提供自动化的内容储存。
AArch32图中未显示Mon和Hyp模式,其各自支援备份暂存器的R13和R14,如同其他的模式。
在Cortex-A中,另有一个与ARM NEON SIMD指令集(如下所述)相关的备份暂存器,共包含三十二个128位元宽度的暂存器。每个暂存器均可定址为字组、双字组或四字组,且NEON指令集从位元组到四字组均支援向量作业。
异常模式
这两个架构的异常模式有相当大的差异,两者均支援内部与外部异常,可由系统事件或外部周边中断所执行。
ARMv7-M支援与传统微控制器极为类似的模型,所有外部中断分别透过包含处理常式位址的向量表来向量。
AArch32支援的模型则类似旧型ARM架构,当中只有八个有独立向量的异常类型。向量表包含可执行的指令,其通常为直接连往合适的异常处理常式的分支指令。仅支援两个外部中断来源:FIQ和IRQ。一般只会有一个高优先的中断连接至FIQ,其余则连接至IRQ。亦即系统必须整合软体分配器,或如同现代化系统所常见的,包含可用个别向量位址进行程式设计的Vectored Interrupt Controller(VIC)。
许多Cortex-A系统包含采用ARM之Generic Interrupt Controller(GIC)架构的标准中断控制器。GIC可作为许多实体中断和ARM核心的两个中断输入(FIQ和IRQ)之间的介面。其可处理优先顺序的决定、遮掩、个别中断启用/停用和抢夺。
指令集
ARM指令集自25年前在ARM1首次推出后已经过许多演进。Cortex-A处理器实际上支援两个指令集,每个指令集均有许多延伸。
.ARM指令集
ARM指令集以第一个ARM处理器所支援的原始指令集为基础,但已经过多次延伸。其为load-store指令集,内含独立指令群组,可用于资料处理、记忆体存取、系统控制及控制流量。现代的ARM指令集具有高效能,且范围广泛。此指令集中的所有指令均以固定长度的32位元字组编码,且字组边界必须对齐。
.Thumb指令集
Thumb指令集为ARM指令集的子集,其中每个指令均编码为16位元的半字组,其半字组边界必须对齐。Thumb指令集的原始概念是为了在编译C之类的高阶语言时,缩小最常用指令的大小,藉此改善程式码的密度。指令缩小后,由于指定的快取行内可放入更多指令,因此也有助于从指令快取内执行。
.进阶SIMD延伸集
进阶SIMD延伸集(Advanced SIMD Extensions)亦称为NEON,是大型的指令集,可利用延伸暂存器组合提供SIMD向量处理功能。
.向量浮点(VFP)
VFP指令集在与NEON相同的备份暂存器上执行,其可提供高效能的IEEE-754相容单一与双重精准浮点作业。
.Thumb-2技术
Thumb-2为延伸集的名称,在ARMv6T2(首先出现在ARM1156T2-S处理器)加入到Thumb指令集内。其为混合长度的指令集,结合Thumb的程式码密度与ARM指令集的较高效能与弹性。
假如使用者已利用Cortex-M微控制器进行开发,应该会对Thumb-2很熟悉。这些程式码在从最小(Cortex-M0和Cortex-M0+)到最大(Cortex-M7)的各种子集中仅支援Thumb-2。转移到Cortex-A处理器,能为程式码生成开启许多可能性。
一般来说,多数针对Cortex-A处理器编译的高阶程式码将以Thumb(含Thumb-2)为目标。因此编译人员可获得最大的自由,在有多重选择下合理选择所要使用的指令,在针对程式码空间进行编译与针对效能进行编译两种情况下实现最高的差异。
ARM指令集通常用于必须要达到最高效能的程式码区段。这些区段有时可在组译器内手动编码,而ARM指令集通常会是最好的选择。
NEON指令集可用下列多种方式存取:
.有程式库支援常见的数学与分析功能及演算法。
.编译器支援完整的内部功能集,允许从C直接存取完整的NEON指令集。透过这种方法,NEON作业便能以最便利的方式与C程式码交错处理。
.NEON可直接在组译器内手动执行。
.编译器亦支援反覆回路的自动向量。只要遵循一些简单的指示来编写程式码,即使是稍显复杂的回路,编译器也能有效执行及向量化。
如果使用者熟悉ARMv7-A处理器,应该也会注意到ARMv8-A加入一些额外的指令。
.密码编译延伸模组(Cryptographic Extensions)
这些指令为ARMv8-A新加入,目的是为了有效实作常见的加密功能建构区块演算法。这些延伸是在NEON备份暂存器上运作。
.Load-Acquire和Store-Release
这些新指令符合C++11记忆体排序语法,能提升编译效率。也可用来减少对资料侧记忆体局限的需求,并部分减少与其相关的工作量。
还有一些其他与浮点和限制指令有关的小型延伸。
虚拟记忆体支援
支援完整虚拟记忆体环境为ARMv8-A主要功能之一,正是透过这项功能,这些装置才能支援Linux和Android等平台作业系统。因此,虚拟记忆体功能经常也是在这些核心中进行选择时最为关键的条件。
虚拟记忆体环境可让作业系统管理记忆体时更富弹性,像是使个别处理程序动态延伸堆叠区,启用个别的程式码,让资料区能视需要在外部储存空间内部和外部进行分页,让个别的使用者处理程序可以检视完全相同的系统记忆体配置图。
为发挥作用,虚拟记忆体在处理器所配发的每个位址上加入了“转译”,如图7所示。软体会在“虚拟位址空间”执行,还有一个名为记忆体管理单元的区块会将其转译为实体位址空间。

图7 虚拟记忆体
为了使作业系统完整控制存取权限等内容,以针对系统内的各项使用者工作及作业系统本身建立新的虚拟记忆体配置图。每项工作可当作系统内唯一的工作,在自己的虚拟记忆体空间内执行。只有作业系统知道工作程式码及资料区在外部实体记忆体内的实体位置。
在切换工作时,作业系统的其中一项任务就是重新设定记忆体管理单元,以启用传入工作所用的程式码及资料,同时让传出工作的记忆体暂时无法存取。如此可强制区分工作,为安全且弹性的系统的必要元素。
此处不会提供完整说明,ARM处理器内的记忆体管理单元使用保留在外部记忆体中的“分页表”所含的资料来带动及控制转译。系统整合多项最佳化作业(例如,包含Translation Lookaside Buffers,或简称为TLB,能为最近使用过的转译建立快取,以减少读取分页表的工作量),可尽量缩小转译处理程序的工作量。
从ARMv7-M到ARMv7-A的软体转移
多数的高阶软体皆须要简单的重新编译。下列区域的软体则须详加注意:
.重置程式码及其他例外处理常式
如果使用作业系统,这部分的工作将由作业系统所提供的工具来处理。多数情况下,常见作业系统的连接埠将透过公开网域散布或装置供应商提供。
因异常模式差异较大,因此须重新写入中断处理常式。作业系统同样会提供基础架构来完成这部分工作,藉以简单地重新编译多数中断处理常式的主体。
.周边驱动程式
从RTOS转移到Linux这类的多功能平台作业系统时,应用程式码及周边驱动程式须更明确地加以区隔。
.系统组态功能
采用Cortex-M与Cortex-A的装置在提供系统组态与控制功能存取方面有较大的差异。Cortex-M处理器通常透过具名或记忆体对映的暂存器来设定,可直接读取及写入,以达成所要的功能。Cortex-A处理器(为Cortex-A32所支援的AArch32执行状态)则是透过“系统控制协同处理器”来支援设定。概念性的“协同处理器15”包含大量的设定暂存器集,使用专属的指令进行读取及写入。非由作业系统执行的系统组态功能则须重新写入,以完成这部分的工作。也就是说,作业系统通常会提供应用程式介面(API),以用于须要由使用者介面存取的功能。
.汇编程式码
很明显地,汇编程式码也须特别注意。因为写入汇编程式码的其中一个主要原因,便是为了获得最高的效能,因此必须详加检验这些功能,确定重新写入能在存取NEON等某些延伸指令集功能时提供好处。若旧型的汇编程式码已使用“Uniform Assembler Language(UAL)”语法写入,则多数程式码将简单地重新汇编为ARM或Thumb指令。
评论