初稿第1章Cortex-M3权威指南你别看CM3只是个小处理器,它的高性能和MPU机制可是足以让复杂的软件跑起来的同时提供健壮的存储器保护。目前在市场上已经有了好多基于Cortex-M3内核的处理器产品,最便宜的还不到1美元,让ARM终于比很多8位机还便宜了。本书的组织Chpt1和2,Cortex-M3的介绍和概览Chpt3-6,Cortex-M3的基础知识Chpt 7-9,异常与中断Chpt10和11,论述在Cortex-M3的编程Chpt12-14Cortex-M3的硬件特性Chpt15-16Cortex-M3的调试支持Chpt 17-20,在Cortex-M3上的应用软件开发附录s深入研究用的读物本书并没有面面俱到地谈及Cortex-M3的技术细节。本书靠前的章节用来做Cortex-M3新手的敲门砖,同时也是CM3处理器的增值参考资料。如果要进一步地学习,就需要从ARM网站下载下面这些重量级的权威资料:《TheCortex-M3TechnicalReferenceManual》,深入了处理器的内心,编程模型,存储器映射,还包括了指令时序。《TheARMv7-MArchitectureApplicationLevelReferenceManual》第2版,对指令集和存储器模型都提供了最不嫌繁的说明。其它半导体厂家提供的,基于CM3单片机的数据手册。如想了解更多总线协议的细节,可以去看《AMBASpecification2.o》(第4版),它讲了更多AMBA接口的内幕。对于c程序员,可以从《ARMApplicationNote179:Cortex-M3EmbeddedSoftwareDevelopment》(第7版)中得到一些编程技巧和提示。本书假设你已经涉足过嵌入式编程,有一些基本知识和经验。如果你是位产品经理或者是想先浅浅地尝一尝,请先读第2章,试着找找感觉再决定要不要深入学习。这一章浓缩了全书的精华,走马观花地讲了Cortex-M3内核。24
Cortex‐M3 权威指南 初稿 第 1 章 24 你别看CM3只是个小处理器,它的高性能和MPU机制可是足以让复杂的软件跑起来的, 同时提供健壮的存储器保护。 目前在市场上已经有了好多基于Cortex‐M3内核的处理器产品,最便宜的还不到1美元, 让ARM终于比很多8位机还便宜了。 本书的组织 Chpt 1和2, Cortex‐M3的介绍和概览 Chpt 3‐6, Cortex‐M3的基础知识 Chpt 7‐9, 异常与中断 Chpt 10和11, 论述在Cortex‐M3的编程 Chpt 12‐14, Cortex‐M3的硬件特性 Chpt 15‐16, Cortex‐M3的调试支持 Chpt 17‐20, 在Cortex‐M3上的应用软件开发 附录s 深入研究用的读物 本书并没有面面俱到地谈及Cortex‐M3的技术细节。本书靠前的章节用来做Cortex‐M3新 手的敲门砖,同时也是CM3处理器的增值参考资料。如果要进一步地学习,就需要从ARM网 站下载下面这些重量级的权威资料: 《The Cortex‐M3 Technical Reference Manual》,深入了处理器的内心,编程模型,存储 器映射,还包括了指令时序。 《 The ARMv7‐M Architecture Application Level Reference Manual》第2版,对指令集和存储 器模型都提供了最不嫌繁的说明。 其它半导体厂家提供的,基于CM3单片机的数据手册。 如想了解更多总线协议的细节,可以去看《AMBA Specification 2.0》(第4版),它讲了 更多AMBA接口的内幕。 对于C程序员,可以从《ARM Application Note 179: Cortex‐M3 Embedded Software Development》(第7版)中得到一些编程技巧和提示。 本书假设你已经涉足过嵌入式编程,有一些基本知识和经验。如果你是位产品经理或者 是想先浅浅地尝一尝,请先读第2章,试着找找感觉再决定要不要深入学习。这一章浓缩了 全书的精华,走马观花地讲了Cortex‐M3内核
初稿第2章Cortex-M3权威指南第2章Cortex-M3概览内容提要:·简介·寄存器组?操作模式和特权极别?内建的嵌套向量中断控制器?存储器映射.总线接口存储器保护单元?.指令系统中断和异常?调试支持??小结简介Cortex-M3是一个32位处理器内核。内部的数据路径是32位的,寄存器是32位的,存储器接口也是32位的。CM3采用了哈佛结构,拥有独立的指令总线和数据总线,可以让取指与数据访问并行不。这样一来数据访问不再占用指令总线,从而提升了性能。为实现这个特性,CM3内部含有好几条总线接口,每条都为自已的应用场合优化过,并且它们可以并行工作。但是另一方面,指令总线和数据总线共享同一个存储器空间(一个统一的存储器系统)。换句话说,不是因为有两条总线,可寻址空间就变成8GB了。比较复杂的应用可能需要更多的存储系统功能,为此CM3提供一个可选的MPU,而且在需要的情况下也可以使用外部的cache。另外在CM3中,Both小端模式和大端模式都是支持的。CM3内部还附赠了好多调试组件,用于在硬件水平上支持调试操作,如指令断点,数据观察点等。另外,为支持更高级的调试,还有其它可选组件,包括指令跟踪和多种类型的调试接口。25
Cortex‐M3 权威指南 初稿 第 2 章 第2章 Cortex-M3概览 内容提要: z 简介 z 寄存器组 z 操作模式和特权极别 z 内建的嵌套向量中断控制器 z 存储器映射 z 总线接口 z 存储器保护单元 z 指令系统 z 中断和异常 z 调试支持 z 小结 简介 Cortex‐M3 是一个 32 位处理器内核。内部的数据路径是 32 位的,寄存器是 32 位的,存储器接 口也是 32 位的。CM3 采用了哈佛结构,拥有独立的指令总线和数据总线,可以让取指与数据访问 并行不悖。这样一来数据访问不再占用指令总线,从而提升了性能。为实现这个特性, CM3 内部 含有好几条总线接口,每条都为自己的应用场合优化过,并且它们可以并行工作。但是另一方面, 指令总线和数据总线共享同一个存储器空间(一个统一的存储器系统)。换句话说,不是因为有两 条总线,可寻址空间就变成 8GB 了。 比较复杂的应用可能需要更多的存储系统功能,为此 CM3 提供一个可选的 MPU,而且在需要 的情况下也可以使用外部的 cache。另外在 CM3 中,Both 小端模式和大端模式都是支持的。 CM3 内部还附赠了好多调试组件,用于在硬件水平上支持调试操作,如指令断点,数据观察点 等。另外,为支持更高级的调试,还有其它可选组件,包括指令跟踪和多种类型的调试接口。 25
初稿第2章Cortex-M3权威指南Cortex-M3ProcessorCoreSystemRegisteraionoahuauuan viedeporaBankDebugInterruptsTraceeSystemALUMemory InterfaceMemoryInstructionBusProtectionData BusUnitDebugDebugBus Interconnect4InterfaceCodeMemorySystemPrivateOptionalMemoryandPeripheralsPeripherals图2.1Cortex-M3的一个简化视图寄存器组Cortex-M3处理器拥有RO-R15的寄存器组。其中R13作为堆栈指针SP。SP有两个,但在同一时刻只能有一个可以看到,这也就是所谓的“banked”寄存器。通用寄存器RO通用寄存器R1R2通用寄存器R3通用寄存器LowRegistersR4通用寄存器R5通用寄存器R6通用寄存器R7通用寄存器R8通用寄存器R9通用寄存器R10HighRegisters通用寄存器R11通用寄存器R12通用寄存器R13(MSP)R13 (PSP)主堆栈指针(MSP),进程堆栈指针(PSP)连接寄存器(LR)R14R15程序计数器(PC)26
Cortex‐M3 权威指南 初稿 第 2 章 图 2.1 Cortex‐M3 的一个简化视图 寄存器组 Cortex‐M3 处理器拥有 R0‐R15 的寄存器组。其中 R13 作为堆栈指针 SP。SP 有两个,但在同一 时刻只能有一个可以看到,这也就是所谓的“banked”寄存器。 26
初稿第2章Cortex-M3权威指南RO-R12:通用寄存器RO-R12都是32位通用寄存器,用于数据操作。但是注意:绝大多数16位Thumb指令只能访问RO-R7,而32位Thumb-2指令可以访问所有寄存器。BankedR13:两个堆栈指针Cortex-M3拥有两个堆栈指针,然而它们是banked,因此任一时刻只能使用其中的一个。主堆栈指针(MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包括中断服务例程)●进程堆栈指针(PSP):由用户的应用程序代码使用。堆栈指针的最低两位永远是0,这意味着堆栈总是4字节对齐的。在ARM编程领域中,凡是打断程序顺序执行的事件,都被称为异常(exception)。除了外部中断外,当有指令执行了“非法操作”,或者访问被禁的内存区间,因各种错误产生的fault,以及不可屏蔽中断发生时,都会打断程序的执行,这些情况统称为异常。在不严格的上下文中,异常与中断也可以混用。另外,程序代码也可以主动请求进入异常状态的(常用于系统调用)。R14:连接寄存器当呼叫一个子程序时,由R14存储返回地址不像大多数其它处理器,ARM为了减少访问内存的次数(访问内存的操作往往要3个以上指令周期,带MMU和cache的就更加不确定了),把返回地址直接存储在寄存器中。这样足以使很多只有1级子程序调用的代码无需访问内存(堆栈内存),从而提高了子程序调用的效率。如果多于1级,则需要把前一级的R14值压到堆栈里。在ARM上编程时,应尽量只使用寄存器保存中间结果,迫不得以时才访问内存。在RISC处理器中,为了强调访内操作越过了处理器的界线,并且带来了对性能的不利影响,给它取了一个专业的术语:溅出。R15:程序计数寄存器指向当前的程序地址。如果修改它的值,就能改变程序的执行流(很多高级技巧就在这里面一一译注)。特殊功能寄存器Cortex-M3还在内核水平上搭载了若干特殊功能寄存器,包括程序状态字寄存器组(PSRs)中断屏蔽寄存器组(PRIMASK,FAULTMASK,BASEPRI)控制寄存器(CONTROL)XPSR状态字寄存器s(三合一)PRIMASK特殊功能中断屏蔽FAULTMASK寄存器s寄存器sBASEPRICONTROL控制寄存器图2.3:Cortex-M3中的特殊功能寄存器集合27
Cortex‐M3 权威指南 初稿 第 2 章 R0-R12:通用寄存器 R0‐R12 都是 32 位通用寄存器,用于数据操作。但是注意:绝大多数 16 位 Thumb 指令只能访 问 R0‐R7,而 32 位 Thumb‐2 指令可以访问所有寄存器。 Banked R13: 两个堆栈指针 Cortex‐M3 拥有两个堆栈指针,然而它们是 banked,因此任一时刻只能使用其中的一个。 z 主堆栈指针(MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包 括中断服务例程) z 进程堆栈指针(PSP):由用户的应用程序代码使用。 堆栈指针的最低两位永远是 0,这意味着堆栈总是 4 字节对齐的。 在 ARM 编程领域中,凡是打断程序顺序执行的事件,都被称为异常(exception)。除了外部中断外,当有指令执 行了“非法操作”,或者访问被禁的内存区间,因各种错误产生的 fault,以及不可屏蔽中断发生时,都会打断程序的 执行,这些情况统称为异常。在不严格的上下文中,异常与中断也可以混用。另外,程序代码也可以主动请求进入 异常状态的(常用于系统调用)。 R14:连接寄存器 当呼叫一个子程序时,由 R14 存储返回地址 不像大多数其它处理器,ARM 为了减少访问内存的次数(访问内存的操作往往要 3 个以上指令周期,带 MMU 和 cache 的就更加不确定了),把返回地址直接存储在寄存器中。这样足以使很多只有 1 级子程序调用的代码无需访 问内存(堆栈内存),从而提高了子程序调用的效率。如果多于 1 级,则需要把前一级的 R14 值压到堆栈里。在 ARM 上编程时,应尽量只使用寄存器保存中间结果,迫不得以时才访问内存。在 RISC 处理器中,为了强调访内操作越过 了处理器的界线,并且带来了对性能的不利影响,给它取了一个专业的术语:溅出。 R15:程序计数寄存器 指向当前的程序地址。如果修改它的值,就能改变程序的执行流(很多高级技巧就在这里面— —译注)。 特殊功能寄存器 Cortex‐M3 还在内核水平上搭载了若干特殊功能寄存器,包括 程序状态字寄存器组(PSRs) 中断屏蔽寄存器组(PRIMASK, FAULTMASK, BASEPRI) 控制寄存器(CONTROL) 图 2.3: Cortex-M3 中的特殊功能寄存器集合 27
初稿第2章Cortex-M3权威指南表2.1寄存器及其功能功能寄存器XPSR记录ALU标志(O标志,进位标志,负数标志,溢出标志),执行状态,以及当前正服务的中断号PRIMASK除能所有的中断一一当然了,不可屏蔽中断(NMI)才不甩它呢。FAULTMASK除能所有的fault—一NMI依然不受影响,而且被除能的faults会“上访”,见后续章节的叙述。BASEPRI除能所有优先级不高于某个具体数值的中断。CONTROL定义特权状态(见后续章节对特权的叙述),并且决定使用哪一个堆栈指针第3章对此有展开的叙述。操作模式和特权极别Cortex-M3处理器支持两种处理器的操作模式,还支持两级特权操作。两种操作模式分别为:处理者模式(handlermode,以后不再把handler中译一一译注)和线程模式(threadmode)。引入两个模式的本意,是用于区别普通应用程序的代码和异常服务例程的代码包括中断服务例程的代码。Cortex-M3的另一个侧面则是特权的分级一一特权级和用户级。这可以提供一种存储器访问的保护机制,使得普通的用户程序代码不能意外地,甚至是恶意地执行涉及到要害的操作。处理器支持两种特权级,这也是一个基本的安全模型。特权级用户级异常handler的代码错误的用法handler模式主应用程序的代码线程模式线程模式图2.4Cortex-M3下的操作模式和特权级别在CM3运行主应用程序时(线程模式),既可以使用特权级,也可以使用用户级:但是异常服务例程必须在特权级下执行。复位后,处理器默认进入线程模式,特权极访问。在特权级下,程序可以访问所有范围的存储器(如果有MPU,还要在MPU规定的禁地之外),并且可以执行所有指令。在特权级下的程序可以为所欲为,但也可能会把自已给玩进去一一切换到用户级。一旦进入用户级,再想回来就得走“法律程序”了一一用户级的程序不能简简单单地试图改写CONTROL寄存器就回到特权级,它必须先“申诉”:执行一条系统调用指令(SVC)。这会触发SVC异常,然后由异常服务例程(通常是操作系统的一部分)接管,如果批准进入,则异常服务例程修改CONTROL寄存器,才能在用户级的线程模式下重新进入特权级。事实上,从用户级到特权级的唯一途径就是异常:如果在程序执行过程中触发了一个异常,处理器总是先切换入特权级,并且在异常服务例程执行完毕退出时,返回先前的状态(也可以手工指定返回的状态一一译注)。28
Cortex‐M3 权威指南 初稿 第 2 章 表 2.1 寄存器及其功能 寄存器 功能 xPSR 记录 ALU 标志(0 标志,进位标志,负数标志,溢出标志),执行状态,以及 当前正服务的中断号 PRIMASK 除能所有的中断——当然了,不可屏蔽中断(NMI)才不甩它呢。 FAULTMASK 除能所有的 fault——NMI 依然不受影响,而且被除能的 faults 会“上访”,见 后续章节的叙述。 BASEPRI 除能所有优先级不高于某个具体数值的中断。 CONTROL 定义特权状态(见后续章节对特权的叙述),并且决定使用哪一个堆栈指针 第 3 章对此有展开的叙述。 操作模式和特权极别 Cortex‐M3 处理器支持两种处理器的操作模式,还支持两级特权操作。 两种操作模式分别为:处理者模式(handler mode,以后不再把 handler 中译——译注)和线程模 式(thread mode)。引入两个模式的本意,是用于区别普通应用程序的代码和异常服务例程的代码 ——包括中断服务例程的代码。 Cortex‐M3 的另一个侧面则是特权的分级——特权级和用户级。这可以提供一种存储器访问的 保护机制,使得普通的用户程序代码不能意外地,甚至是恶意地执行涉及到要害的操作。处理器支 持两种特权级,这也是一个基本的安全模型。 图 2.4 Cortex‐M3 下的操作模式和特权级别 在 CM3 运行主应用程序时(线程模式),既可以使用特权级,也可以使用用户级;但是异常服 务例程必须在特权级下执行。复位后,处理器默认进入线程模式,特权极访问。在特权级下,程序 可以访问所有范围的存储器(如果有 MPU,还要在 MPU 规定的禁地之外),并且可以执行所有指令。 在特权级下的程序可以为所欲为,但也可能会把自己给玩进去——切换到用户级。一旦进入用 户级,再想回来就得走“法律程序”了——用户级的程序不能简简单单地试图改写 CONTROL 寄存器 就回到特权级,它必须先“申诉”:执行一条系统调用指令(SVC)。这会触发 SVC 异常,然后由异常 服务例程(通常是操作系统的一部分)接管,如果批准了进入,则异常服务例程修改 CONTROL 寄存 器,才能在用户级的线程模式下重新进入特权级。 事实上,从用户级到特权级的唯一途径就是异常:如果在程序执行过程中触发了一个异常,处 理器总是先切换入特权级,并且在异常服务例程执行完毕退出时,返回先前的状态(也可以手工指 定返回的状态——译注)。 28