再上一篇:17.4 开发工具
上一篇:第18章
主页
下一篇:18.3 汇编源程序
再下一篇:18.4 C 源程序
文章列表

18.2 系统的个性

《Cortex-M3 权威指南》,嵌入式处理器开发教程。

想必大家也已经总结出来了,CM3 与 ARM7 相比,还是有很多新的个性的。像固定的存储器映 射,中断处理机制,操作模式,系统控制,以及新引入了 MPU等。下面我们就一一小结。

18.2.1 存储器映射

在不同处理器架构间的差异中,存储器映射算得上是最“外向”型的了。在 ARM7 中,是由器 件厂商自由划分 4GB的寻址空间的,再加上厂商还可能玩各种“二次映射”技术,各 ARM芯片之间 的存储器映射可以是大相径庭的。到了 CM3中,把存储器映射被粗线条地标准化了——把 4GB空间 分成了若干个不同类型的区域,对应的存储器必须对号入座。一般地,通过设置编译和连接选项, 可以轻易地适应新的 ROM和 RAM的映射图。但对于设备驱动程序,则情况比较复杂。如果是不同厂 家的芯片,外设寄存器的用法基本上是完全不同的,此时驱动程序必须重写;如果是在同一厂家的 ARM7 和 CM3 芯片间移植,则外设寄存器有望相对一致,驱动程序只需部分改动,甚至简单到只修
改基地址即可。
许多 ARM7 芯片会提供存储器的“二次映射”功能,其中一个重要的用途,就是使向量表可以 被重映射到 SRAM 中。而在 CM3 中,可以通过编程 NVIC 的寄存器来实现此功能,因此不再需要这 些二次映射功能,从而许多芯片可能也去掉了完备的二次映射支持(但是可能会提供一种“硬件控 制”的二次映射——上电时,由某些管脚的电平决定把哪里的存储器映射到零地址上,以支持多种 引导方式。如 STM32就采用了此法,以支持从 Flash/SRAM/原配 BootLoader引导——译者注)。
CM3 对大端模式的支持方式也与 ARM7 的不一样。程序代码只需重新编译,但是事先做好的查 找表则需要重新编码。(大端编码是多事之地,建议读者少碰它——译者注)。
从 ARM720T,以及 ARM9等那个年代开始的处理器,为了支持像 WinCE这样的操作系统,引入 了所谓的“高端向量”功能——允许把向量表重定位到 0xFFFF_0000。CM3并没有打算支持 WinCE
(实际上最重要的原因是没有配 MMU),因此去掉了“高端向量”的支持。

18.2.2 中断/异常系统

可能 NVIC都快引起大家的审美疲劳了。没错,在 CM3中的中断处理已经被彻底改造,因此所 有与控制中断有关的代码都需要大面积更新。而且还需要为建立中断优先级和向量表添加全新的代 码。
中断返回机制也变了。这影响到了汇编代码。而且如果编译器使用指示字(directive)来支持

C程序中断服务程序的话,还需要调整指示字。

过去,对中断的使能和除能是通过修改 CPSR 的,在 CM3 中没有 CPSR,而是使用 PRIMASK 或

FAULTMASK来实现全局中断的开关。

CM3 在响应中断时,启用了一个自动栈操作的机制,因此可以把旧时的入栈和出栈指令化简。 然而,旧时的ARM还有所谓的FIQ,并且为FIQ服务例程专开了小灶——独立的4个寄存器(R8-R11), 专为 FIQ 服务例程使用,无需 push/pop。FIQ 其实极少利用,成了“彩色糖衣包装却没营养的药 药”。在 CM3中并没有 FIQ的概念,因此在移植以前的 FIQ服务例程时,在代码上必须把它当作普 通的中断服务例程处理——其实因为CM3有自动堆栈操作,普通中断也相当于享有FIQ的小灶待遇。 另一方面,通过提升其优先级到最高,可以使它在时间上得到 FIQ的待遇。
实现嵌套中断的代码现在可以去掉了,因为 CM3的 NVIC已经内部实现了中断嵌套。 错误处理机制也大有不同。旧时的 ARM只有 DAbt, IAbt, Undef这 3种异常模式对应错误处
理,而到了CM3中,提供了很多fault状态寄存器来确定各种faults,而且还定义了许多新的fault 类型,其中最有新意的就是堆栈操作 faults、存储器管理 faults以及硬 fault了。因此,fault 服务例程需要重新设计。

18.2.3 MPU

MPU是 CM3中的新鲜血液,因此需要新的程序代码来使用它。另一方面,因为在 ARM7TDMI中 没有 MPU,因此这方面没有“代码移植”的概念。不过,在 ARM720T上是配有 MMU的,它的功能与 CM3的 MPU不一样——事实上,如果代码需要 MMU来支持虚拟内存,根本就不能使用 CM3。

18.2.4 系统控制

系统控制也是移植程序时必须充分重视的关键内容。CM3 内建了进入睡眠模式的指令。另一方 面,在 CM3芯片中的系统控制器也有特殊的设计要求,基本上它们不会与 ARM7芯片中的有什么相 似之处。因此,要做好思想准备,来重写系统控制相关的代码。

18.2.5 操作模式

以前的 ARM架构有 7种操作模式,在 CM3中,它们可以用对应的异常来取代,如表 18.1所示:
表 8.1 把 ARM7TDMI 中的操作模式和异常映射到 CM3

在 ARM7中的操作模式和异常

在 CM3中与之等价的操作模式和异常

监察者(supervisor)(复位后自动进入)

特权级的线程模式+MSP

监察者(因 SWI而进入)

SVC异常

FIQ

优先级最高的外部中断

IRQ

外部中断

指令流产(IAbt)

总线 fault

数据流产(DAbt)

总线 fault

未定义指令

用法 fault

系统模式

特权级的线程模式+PSP

用户

用户级的线程模式+PSP

虽然在 CM3 中,可以把 ARM7 的 FIQ对应到优先级最高的外中断,从而实现 FIQ 的时间地位。
但是 ARM7的“专用寄存器”是 R8-R11,而 CM3自动入栈的寄存器是 R0-R3,R12。因此,旧时 FIQ

服务例程需要改用 R0-R3,R12;如果依然要使用 R8-R11,就必须先把它们手工入栈。

NMI vs. FIQ

可能有不少人曾想到过用 NMI来取代 FIQ。的确,在一些场合中,这是可行的。但 是,NMI与 FIQ有本质的区别,使得很多情况下它们不能互换,这也是我们必须清醒地 认识到的。
第一, NMI正如其名,是不能被除能的。而 ARM7的 FIQ则可以通过把 CPSR.F置位来 除能。因此,在 CM3中何时进入 NMI完全不可控——有可能在引导期间就进入 NMI。而在 ARM7中,复位后 FIQ是除能的,因此不会意外地进入。
第二, CM3的 NMI服务例程不得使用 SVC,而 ARM7的 FIQ服务例程则可以使用 SWI。 另外,在 ARM7下,即使是在 FIQ服务例程的执行过程中,也可以转而响应其它 异常(IRQ除外)。而在 CM3下,如果 NMI服务例程执行过程中发生 fault,则 处理器当即被锁定。