做一个对社会有用的人!不抱怨,不气馁!
目录
前言
1 ARM处理器家族
2 什么是ARM Cortex-M处理器
2.1 Cortex-M3
2.2 M3处理器到微控制器
2.3 ARM处理器的发展
2.4 Thumb ISA的架构版本
2.4.1 指令集的概念
2.5 软件开发流程
2.5.1 轮询
3、技术综述
3.1、Cortex-M3简介
3.1.1 处理器类型
3.1.2 指令集
3.1.3 模块框图
3.1.5 存储器系统
3.2.6 中断处理
4 架构
4.1 编程模型
4.1.1 操作模式和状态
4.2.2 寄存器
4.2.3 特殊寄存器
4.4 存储器系统
4.4.1 存储器映射
4.2.2 栈存储
4.5 异常和中断
4.5.2 嵌套向量中断控制器(NVIC)
4.5.3 向量表
4.3.4 错误处理
5 指令集
6 存储器系统
6.1 存储器映射
6.1.1 互斥访问
6.6 数据对齐和非对齐数据访问支持
6.7 流水线
6.7.1 详细的框图
6.7.2 连接方式样板
7 异常和中断
7.1 异常类型
7.5 向量表
7.8 中断控制与NVIC寄存器细节
7.8.1 NVIC概览
7.8.2 中断使能寄存器
7.8.4 活跃状态
8 深入理解异常处理
8.1.1 入栈
8.1.2 取向量
8.1.3 更新寄存器
8.2 异常返回
8.3 嵌套的中断
8.4 咬尾中断
8.5 晚到(的高优先级)异常
8.6 异常返回值
9 低功耗和系统控制特性
10 Cortex-M3的低层编程
15 调试系统架构
15.2.2 DP模块,AP模块和 DAP
19 使用 GNU工具链开始 Cortex-M3开发
20 概念整理
参考文献
笔者最近也是想窥见一下arm cortex-M3的魅力,但又知道从何提笔,故借鉴了网上一些前辈的文章...如有错误的地方,请指正。
Application Processors(应用处理器)–面向移动计算,智能手机,服务器等市场的的高端处理器。这类处理器运行在很高的时钟频率(超过 1GHz),支持像 Linux,Android,MS Windows和移动操作系统等完整操作系统需要的内存管理单元(MMU)。 如果规划开发的产品需要运行上述其中的一个操作系统,你需要选择 ARM 应用处理器.
Real-time Processors (实时处理器)–面向实时应用的高性能处理器系列,例如硬盘控制器,汽车传动系统和无线通讯的基带控制。多数实时处理器不支持 MMU,不过通常具有 MPU、Cache和其他针对工业应用设计的存储器功能。实时处理器运行在比较高的时钟频率(例如 200MHz 到 >1GHz ),响应延迟非常低。虽然实时处理器不能运行完整版本的 Linux和 Windows操作系统, 但是支持大量的实时操作系统(RTOS)。
Microcontroller Processors(微控制器处理器)–微控制器处理器通常设计成面积很小和能效比很高。通常这些处理器的流水线很短,最高时钟频率很低(虽然市场上有此类的处理器可以运行在 200Mhz之上)。 并且,新的 Cortex-M处理器家族设计的非常容易使用。因此,ARM 微控制器处理器在单片机和深度嵌入式系统市场非常成功和受欢迎。
Cortex-M3(2005年发布)处理器是ARM公司设计的处理器。
Cortex-M3处理器使用32位架构,寄存器组中断内部寄存器、数据以及总线接口都是32位。Cortex-M处理器使用的指令集架构(ISA)是Thumb ISA(是一种RISC(精简指令集)),其基于Thumb-2技术并同时支持16位和32位指令。
Cortex-M3 针对低功耗微控制器设计的处理器,面积小但是性能强劲,支持可以处理器快速处理复杂任务的丰富指令集。具有硬件除法器和乘加指令(MAC).并且,M3支持全面的调试和跟踪功能,使软件开发者可以快速的开发他们的应用。
Cortex-M4 不但具备 Cortex-M3的所有功能,并且扩展了面向数字信号处理(DSP)的指令集,比如单指令多数据指令(SMID)和更快的单周期 MAC操作。此外,它还有一个可选的支持 IEEE754浮点标准的单精度浮点运算单元。
主要有以下特点:
Cortex-M3处理器提供了多种指令:
Cortex-M3处理器内核是单片机的中央处理单元(CPU)。完整的基于CM3的MCU还需要很多其
它组件。在芯片制造商得到CM3处理器内核的使用授权后,它们就可以把CM3内核用在自己的硅片设计中,添加存储器,外设,I/O以及其它功能块。不同厂家设计出的单片机会有不同的配置,包括存储器容量、类型、外设等都各具特色。如下图:
Cortex-M3处理器发布之前,ARM处理器以及有了许多种,比如ARM7、ARM9、ARM11。它们支持两套指令集:32位的ARM指令集和16位的Thumb指令集。
目前Cortex处理器系列包括三类:
汇编语言很重要! 汇编语言很重要! 汇编语言很重要!这里由于我个人水平原因,就不展开了。
还有大家需要什么资料的话,可以问我要,如果我有的话,会分享给你。
计算机指令就是指挥机器工作的指示和命令,程序就是一系列按一定顺序排列的指令,执行程序的过程就是计算机的工作过程。指令集,就是CPU中用来计算和控制计算机系统的一套指令的集合,而每一种新型的CPU在设计时就规定了一系列与其他硬件电路相配合的指令系统。而指令集的先进与否,也关系到CPU的性能发挥,它也是CPU性能体现的一个重要标志。指令的强弱也是CPU的重要指标,指令集是提高微处理器效率的最有效的工具之一。
在使用GNU的 gcc工具链时,一般可以一次性地编译整个应用程序,而不是将编译和链接阶段拆开,如图2.6所示。 在使用GNU的GCC工具链时,一般可以一次性地编译整个应用程序,而不是将编译和链接阶段拆开,如图2.6所示。
gcc编译时会自动调用所需的链接器和汇编器,这种处理可以确保所需的详细参数和库被正确地传到链接器。单独使用链接器可能会引发错误,因此这种做法是多数gcc 工具供应商所不提倡的。
简单的说,就是大家排队打饭一样。
轮询的缺点在于能耗效率差,在不需要服务时也会浪费很多能量。(大家都饿啊,排在前面的人先吃,看的人就更饿。)
为了解决这个问题,几乎所有的微控制器都会提供某种休眠模式以降低功耗,在休眠模式下,外设在需要服务时可以将处理器唤醒,如图2.9所示。这通常被称作中断驱动的应用程序。
在中断驱动的应用中,不同外设的中断可以被指定为不同的中断优先级。例如,重要/关键的外设可以被指定为较高的优先级﹐这样,若中断产生时处理器正在处理更低优先级的中断,低优先级中断就会被暂停,而更高优先级的中断服务就会立即执行。这种设计的响应较快。
多数情况下,外设服务的数据处理可以分为两部分:第一部分需要快速处理,而另一部分则可以执行得稍微慢一些。在这种情况下,在编写程序时可以将中断驱动和轮询结合起来。在当外设需要服务时,它就会像中断驱动的应用一样触发一个中断务执行后,它就会更新某些软件变量,以便第二部分可以在基于循环的应用程序代码中执行,如图2.10所示。
Cortex-M3和M4为32位RISC(精简指令集)处理器,其具有:
Cortex-M3和M4具有三级流水线,基于哈佛总线架构(另一个是普林斯顿架构),取指和数据访问可以同时执行。存储器系统使用32位寻址,地址最大空间是4GB。存储器空间包括程序代码、数据、外设以及处理器内部的调试支持部件。
Cortex-M刺激器基于一种加载—存储架构。比如要增加SRAM中存储的数据值,处理器需要一条指令从SRAM中读出数据,将其放到处理器的寄存器中,然后使用第二条指令增加寄存器中的值,最后使用第三条指令将其写回存储器。
所有的 Cortex-M 处理器都支持 Thumb指令集。整套 Thumb指令集扩展到 Thumb-2版本时变得相当大。但是,不同的 Cortex-M处理器支持不同的 Thumb 指令集的子集。
经典的ARM处理器(比如ARM7)具有两种操作状态:32位的ARM状态和16位的Thumb状态。在ARM状态,指令是32位的,内核能够以很高的性能执行所有支持的指令;而对于Thumb状态,指令是16位的,可以得到很好地代码密度,bugThumb指令不具有ARM指令所有功能,要完成特定的操作可能需要更多的指令。如下图。对于经典的ARM处理器,中断处理会进入ARM状态。
随着Thumb-2技术的引入,Thumb指令被扩展为支持16位和32位两种解码方式,无需在两个不同操作状态切换就可以满足所有的处理需求。
Cortex-M3和M4处理器本身不包含存储器,它们具有通用的片上总线接口,供应商可以将它们自己的存储器系统添加到系统中。如下部件:
Cortex-M3和M4处理器主要使用的总线接口协议是AHB Lite(高级高性能总线),用于程序存储器和系统总线接口。高级外设总线(APB)接口为处理器使用的另外一种总线协议。
Cortex-M3和M4处理器中存在一个嵌套向量中断控制器(NVIC)。它是可编程的且其寄存器经过了存储器映射。它的地址固定,编程模型对于所有的Cortex-M处理器都是一致的。
除了外设和其他外部输入中断,NVIC还支持多个系统异常,包括NMI(不可屏蔽中断)等。供应商决定实际支持的可编程中断优先级的数量。
1.操作状态
Cortex-M3处理器有两种操作状态和两个模式。
另外,处理器还可以区分特权和非特权访问等级﹐如图4.1所示。
特权访问等级可以访问处理器中的所有资源,而非特权访问等级则意味着有些存储器区域是不能访问的,有些操作也是无法使用的。
在一些文献中,非特权访问等级还可被称作“用户”状态,这个叫法是从 ARM7TDMI继承下来的。
2. 操作模式
在特权级下的代码可以通过置位 CONTROL[0]来进入用户级。而不管是任何原因产生了任何异常,处理器都将以特权级来运行其服务例程,异常返回后,系统将回到产生异常时所处的级别。用户级下的代码不能再试图修改 CONTROL[0]来回到特权级。它必须通过一个异常 handler,由那个异常handler来修改 CONTROL[0],才能在返回到线程模式后拿到特权级。
区分特权和非特权访问等级,设计人员可以提供对关键区域访问的保护机制及基本的安全模型,这样有助于开发健壮的嵌入式系统。例如,系统中可能包含运行在特权访问等级的OS内核,以及运行在非特权访问等级的应用程序。还可以通过MPU设置存储器访问权限避免应用任务破坏OS内核以及其他任务使用的存储器和外设。若应用任务崩溃,剩下的任务和OS内核可以继续运行。
几乎所有的NVIC寄存器支持特权访问。
什么寄存器?
给有特定功能的内存单元取一个别名,这个别名就是我们经常说的寄存器,这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。
如我们所见,CM3拥有通用寄存器 R0-R15以及一些特殊功能寄存器。R0-R12是最“通用目的”的,但是绝大多数的 16位指令只能使用 R0-R7(低组寄存器),而 32位的 Thumb-2指令则可以访问所有通用寄存器。特殊功能寄存器有预定义的功能,而且必须通过专用的指令来访问。
R0-R12都是 32位通用寄存器,用于数据操作。但是注意:绝大多数 16位 Thumb指令只能访
问 R0-R7,而 32位 Thumb-2指令可以访问所有寄存器。
前8个(R0 - R7)是低寄存器。许多16位指令只能访问低寄存器。高寄存器(R8 - R12)可以用于32位指令和几个16位指令。R0 - R12初始值未定义。
R13为栈指针,可通过PUSH和POP指令实现栈存储的访问。存在2个栈指针:
主栈指针(MSP)为默认的栈指针,在复位或处理器在处理模式时使用;
另一个为进程栈指针(PSP),只能用于线程模式。栈指针的选择由特殊寄存器(CONTROL)决定。
堆栈指针的最低两位永远是 0,这意味着堆栈总是 4字节对齐的。
当呼叫一个子程序时,由 R14存储返回地址 。
R15是程序计数器。指向当前的程序地址。如果修改它的值,就能改变程序的执行流。
由于这个概念比较重要,所以就不展开说了,大家可以参考这篇文章。
10.6 对栈进行push和pop - 叮铃铛铛 - 博客园 (cnblogs.com)
除了寄存器组中的寄存器外,处理器还存在多个特殊寄存器,
4.2.4 CONTROL寄存器
CONTROL寄存器(如下图)定义了:
CONTROL寄存器只能在特权访问等级修改,读操作在特权和非特权都可以。
Cortex-M处理器的4GB地址空间被划分了多个存储器区域,如下图。区域根据各自用法划分,主要用于:
架构的这种安排具有很大的灵活性,存储器区域可用于其他目的。例如,程序即可以在CODE区域执行,也可以在SRAM区域执行,而且微控制器也可以在CODE区域加入SRAM。
在栈这种存储器机制中,存储器的一部分可被用作后进先出的数据存储缓冲。ARM处理器将系统主存储器用于栈空间操作,使用PUSH和POP。每次PUSH和POP操作后,栈指针会自动调整。
栈可用于:
Cortex-M处理器使用的栈模型是“满递减”。处理器启动后,SP被设置为栈存储空间最后的位置。每次PUSH操作,处理器先减小SP的值,然后将数据存储在SP指向的存储器位置。对于POP操作,SP指向的存储器位置数据被读出,然后SP的值自动减小。
PUSH和POP指令最常见的用法是,在执行函数调用时保存寄存器组中的内容,函数调用结束时通过POP恢复它们的值。
对于不具有OS的简单应用,线程模式和处理模式都可以只使用MSP,如图4.23所示。在异常事件产生后,处理器在进入中断服务程序(ISR)前会首先将多个寄存器压人栈中,这种寄存器状态保存操作被称作“压栈”,而在ISR结束时,这些寄存器又会被恢复到寄存器组中,这种操作则被称作“出栈”。
若嵌入式系统中包含OS,通常会将应用任务和内核所用的栈空间分离开来,因此PSP会被用到,在异常入口和出口时会发生SP切换,如下图。
尽管同一时间内只有一个SP可见,如果当前处于特权等级,可以用PSR和MRS指令访问隐藏的SP。
4.5.1 什么是异常
异常是会改变程序流的事件,当其产生时,处理器会暂停当前正在执行的任务,转而执行一段被称作异常处理的程序。在异常处理执行完后,处理器会继续正常地程序执行。对于ARM架构,中断就是异常的一种,它一般由外设或外部输入产生,有时也可以由软件触发。中断的异常处理也被称作中断服务程序(ISR)。
简单的理解:我们在看这篇文章的时候,你的手机微信震动了一下。
本来这篇文章已经很晦涩难懂了,你的神经元就像是一道光一样,告诉你的大脑,该出去散散步了,等散步回来再看。然后就这么愉快的决定了。
记住这不是你不认真好好工作,是外界干扰了你。人生也是一样的道理。遇到问题,尤其是领导说你不行的时候,不要傻傻的认为是自己的问题。
(1)NVIC处理异常。NVIC可以处理多个中断请求(IRQ)和一个不可屏蔽中断(NMI)请求,IRQ一般由片上外设或外部中断输入通过I/O端口产生,NMI可用于看门狗定时器或掉电检测(一种电压监视单元,在电压低到一定程度时会给处理器产生警告)。处理器内部也有名为SysTick 的定时器,它可以产生周期性的定时中断请求,可用于嵌入式OS计时或没有OS的应用中的简单定时控制。
(2)处理器自身也是一个异常事件源﹐其中包括表示系统错误状态的错误事件以及软件产生、支持嵌入式OS操作的异常。这些异常类型如下表所示。
Cortex-M3中的异常类型
(没有理解)
当异常事件产生且被处理器内核接受后,相应的异常处理就会执行。向量表是可以重定位的,由NVIC中的名为向量表偏移寄存器(VTOR)控制。复位后默认为0,向量表则位于地址0x0处。
Cortex-M3和M4处理器中有几个异常为错误处理异常。处理器检测到错误时,触发错误异常,错误包括执行未定义的指令以及总线错误、对存储器访问返回错误等。
总线错误、使用错误以及存储器管理错误默认是禁止的,且所有的错误事件都会触发HardFault异常(总是使能)。但这些配置是可编程的。
4.4 复位和复位流程
对于典型的Cortex-M处理器,复位类型由三种:
上电复位。复位微控制器的所有部分,包括处理器、调试支持部件和外设等。
系统复位。只会复位处理器和外设,不包括调试支持部件。
处理器复位。只复位处理器
在复位后以及处理器开始执行程序之前,Cortex-M处理器会从存储器中读出头两个字,如下图。向量表位于存储器的开头部分,它的头两个字为MSP的初始值和代表复位除了起始地址的复位向量。处理器读出这两个字会将其赋值给MSP和PC。
MSP的设置非常必要。因为在复位的很多时间内有产生NMI或HardFault的可能,在异常处理前将处理器状态压栈时需要栈存储和MSP。
指令集的设计为处理器架构的重点之一,ARM一般将其称作指令集架构(ISA)。所有的ARM Cortex-M处理器都基于Thumb-2技术,允许在一种操作状态下混合使用16位和32位指令,这一点和ARM7TDMI等经典的ARM处理器不同。
主要看看汇编语言,这里不再赘述。
存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配给存储器分配地址的过程就称为存储器映射。
Cortex-M处理器可以对32位存储器进行寻址,因此存储器空间能够达到4GB(2^32)。存储器空间是统一的,这也意味着指令和数据共用相同的地址空间。根据架构定义,4GB的存储器空间被分为了多个区域,6.2节将会介绍这方面的内容。
内部 SRAM区的大小是 512MB,用于让芯片制造商连接片上的 SRAM,这个区通过系统总线来访
问。在这个区的下部,有一个 1MB的区间,被称为“位带区”。该位带区还有一个对应的、32MB的
“位带别名(alias)区”,容纳了 8M个“位变量”(对比 8051的只有 128个位变量)。位带区对应
的是最低的 1MB地址范围,而位带别名区里面的每个字对应位带区的一个比特。位带操作只适用于数据访问,不适用于取指。通过位带的功能,可以把多个布尔型数据打包在单一的字中,却依然可以从位带别名区中,像访问普通内存一样地使用它们。位带别名区中的访问操作是原子的,消灭了传统的“读-改-写”三步曲。位带操作的细节待会还要讲到。
地址空间的另一个 512MB范围由片上外设(的寄存器)使用。这个区中也有一条 32MB的位带
别名,以便于快捷地访问外设寄存器,用法与内部 SRAM区中的位带相同。例如,可以方便地访问各种控制位和状态位。要注意的是,外设区内不允许执行指令。
还有两个 1GB的范围,分别用于连接外部 RAM和外部设备,它们之中没有位带。两者的区别在
于外部 RAM区允许执行指令,而外部设备区则不允许。
互斥体在多任务环境中使用,也在中断服务例程和主程序之间使用,用于给任务申请共享资源
(如一块共享内存)。在某个(排他型)共享资源被一个任务拥有后,直到这个任务释放它之前,
其它任务是不得再访问它的。
由于存储器系统为32位的(至少从编程模型的角度来看是这样的),大小为32位(4字节,或字)或16位(2字节,或半字)可以是对齐也可以是不对齐的。对齐传输的意思是地址值为大小(以字节为单位)的整数倍。例如,字大小的对齐传输可以执行的地址为0x00000000,0x00000004,…,0x00001000,0x00001004等;类似地,半字大小的对齐传输可以执行的地址则为0x00000000、0x00000002、…,0x00001000、0x00001002等。
对齐和非对齐传输的实例如图6.6所示。
Cortex-M3处理器使用一个 3级流水线。流水线的 3个级分别是:取指,解码和执行,如图
6.7所示:
图 6.7Cortex-M3的三级流水线
由于流水线的存在,以及出于对Thumb代码兼容的考虑,读取PC时,会返回当前指令地址+4的
值。这个偏移量总是4,不管是执行16位指令还是32位指令,这就保证了在Thumb和Thumb2之间的一致性。
这一章节很有意思,大家一起聊聊!
对于几乎所有的微控制器,中断都是一种常见的特性。中断一般是由硬件(如外设和外部输人引脚)产生的事件,它会引起程序流偏离正常的流程(如给外设提供服务)。当外设或硬件需要处理器的服务时,一般会出现下面的流程:
(1)外设确认到处理器的中断请求。
(2)处理器暂停当前执行的任务。
(3)处理器执行外设的中断服务程序(ISR),若有必要可以选择由软件清除中断请求。
(4)处理器继续执行之前暂停的任务。
Cortex-M3在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断。其
中,编号为 1-15的对应系统异常,大于等于 16的则全是外部中断。除了个别异常的优先级被定
死外,其它异常的优先级都是可编程的。
译注:所有能打断正常执行流的事件都称为异常。在本书中,经常混合使用术语“中断”与“异常”。如不加说明,则强调的都是它们对主程序所体现出来的“中断”性质,与我们以前学单片机时所讲的概念是相同的。如果非得分个丁一卯二,则中断与异常的区别在于,那 240个中断对 CM3核来说都是“意外突发事件”——也就是说,该请求信号来自 CM3内核的外面,来自各种片上外设和外扩的外设,对 CM3来说是“异步”的;而异常则是因 CM3内核的活动产生的——在执行指令或访问存储器时产生,因此对 CM3来说是“同步”的。
因为芯片设计者可以修改 CM3的硬件描述源代码,所以做成芯片后,支持的中断源数目常常不到 240个,并且优先级的位数也由芯片厂商最终决定。
类型编号为 1-15的系统异常如表 7.1所示(注意:没有编号为 0的异常),从 16开始的外部中断类型如表 7.2所示。
在 CM3中,优先级对于异常来说很关键的,它会决定一个异常是否能被掩蔽,以及在未掩蔽的
情况下何时可以响应。优先级的数值越小,则优先级越高。CM3支持中断嵌套,使得高优先级异常
会抢占(preempt)低优先级异常。有 3个系统异常:复位,NMI以及硬 fault,它们有固定的优先
级,并且它们的优先级号是负数,从而高于所有其它异常。
当发生了异常并且要响应它时,CM3需要定位其服务例程的入口地址。这些入口地址存储在所
谓的“(异常)向量表”中。缺省情况下,CM3认为该表位于零地址处,且各向量占用 4字节。因此
每个表项占用 4字节,如表 7.6所示。
有些微控制器具有多个程序存储器:启动ROM和用户Flash存储器。微控制器生产商一般会将Boot loader预先写到启动ROM中,这样在微控制器启动时,启动ROM中的 Bootloader就会首先执行,而且在跳转到用户Flash的应用程序前,VTOR会被设置为指向用户Flash存储器的开始处,因此会使用用户 Flash 中的向量表。
2.应用程序加载到RAM(图7.13)
有些情况下,应用程序可能会被从外部设备加载到RAM中执行,它可能会位于SD卡中,或者甚至需要通过网络传输。在这种情况下,存储在片上存储器中用于启动的程序需要初始化一些硬件、复制位于外部设备中的应用程序到RAM、更新VTOR后执行存储在外部的程序。
正如前文已经多次提到的,向量中断控制器,简称 NVIC,是 Cortex-M3不可分离的一部分,
它与 CM3内核的逻辑紧密耦合,有一部分甚至水乳交融在一起。NVIC与 CM3内核同声相应,同气相求,相辅相成,里应外合,共同完成对中断的响应。NVIC的寄存器以存储器映射的方式来访问,除了包含控制寄存器和中断处理的控制逻辑之外,NVIC还包含了 MPU、SysTick定时器以及调试控制相关的寄存
器。本章中,我们将体检 NVIC的中断处理控制逻辑。MPU与调试控制逻辑在后续章节中讨论。
NVIC共支持 1至 240个外部中断输入(通常外部中断写作 IRQs)。具体的数值由芯片厂商在
设计芯片时决定。此外,NVIC还支持一个“永垂不朽”的不可屏蔽中断(NMI)输入。NMI的实际
功能亦由芯片制造商决定。在某些情况下,NMI无法由外部中断源控制。
NVIC的访问地址是 0xE000_E000。所有 NVIC的中断控制/状态寄存器都只能在特权级下访问。
不过有一个例外——软件触发中断寄存器可以在用户级下访问以产生软件中断。所有的中断控制/
状态寄存器均可按字/半字/字节的方式访问。
中断使能寄存器可由两个地址进行配置。要设置使能位,需要写入NVIC->ISER[n]寄存器地址﹔要清除使能位,需要写入NVIC->ICER[n]寄存器地址。这样,使能或禁止一个中断时就不会影响其他的中断使能状态,ISER/ICER寄存器都是32位宽,每个位代表一个中断输入。 中断使能寄存器可由两个地址进行配置.要设置使能位,需要写入[n]寄存器地址;要清除使能位,需要写入n->ICER[n]寄存器地址.这样,使能或禁止一个中断时就不会影响其他的中断使能状态,ISER/ICER 32位宽,每个位代表一个中断输入。
每个外部中断都在 NVIC的下列寄存器中“挂号”:
另外,下列寄存器也对中断处理有重大影响
每个外部中断都有一个活跃状态位,当处理器开始执行中断处理时,该位会被置1,而在执行中断返回时会被清零。不过,在中断服务程序(ISR)执行期间,更高优先级的中断可能会产生且抢占。在此期间,尽管处理器在执行另一个中断处理,之前的中断仍会被定义为活跃的。尽管IPSR(见图4.5)表示当前正在执行的异常服务,它无法告诉你当有嵌套异常时某个异常是否为活跃的。中断活跃状态寄存器为32位宽,不过还能通过半字或字节传输访问。若外部中断的数量超过32,则活跃状态寄存器会不止一个。外部中断的活跃状态寄存器为只读的,如表7.12所示。
当CM3开始响应一个中断时,会在它小小的体内奔涌起三股暗流:
响应异常的第一个行动,就是自动保存现场的必要部分:依次把xPSR, PC, LR, R12以及R3-R0由硬件自动压入适当的堆栈中:如果当响应异常时,当前的代码正在使用PSP,则压入PSP,也就是使用进程堆栈;否则就压入MSP,使用主堆栈。一旦进入了服务例程,就将一直使用主堆栈。
假设入栈开始时,SP的值为N,则在入栈后,堆栈内部的变化如表9.1表示。又因为AHB接口上
的流水线操作本性,地址和数据都在经过一个流水线周期之后才进入。另外,在自动入栈的过程中,把寄存器写入堆栈内存的时间顺序,并不是与写入的空间顺序相对应的。但是机器会保证:正确的寄存器将被保存到正确的位置,如图9.1和表9.1的第3列所示。
当数据总线(系统总线)正在为入栈操作而忙得风风火火时,指令总线(I-Code总线)可不是
凉快地坐那儿看热闹——它正在为响应中断紧张有序地执行另一项重要的任务:从向量表中找出正
确的异常向量,然后在服务程序的入口处预取指。由此可以看到各自都有专用总线的好处:入栈与
取指这两个工作能同时进行。
在入栈和取向量操作完成之后,执行服务例程之前,还要更新一系列的寄存器:
以上是在响应异常时通用寄存器的变化。另一方面,在NVIC中,也会更新若干个相关有寄存器。
例如,新响应异常的悬起位将被清除,同时其活动位将被置位。
当异常服务例程执行完毕后,需要很正式地做一个“异常返回”动作序列,从而恢复先前的系
统状态,才能使被中断的程序得以继续执行。从形式上看,有3种途径可以触发异常返回序列,如
表9.2所示。而不管使用哪一种,都需要用到先前储到LR的EXC_RETURN。
在CM3内核以及NVIC的深处,就已经内建了对中断嵌套的全力支持,根本无需使用汇编去写封
皮代码(wrapper code)。事实上,我们要做的就只是为每个中断适当地建立优先级,不用再操心别的。
表现在:
第一、 NVIC和CM3处理器会根据优先级的设置来控制抢占与嵌套行为。因此,在某个异常正
在响应时,所有优先级不高于它的异常都不能抢占之,而且它自己也不能抢占自己。
第二、 有了自动入栈和出栈,就不用担心在中断发生嵌套时,会使寄存器的数据损毁,从而
可以放心地执行服务例程。
(理解抽象,请大家指点指点。)
当处理器在响应某异常时,如果又发生其它异常,但它们优先级不够高,则被阻塞——这个我们已经知道。那么在当前的异常执行返回后,系统处理悬起的异常时,倘若还是先POP,然后又把POP出来的内容PUSH回去,这不成了砸锅炼铁再铸锅,白白浪费CPU时间吗,可知还有多少紧急的事件悬而未决呀!正因此,CM3不会傻乎乎地POP这些寄存器,而是继续使用上一个异常已经PUSH好的成果,消灭了这种铺张浪费。这么一来,看上去好像后一个异常把前一个的尾巴咬掉了,前前后后只执行了一次入栈/出栈操作。于是,这两个异常之间的“时间沟”变窄了很多,如图9.2所示:
(没有理解)
(没有理解)
图10.1 使用ARM工具链时的典型开发流程
这一章节的内容比较多,这里我仅简单的整理,详细的内容,后续会更新。
从外部调试器到 CM3调试接口的连接,需要多级互联才能完成,如图 15.1所示。
第一步,是通过 DP接口模块(通常是 SWJ-DP或 SW-DP),先把外部信号转换成一个通用的 32
位调试总线信号(图表中的 DAP总线)。SWJ-DP支持 SW与 JTAG两种协议,而 SW-DP则只支持 SW。
另外,在 CoreSight产品中还可以使用一种 JTAG-DP,它只支持 JTAG协议。DAP总线上的地址是
32位的,其中高 8位用于选择访问哪一个设备,由此可见,最多可以在 DAP总线上面挂 256个设
备。在 CM3处理器的内部,只用掉了一个设备的地址,还剩下的 255个都可以用于连接访问端口(AP)到 DAP总线上。
不同的应用程序环境中也有不同版本的工具链(Symbian, Linux, EABI等)。取决于工具链
的目标平台,相应的可执行文件通常有一个前缀。例如,如果使用了 EABI环境,则 GCC命令为
arm-xxxx-eabi-gcc。本章的目标代码使用 CodeSourcery的 GNU ARM工具链,如表 19.1所示。
表 19.1 winARM20080331 GNU工具链的命令名称
SFR,Special Function Register,又称专用寄存器
[1]ARM Cortex-M3/M4内核相关_arm m4内核-CSDN博客
(持续更新,也欢迎大家评论留言,共同进步!)