好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

第二章ARMCortexM3内核结构.pdf

37页
  • 卖家[上传人]:hs****ma
  • 文档编号:574178229
  • 上传时间:2024-08-16
  • 文档格式:PDF
  • 文档大小:2.08MB
  • / 37 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 1 页 第二章 ARM Cortex-M3 内核结构 教学目标 通过本章的学习,要理解 ARM Cortex-M3内核结构,结合 MCS-51单片机,分析其优缺点;掌握 ARM Cortex-M3内核寄存器组织、处理器运行模式、存储器映象、异常及其操作;了解存储器保护单元及应用;了解 ARM Cortex-M3调试组件的工作原理及应用 本章是 ARM Cortex-M3 微控制器体系结构分析,内容涉及内核结构、CPU 寄存器组织、存储器映射、异常形为及操作,在学习过程中与 8 位单片机(MCS-51 单片机、PIC 系列单片机等)结合分析,以期达到良好学习效果 2.1 ARM Cortex-M3处理器简介 2.1.1 概述 ARM公司成立于上个世纪九十年代初,致力于处理器内核研究,ARM 即 Advanced RISC Machines的缩写,ARM公司本身不生产芯片,只设计内核,靠转让设计许可,由合作伙伴公司来生产各具特色的芯片。

      这种运行模式运营的成果受到全球半导公司以及用户的青睐 目前ARM体系结构的处理器内核有:ARM7TDMI、ARM9TDMI、ARM10TDMI、ARM11以及Cortex等2005年ARM推出的ARM Cortex系列内核,分别为:A 系列、R 系列和M 系列,其中A 系列是针对可以运行复杂操作系统(Linux、Windows CE、Symbian等)的处理器;R 系列是主要针对处理实时性要求较高的处理器(汽车电子、网络、影像系统);M 系列又叫微控制器,对开发费用敏感,对性能要求较高的场合 Cortex-M系列目前的产品有M0、M1、M3,其中M1用在FPGA中Cortex-M系列对微控制器和低成本应用提供优化,具有低成本、低功耗和高性能的特点,能够满足微控制器设计师进行创新设计的需求其中,ARM Cortex-M3处理器的性能是ARM7的两倍,而功耗却只有ARM7的1/3,适用于众多高性能、极其低成本需求的嵌入式应用,如微控制器、汽车系统、大型家用电器、网络装置等,ARM Cortex-M3提供了32位微控制器市场前所未有的优势 Cortex-M3内核,内部的数据路径为32位,寄存器为32位,存储器接口也是32位。

      Cortex-M3采用了哈佛结构,拥有独立的指令总线和数据总线,可以让取指与数据访问分开进行Cortex-M3还提供一个可选的MPU,对存储器进行保护,而且在需要的情况下也可以使用外部的cache另外在Cortex-M3中,存储器支持小端模式和大端存储格式Cortex-M3内部还附赠了很多调试组件,用于在硬件水平上支持调试操作,如指令断点,数据观察点等另外,为支持更高级的调试,还有其它可选组件,包括指令跟踪和多种类型的调试接口 2.1.2 内核结构组成及功能描述 Cortex-M3微控制器内核包括处理核心和许多的组件,目的是用于系统管理和调试支持如图2.1为Cortex-M3内核方框图 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 2 页 图 2.1 Cortex-M3 内核方框图 1.处理器内核 Cortex-M3处理器内核采用ARMv7-M架构,其主要特性如下:  Thumb-2指令集架构(ISA)的子集,包含所有基本的16位和32位Thumb-2指令;  哈佛处理器架构,在加载/ 存储数据的同时能够执行指令取指;  带分支预测的三级流水线;  32位单周期乘法;  硬件除法; NVIC CM3核 MPU FPB AHB-AP DWT ITM APB ETM TPIU ROM表 SW-DP JTAG-DP 专用外设总线I-code 总线 D-code总线 系统总线 中断 睡眠 调试 NMI SLEEPING SLEEPDEEP 指令 数据 触发 专用外设总线(内部) Cortex-M3 中断号[239:0] 总线矩阵 总线矩阵 Flash存储器 SRAM可选配 系统总线(AHB) 静态 RAM 外部 RAM控制器 外部 RAM 外部设备 AHB to APB总线 外设总线 UART PWM Timer SysTick I/O 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 3 页  Thumb状态和调试状态;  处理模式和线程模式;  ISR的低延迟进入和退出;  可中断- 可继续(interruptible-continued)的LDM/STM、PUSH/POP;  支持ARMv6类型BE8/LE;  支持ARMv6非对齐访问。

      2.NVIC(嵌套向量中断控制器) NVIC与处理器内核是紧密耦合的,这样可实现快速、低延迟的异常处理在Cortex-M微控制器此功能非常强大 3.总线矩阵 总线矩阵用来将处理器和调试接口与外部总线相连 处理器包含4 个总线接口:  ICode 存储器接口:从Code 存储器空间(0x0000000–0x1FFFFFFF)的取指都在这条32 位AHBLite 总线上执行  DCode 存储器接口:对Code 存储器空间(0x0000000–0x1FFFFFFF)进行数据和调试访问都在这条32 位AHBLite 总线上执行  系统接口: 对系统空间 (0x20000000–0xDFFFFFFF) 进行取指、 数据和调试访问都在这条32 位AHBLite 总线上执行  外部专用外设总线(PPB):对外部PPB 空间(0xE0040000–0xE00FFFFF)进行数据和调试访问都在这条32 位APB 总线(AMBA v2.0)上执行跟踪端口接口单元(TPIU)和厂商特定的外围器件都在这条总线上 注:处理器包含一条内部专用外设总线,用来访问嵌套向量中断控制器(NVIC)、数据观察点和触发(DWT)、Flash 修补和断点(FPB),以及存储器保护单元(MPU)。

      4.FPB FPB单元实现硬件断点以及从代码空间到系统空间的修补访问,FPB有8 个比较器 5.DWT 数据观察点和跟踪,调试功能部件 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 4 页 6.ITM ITM是一个应用导向(application driven)的跟踪源,支持对应用事件的跟踪和printf类型的调试 7.MPU 存储器保护单元(MPU)是用来保护存储器的一个元件处理器支持标准的ARMv7“受保护的存储器系统结构”(PMSA)模型如果希望向处理器提供存储器保护,则可以使用可选的MPU;MPU对访问允许和存储器属性进行检验它包含8 个区和一个可选的执行默认存储器映射访问属性的背景区 8.ETM ETM支持指令跟踪的低成本跟踪宏单元 9.TPIU TPIU用作来自ITM和ETM(如果存在) 的Cortex-M3内核跟踪数据与片外跟踪端口分析仪之间的桥接 10.SW/JTAG-DP Cortex-M3处理器可配置为具有SW-DP或JTAG-DP调试端口的接口,或两者都有。

      这两个调试端口提供对系统中包括处理器寄存器在内的所有寄存器和存储器的调试访问 2.2 内核寄存器组织 如图 2.2所示,Cortex_M3内核寄存器分为 16 个通用寄存器 R0~R15和 7 个特殊功能寄存器 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 5 页 图 2.2 寄存器组织图 2.2.1 通用寄存器 R0-R15 R0~R12寄存器:是真正意义上的通用在处理器运行过程中,作数据的寄存 R13为堆栈指针寄存器:堆栈指针是用于访问堆栈,也即系统的 RAM区Cortex_M3中采用了两个堆栈指针:主堆栈指针(MSP)和进程堆栈指针(PSP),R13在任何时刻只能是其中一个,默认情况为MSP,可以通过控制寄存器(CONTORL)来改变Cortex_M3中堆栈方向是向低地址方向增长,为满堆栈机制堆栈操作是通过 PUSH和 POP来完成操作的 例如 MSP当前指针指向:0x2000_000C;R0=0x00000000 执行:PUSH R0 此时 MSP指向:0x2000_0008 执行示意如图 2.3所示。

      R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13(SP) R14(LR) R15(PC) MSP PSP 低寄存器 高寄存器 xPSR PRIMASK FAULTMASK BASEPRI CONTROL 通用寄存器 特殊功能寄存器 状态寄存器 中断屏蔽寄存器 控制寄存器 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 6 页 2.3 堆栈操作示意图 R14 程序连接寄存器(LR):在执行分支(B)和链接(BL)指令或带有交换分支(BX)和链接指令(BLX)时,PC 的返回地址自动保存进 LR比如在子程序调用时用保存子程序的返回地址LR也用于异常返回,但是在这里保存的是返回后的状态,不是返回的地址,异常返回是通过硬件自动出栈弹出之前压入的 PC 完成的 R15 程序计数器(PC):是程序运行的基础,具有自加的功能该寄存器的位 0 始终为 0,因此,指令始终与字或半字边界对齐 2.2.2 特殊功能寄存器 特殊功能寄存器分为程序状态寄存器、中断屏蔽寄存器和控制寄存器三类。

      xPSR程序状态寄存器:系统级的处理器状态可分为 3类,应用状态寄存器(APSR)、中断状态寄存器(IPSR)、执行状态寄存器(EPSR),可组合起来构成一个 32 位的寄存器,统称 xPSR 表 2.1 xPSR 寄存器 寄存 器名 位 31 30 29 28 27 26:25 24 23:20 19:16 15:10 9 8 7 6 5 4:0 APSR N Z C V Q IPSR 中断编号 EPSR ICI/IT T ICI/IT xPSR寄存器的各位的功能如表 2.2: 表 2.2 xPSR 寄存器各位功能 位 名称 定义 31 N 负数或小于标志:1:结果为负数或小于;0 结果为正数或大于 30 Z 零标志:1:结果为 0;0:结果为非 0 0x2000_000C 已使用 已使用 上次压入的数据 未用 未用 已使用 已使用 已使用 0x00000000 未用 MSP RAM RAM 0x2000_0008 MSP 向下生长 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 7 页 29 C 进位/借位标志:1:进位或借位;0 没有进位或借位 28 V 溢出标志:1:溢出;0:没有溢出 27 Q 粘着饱和标志:1:已饱和;0:没有饱和 26:25 15:10 IT IF-Then 位。

      它们是 if-Then 指令的执行状态位 包含 if-Then 模块的指令数目和它们的执行条件 24 T 用于指示处理器当前是 ARM 状态还是 Thumb 状态 15:12 ICI 可中断-可继续的指令位: 如果在执行 LDM 或 STM 操作时产生一次中断, 则 LDM或 STM 操作暂停,该位来保存该操作中下一个寄存器操作数的编号,在中断响应之后,处理器返回由该位指向的寄存器并恢复操作 8:0 ISR 占先异常的编号 中断屏蔽寄存器:分为三组,分别是 PRIMASK、FAULTMASK、BASEPRI PRIMASK为片上外设总中断开关,该寄存器只有位 0 有效,当该位为 0 是响应所有外设中断;当该位为 1 时屏蔽所有片上外设中断 FAULTMASK寄存器管理系统错误的总开关,该寄存器中有位 0 有效,当该位为 0 时,响应所有的异常;为 1 屏蔽所有的异常 BASEPRI寄存器用来屏蔽优先级等于和小于某一个中断数值的寄存器 控制寄存器:CONTROL有两个作用,其一用于定义处理器特权级别,其二用于选择堆栈指针,如表3.3所示 表 2.3 CONTROL 寄存器 位 功能 CONTROL[1] 堆栈指针选择 0:选择主堆栈指针 MSP 1:选择进程堆栈指针 PSP CONTROL[0] 0:特权级 1:用户级 CONTROL[0]:异常情况下,处理器总是处于特权模式,CONTROL[0]位总是为 0 ;程模式情况下(非异常情况),处理器可以工作在特权级也可工作在用户级,该位可为 0 或 1 。

      特权级下所有的资源都可以访问,而用户级下被限制的资源不能访问,比如 MPU被限制的资源 CONTROL[1]:为 0 时,只使用 MSP,此时用户程序和异常共享同一个堆栈,处理器复位后默认的也是该模式为 1 时,用户应用程序使用进程堆栈 PSP,而中断任然得使用主堆栈 MSP这种双堆栈机制,特别适合在带有 OS(操作系统)的环境下使用,只要 OS 内核在特权级下执行,而用户应用程序在用户模式下执行,就可很好的将代码隔离互不影响 2.3处理器操作模式 ARM Cortex-M3支持2 个模式和两个特权等级如图2.4所示,在嵌入式系统应用程序中,程序代码涉及异常服务程序代码和非异常服务程序代码, 这些代码可以工作在处理器特权级也可以工作在用户级 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 8 页 级, 但有区别 当处理器处程模式下时, 既可以使用特权级, 也可以使用用户级; 另一方面, handler模式总是特权级的在复位后,处理器进入线程模式+特权级 图 2.4 操作模式和特权等级 程模式+用户级下,对系统控制空间(SCS,0xE000E000~0xE000EFFF,包括NVIC、SysTick、MPU以及代码调试控制所用的寄存器)的访问将被禁止。

      除此之外,还禁止使用MRS/MSR访问,除了APSR之外的特殊功能寄存器如果操作,则对于访问特殊功能寄存器的,访问操作被忽略;而对于访问SCS空间的,将产生错误 在特权级下不管是任何原因产生了任何异常,处理器都将以特权级来运行其服务例程,异常返回后,系统将回到产生异常时所处的级别,同时特权级也可通过置位CONTROL[0]来进入用户级用户级下的代码不能再试图修改CONTROL[0]来回到特权级它必须通过一个异常handler,来修改CONTROL[0],才能在返回到线程模式后进入特权级如图2.5所示 图 2.5 处理器模式转换图 把代码按特权级和用户级分开处理,有利于使Cortex-M3的架构更加稳定可靠例如,当某个用户程序代码出问题时, 可防止处理器对系统造成更大的危害, 因为用户级的代码是禁止写特殊功能寄存器和NVIC中寄存器的另外,如果还配有MPU,保护力度就更大,甚至可以阻止用户代码访问不属于它的内存区域 在引入了嵌入式实时操作系统中,为了避免系统堆栈因应用程序的错误使用而毁坏,我们可以给应用程序专门配一个堆栈,不让它共享操作系统内核的堆栈在这个管理制度下,运行程模式的用户代码使用PSP,而异常服务例程则使用MSP。

      这两个堆栈指针的切换是智能全自动的,在异常服务的始末由Cortex-M3硬件处理 如前所述,特权等级和堆栈指针的选择均由CONTROL负责 Handler 模式 错误的用法 线程模式 线程模式 特权级 用户级 异常 handler 的代码 主应用程序的代码 启动代码 用户 程序 异常服务例程 用户 程序 异常服务例程 特权级的线程 特权级 handler模式 CONTROL[0]=1 特 权 级 线程模式 用 户 级 线程模式 异常 异常 CONTROL[0]=0 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 9 页 当CONTROL[0]=0,在异常处理的始末,只发生了处理器模式的转换,如图2.6所示 若CONTROL[0]=1(线程模式+ 用户级),则在中断响应的始末,处理器模式和特权等级都要发生变化,如图2.7所示 CONTROL[0 ]只有在特权级下才能访问用户级的程序如想进入特权级,通常都是使用一条“系统服务呼叫指令(SVC)”来触发“SVC异常”,该异常的服务例程可以视具体情况而修改CONTROL[0]。

      图 2.6 中断前后的状态转换 图 2.7 中断前后的状态转换+特权等级切换 2.4存储器系统 2.4.1 存储器映射 Cortex-M3采用了固定的存储映射结构,如图 2.8所示 Cortex-M3的地址空间是 4GB, 程序可以在代码区, 内部 SRAM区以及外部 RAM区中执行 但是因为指令总线与数据总线是分开的, 最理想的是把程序放到代码区, 从而使取指和数据访问各自使用己的总线 内部 SRAM区的大小是 512MB,用于让芯片制造商连接片上的 SRAM,这个区通过系统总线来访问在这个区的下部,有一个 1MB的区间,被称为“位带区”该位带区还有一个对应的 32MB的 “位带别主程序 中断事件 入栈 出栈 中断返回 中断服务程序 线 程 模 式(用户级) Handler模 式(特权级) 线 程 模 式(用户级) t主程序 中断事件 入栈 出栈 中断返回 中断服务程序 线 程 模 式(特权级) Handler模 式(特权级) 线 程 模 式(特权级) t 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 10 页 名(alias)区”,容纳了 8M 个“位变量”(对比 8051的只有 128个位变量),位带区对应的是最低的1MB地址范围,而位带别名区里面的每个字对应位带区的一个比特。

      位带操作只适用于数据访问,不适用于取指通过位带的功能,可以把多个布尔型数据打包在单一的字中,却依然可以从位带别名区中,像访问普通内存一样地使用它们 位带别名区中的访问操作是原子的, 消灭了传统的“读-改-写”三步 图 2.8 Cortex-M3 存储器映射图 片上外设对应 512MB的空间, 芯片上所有与外围设备相关的寄存器都位于该区域 这个区中也有一条 32MB的位带别名,以便于快捷地访问外设寄存器,用法与内部 SRAM区中的位带相同例如,可以方便地访问各种控制位和状态位要注意的是,外设区内不允许执行指令通常半导体厂商就是修改此区域的片上外设,来达到各具特色的、个性化的设备 还有两个 1GB的范围,分别用于连接外部 RAM和外部设备,它们之中没有位带两者的区别在于外芯片厂商定义 内核私有区域512MB 0xFFFFFFFF 0xE0100000 0xE00FFFFF 0xE0040000 0xE003FFFF 0xE0000000 0xDFFFFFFF 0xA0000000 0x9FFFFFFF 0x60000000 0x5FFFFFFF 0x40000000 0x3FFFFFFF 0x20000000 0x1FFFFFFF 0x00000000 外部私有外设总线 内部私有外设总线 片外外设 1.0GB 片外 RAM 1.0GB 片上外设区 512MB 片上 SRAM 512MB 代码区 512MB 0xE00FFFFF ROM 0xE00FF000 0xE0042000 外部 PPB 0xE0041000 ETM 0xE0040000 TPIU 0xE003FFFF 保留 0xE000F000 0xE000E000 NVIC 0xE0003000 保留 0xE0002000 FPB 0xE0001000 DWT 0xE0000000 ITM 0x43FFFFFF 32MB位带别名区 0x42000000 0x41FFFFFF 31MB 0x40100000 0x40000000 1MB位带区 0x23FFFFFF 32MB位带别名区 0x22000000 0x21FFFFFF 31MB 0x20100000 0x20000000 1MB位带区 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 11 页 部 RAM区允许执行指令,而外部设备区则不允许。

      最后还剩下 0.5GB的隐秘地带,包括了系统级组件,内部私有外设总线,外部私有外设总线,以及由提供者定义的系统外设 私有外设总线有两条: AHB私有外设总线,只用于 CM3内部的 AHB外设,它们是:NVIC, FPB, DWT和 ITM APB私有外设总线, 既用于 CM3内部的 APB设备, 也用于外部设备 (这里的“外部”是对内核而言) Cortex-M3允许器件制造商再添加一些片上 APB外设到 APB私有总线上,它们通过 APB接口来访问 NVIC所处的区域叫做“系统控制空间(SCS)”,在 SCS里的除了 NVIC外,还有 SysTick、MPU以及代码调试控制所用的寄存器 最后,未用的提供商指定区也通过系统总线来访问,但是不允许在其中执行指令 2.4.2 位带操作 在Cotex-M3存储器映射中包括两个位操作区分别位于SRAM和片上外设存储区的最低1MB空间中这两个位带中的地址除了可以像普通的RAM一样使用外,它们还都有自己的“位带别名区”,位带别名区把每个比特膨胀成一个32位的字形成位地址 当你通过位带别名区访问这些字时, 就可以达到访问原始比特的目的,其对应关系如图2.8所。

      位地址与位别名对应关系统如下: 对于 SRAM位带区的某个位: 4)8)200000000((220000000nxAxAliasaddr 432)200000000(220000000nxAx 对于片上外设位带区的某个位: 4)8)400000000((420000000nxAxAliasaddr 432)400000000(420000000nxAx 在上述表达式中,A 表示要操作的位所在的字节地址,n (0 ≤n ≤7 )表示位序号 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 0x23FFFFFC 0x23FFFFF8 0x23FFFFF4 0x23FFFFF0 0x23FFFFEC 0x23FFFFE8 0x23FFFFE4 0x23FFFFE0 0x2200001C 0x22000018 0x22000014 0x22000010 0x2200000C 0x22000008 0x22000004 0x22000000 0x200FFFFC 0x200FFFFD 0x200FFFFE 0x200FFFFF 0x20000000 0x20000001 0x20000002 0x20000003 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 位带别名区(共 32MB) SRAM位带区(共 1MB) 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 12 页 2.9 位操作对应关系图 举例:将地址 0x20000000的第 2 位置 1 。

      通过上述计算关系,可计算出位带别名为 0x22000008如程序清单 L2.1所示 程序清单 L2.1 SRAM 位操作实例 LDR R0,=0x22000008 LDR R1,=0x01 STR R1,[R0] 将片上外设I/O端口的A 口的第0 位 (也即PORTA0) 为输出, 其A 口的方向寄存器地址为0x40004400,设置 1 作为输出,可根据上述关系计算出位带别名为 0x42088000如程序清单 L2.2所示 程序清单 L2.2 片上外设位操作实例 LDR R0,=0x42088000 LDR R1,=0x01 STR R1,[R0] 注:采用大端格式时,对位邦定别名区的访问必须以字节方式,否则访问不可预知 2.5异常 ARM Cortex-M3中异常涉及异常的类型、优先级、向量表等,本节并以 Luminary系列微控制器为例说明异常的具体行为 2.5.1 异常类型 在 Cortex-M3中有一个与内核紧耦合部件叫嵌套向量中断控制器(NVIC,Nested Vectored Interrupt Controller), 定义了 16 种系统异常和 240路外设中断。

      通常芯片设计者可自由设计片上外设,因此具体的片上外设中断都不会用到多达 240路如表 2.4所示系统异常类型,表 2.5所示为外设中断类型 Cortex-M3中目前只有 11 种系统异常可用分别是:系统复位、NMI(不可屏蔽中断)、硬件故障、存储器管理、总线故障、用法故障、SVCall(软件中断)、调试监视器中断、PendSV(系统服务请求) 、SysTick(24 位定时器中断)240路外设中断,是指片上外设的各模块,比如 I/O口、UART通信接口、SSI总线接口等所需的中断 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 13 页 表 2.4 异常类型 编号 类型 优先级 描述 0 - - 复位时载入向量表的第一项作为主堆栈栈顶地址 1 复位 -3 复位 2 NMI -2 不可屏蔽中断(来自外部 NMI输入脚) 3 硬故障 -1 当故障由于优先级或者是可配置的故障处理程序被禁止的原因而无法激活时,所有类型故障都会以硬故障的方式激活 4 存储器管理 可编程 MPU不匹配,包括访问冲突和不匹配。

      5 总线故障 可编程 预取指故障、存储器访问故障和其它地址/ 存储器相关的故障 6 用法故障 可编程 由于程序错误导致的异常, 通常是使用一条无效指令, 或都是非法的状态转换 7-10 保留 - 保留 11 SVCall 可编程 执行 SVC指令的系统服务调用 12 调试监视器 可编程 调试监视器(断点,数据观察点,或是外部调试请求) 13 保留 - 14 PendSV 可编程 系统服务的可触发(pendable)请求 15 SysTick 可编程 系统节拍定时器 表 2.5 中断类型 编号 类型 优先级 描述 16 IRQ #0 可编程 外设中断 #0 17 IRQ #1 可编程 外设中断 #1 „ „ … … 255 IRQ #239 可编程 外设中断 #239 2.5.2 优先级 Cortex-M3的异常功能非常强大,机制非常灵活,异常可以通过占先、末尾连锁和迟来等处理来降低中断的延迟优先级决定了处理器何时以及怎样处理异常 Cortex-M3支持 3 个固定的高优先级和多达 256级的可编程优先级,并且支持 128级抢占,绝大多数芯片都会精简设计,实际中支持的优先级数会更少,如 8 级、16 级、32 级等,通常的做法是裁掉表达优先级的几个低端有效位(防止优先级反转),以减少优先级的级数。

      比如 Luminary的芯片采用 8级优先级 Cortex-M3中 NVIC支持由软件指定的可配置的优先级(称为软件优先级),其寄存器地址为:0xE000_E400-0xE000_E4EF通过对中断优先级寄存器的 8 位 PRI_N区执行写操作,来将中断的优先级指定为 0-255硬件优级随着中断中的增加而降低0优先级最高,255优先级最低指定软件优先级 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 14 页 后, 硬件优先级无效 例如: 如果将 INTISR[0]指定为优先级 1 , INTISR[31]指定为优先级 0 , 则 INTISR[0]的优先级比 INTISR[31]低 为了对具有大量中断的系统加强优先级控制,Cortex-M3支持优先级分组,通过 NVIC控制,设置为占先优先级和次优先级可通过对应用程序中断及复位控制寄存器(AIRCR,地址为:0xE000_ED00)的[10:8]位进行设置 如果有多个激活异常共用相同的组优先级, 则使用次优先级区来决定同组中的异常优先级,这就是同组内的次优先级。

      如表 2.6应用程序中断及复位控制寄存器,表 2.7为占先优先级和次优级的关系 表 2.6 应用程序中断及复位控制寄存器(AIRCR,地址:0xE000ED00) 位段 名称 类型 复位值 描述 [31:16] VECTKEY RW - 访问钥匙:任何对该寄存器的写操作,都必须同时把 0x05FA写入此段,否则写操作被忽略若读取此半字,则读回值为 0xFA05 15 ENDIANESS R - 指示端设置1 :大端,0 :小端 [10:8] PRIGROUP R/W 0 优先级分组 2 SYSRESETREQ W - 请求芯片控制逻辑产生一次复位 1 VECTCLRACTIVE W - 清零所有异常的活动状态信息通常只在调试时用,或都在OS 从错误中恢复时用 0 VECTRESET W - 复位 Coretex-M3微控制器内核 表 2.7 抢占优先级和次优先级分组位置的关系 分组位置 表达抢占优先级的位段 表达亚优先的位段 0 [7:1] [0:0] 1 [7:2] [1:0] 2 [7:3] [2:0] 3 [7:4] [3:0] 4 [7:5] [4:0] 5 [7:6] [5:0] 6 [7:7] [6:0] 7 无 [7:0]所有位 注: 表 2.7显示了利用优先级的 8 个位来配置处理器优先级。

      如果使用小于 8 的位来配置处理器的优先级,则寄存器的低位始终为 0 ,例如,如果使用 3 个位来配置优先级,则 PRI_N[7:5]用来配置优先级,而 PRI_N[4:0]为 4 ‵b0000 2.5.3 中断向量表 当发生了异常并且要响应它时,Cortex-M3需要定位其服务例程的入口地址这此入口地址存储在 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 15 页 所谓“异常向量表”中缺省情况下,Cortex-M3认为该表位于零地址处,且各向量占用 4 字节因此每个表项占用 4 字节,复位后的向量表如表 2.8所列 表 2.8 复位后向量表 地址 异常编号 值(32 位整数) 0x0000_0000 - MSP的初始值 0x0000_0004 1 复位向量(PC 初始值) 0x0000_0008 2 NMI服务例程的入口地址 0x0000_000C 3 硬 fault服务例程的入口地址 … … 其它异常服务例程的入口地址 向量表中的第 1 个字为指向堆栈栈顶的指针,复位时内核读取该地址的数据设置主堆栈。

      向量表的基地址可以通过 NVIC中的向量偏移寄存器(0xE000ED08)来设置,如表 2.9所示从表中可以看出,可以将异常向量表放在 Code区也可以将其放在 RAM区,起始地址也可改变,起始地址是有要求的:必须先求出系统中共有多少个向量,再把这个数字向上记到 2 的整次幂,而起始地址必须对齐到后者的边界上例如,如果一共有 32 个中断,则共有 32+16(系统异常)=48个向量,向上记到 2的整数次幂后值为 64,因此向量表重定位的地址必须能被 64 X 4=256整除 表 2.9 向量偏移量寄存器(0xE000ED08) 位段 名称 类型 复位值 描述 29 TBLOFF R - 向量表是在 Code区(0 ),还是在 RAM区(1 ) 7-28 TBLBASE R/W 0 向量表的起始地址 向量表中至少需要有 4 个值: 栈顶地址; 复位程序的位置; NMI异常的位置; 硬故障的异常的位置 当中断使能时,不管向量表的位置在哪,它指向所有使能屏蔽的异常并且如果使用 SVC指令,还需要指定 SVCCall ISR的位置 2.5.4 异常的进入与退出 1.异常进入 入栈:当处理器发生异常时,首先自动把 8 个寄存器(xPSR、PC、LR、R12、R3、R2、R1、R0)压入栈, 处理器自动完成, 在自动入栈的过程中, 把寄存器写入栈的时间顺序, 并不是写入空间相对应的,但机器会保证正确的寄存器被保存到正确的位置,如图 2.10所示, 假设入栈,栈地址为 N 。

      四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 16 页 2.10 内部入栈示意图 取向量:发生异常,紧接着内核将根据向量表找出正确的异常向量,然后在服务程序的入口处预取指,处理器将取指与取数据分别能过总线控制,使入栈与取指这两项工作能同时进行,以便快速进入中断 更新寄存器:入栈和取向量操作完成之后,在执行服务程序之前,还必须更新一系列寄存器 SP:在入栈后会把堆栈指针(PSP或MSP)更新到新的位置在执行服务例程时,将由MSP负责对堆栈的访问 PSR:更新IPSR位段(地处PSR的最低部分)的值为新响应的异常编号 PC :在取向量完成后,PC 将指向服务例程的入口地址, LR :在出入ISR的时候,LR 的值将得到重新的诠释,这种特殊的值称为“EXC_RETURN”,在异常进入时由系统计算并赋给LR ,并在异常返回时使用它 以上是在响应异常时通用寄存器及特殊功能寄存器的变化 另外在NVIC中, 也会更新若干个相关寄存器 2.异常退出 当异常服务程序最后一条指令将进入异常时的 LR 的值加载到 PC 中。

      该操作指示中断服务结束, 在从异常返回时处理器将执行下列操作之一: 如果激活异常的优先级比所有被压栈(等待处理)的异常的优先级都高,则处理器会末尾连锁到一个激活异常 如果没有激活异常, 或者如果被压栈的异常的最高优先级比激活异常的最高优先级要高, 则处理器返回到上一个被压栈的中断服务程序 如果没有激活的中断或被压栈的异常,则处理器返回线程模式 在启动了中断返回序列后,下述的处理就将进行: 出栈:先前压入栈中的寄存器在这里恢复内部的出栈顺序与入栈时的相对应,堆栈指针的值也改回先前的值 更新NVIC寄存器:伴随着异常的返回,它的活动位也被硬件清除对于外部中断,倘若中断输入再次被置为有效,悬起位也将再次置位,新一次的中断响应序列也可随之再次开始 异常返回值:异常返回值存放在LR 中这是一个高28位全为1 的值,只有[3:0]的值有特殊含义,如表2.10所示当异常服务例程把这个值送往PC 时,就会启动处理器的中断返回序列因为LR 的值是由N-8 N-4 N-32 N-28 N-24 N-20 N-16 N-12 地址 PC PSR R0 R1 R2 R3 R12 LR 数据 时间 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 17 页 Cortex-M3自动设置的,所以只要没有特殊需求,就不要改动它。

      表 2.10 EXC_RETURN 各位含义 位段 含义 [31:4] EXC_RETURN的标识:必须全为1 3 0=返回后进入处理器模 1=返回后进入线程模式 2 0=从主堆栈中做出栈操作,返回后使用MSP 1=从进程堆栈中做出栈操作,返回使用PSP 1 保留,必须为0 0 0=返回ARM状态 1=返回Thumb状态Cortex-M3中必须为1 因此,上述表格中EXC_RETURN的值有三种情况: 0xFFFF_FFF1:返回处理器模式; 0xFFFF_FFF9:返回线程模式,并使用主堆栈; 0xFFFF_FFFD:返回线程模式,并使用线程堆栈 例如系统中使用了PendSV异常,服务程序结束时由处理模式返回到线程模式前使用进程堆栈,如程序清单L2.3所示 程序清单 L2.3 异常返回类型实例 OSPendSV „„ ;异常服务程序 LDR LR,=0Xfffffffd ;返回到线程模式进程堆栈 BX LR 2.5.5 Cortex-M3 异常处理机制 1.末尾连锁 末尾连锁能够在两个中断之间没有多余的状态保存和恢复指令的情况下实现异常背对背处理。

      如图2.11所示在退出 ISR并进入另一个中断时,处理器省略了 8 个寄存器的出栈和入栈操作如果当前挂起中断的优先级比所有被压栈的异常的优先级都高 则处理器执行末尾连锁机制 如果挂起中断的优先级比被压栈的异常的最高优先级都高,则省略压栈和出栈操作,处理器立即取出挂起的中断向量在退出前一个 ISR之后,开始执行被末尾连锁的 ISR 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 18 页 图 2.11 末尾连锁示意图 2.异常迟来 在 Cortex-M3中迟来中断的意思是如果前一个 ISR还没有进入执行阶段, 并且迟来中断的优先级比前一个中断的优先级要高,则迟来中断能够抢占前一个中断如图 2.12所示 图 2.12 迟来异常示意图 响应迟来中断时需执行新的取向量地址和 ISR预取操作 迟来中断不保存状, 因为状态保存已经被最初的中断执行过了,因此不需要重复执行 2.5.6 嵌套向量中断控制器 嵌套向量中断控制器,简称NVIC,完成对中断的响应NVIC共支持1 至240个外部中断输入(通常外部中断写作IRQs)。

      具体的数值由芯片厂商在设计芯片时决定 NVIC的访问地址是0xE000_E000 所有NVIC的中断控制/ 状态寄存器都只能在特权级下访问 不过有一个例外软件触发中断寄存器可以在用户级下访问以产生软件中断 所有的中断控制、 状态寄存器均可按字、半字、字节的方式访问 中断配置内容:  使能与禁止寄存器  挂起与解挂寄存器 用户程序 中断 1 压栈 优先级 3 中断 1 优先级 2 中断 2 中断 2 出栈 继 续 压 栈用户程序 中断 1 压栈 优先级 3 中断 1 优先级 2 中断 2 中断 1 结束 中断 2 出栈 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 19 页  优先级寄存器  活动状态寄存器 另外,下列寄存器也对中断处理有重大影响:  异常掩蔽寄存器  向量表偏移寄存器  软件触发中断寄存器  优先级分组寄存器 Cortex-M3中异常及中断的行为如图 2.13所示分成三级,由 NVIC负责管理 图 2.13 异常和中断控制示意图 1.中断的使能与禁止 此处的中断使能与禁止,主要是针对片上外设 240路中断的控制,使能是向 SETENA寄存器对应位写“1 ”,禁止是向 CLRENA寄存器对应位写“1 ”。

      如表 2.11所示 表 2.11 SETENA/CLRENA 寄存器族 名称 类型 地址 复位值 描述 SETENA0 R/W 0xE000_E100 0 中断 0-31的使能寄存,共 32 个使能位[n],中断#n 使能(异常号 16+n) SETENA1 R/W 0xE000_E104 0 中断 32-63使能寄存器,共 32 个使能位 „ „ „ „ „ SETENA7 R/W 0xE000_E11C 0 中断 224-239使能寄存器,16 个使能位 中断挂起 NVIC_PEND 中断解挂 NVIC_CLRPEND 中断使能 NVIC_EN 中断禁止 NVIC_DIS 激活位设置 NVIC_ACTIVE 中断控制及状态寄存器 NVIC_INT_CTRL NVIC_PRI 优先级设置 NVIC_SYS_PRI 系统处理控制与状态寄存器 NVIC_SYS_HAND_CTRL 外设中断源 系统异常源 PRIMASK FLAUTMASK 内核 优先级设置 NVIC_PRI 第三级 第二级 第一级 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 20 页 CLRENA0 R/W 0xE000_E180 0 0-31禁止,共 32 个禁止位 „ „ „ „ „ CLRENA7 R/W 0xE000_E19C 0 224-239的禁止寄存器,共 16 个禁止 在 Luminary系列的单片机中,片上外设中断对应编号如 2.12表所示: 表 2.12 Luminary 单片机外设中断源 编号 类型 优先级 描述 0 IRQ #0 可编程 GPIOA 1 IRQ #1 可编程 GPIOB 2 IRQ #2 可编程 GPIOC 3 IRQ #3 可编程 GPIOD 4 IRQ #4 可编程 GPIOE 5 IRQ #5 可编程 UART0 6 IRQ #6 可编程 UART1 7 IRQ #7 可编程 SSI 8 IRQ #8 可编程 I2C 9 IRQ #9 可编程 PWM_Fault 10 IRQ #10 可编程 PWM0 11 IRQ #11 可编程 PWM1 12 IRQ #12 可编程 PWM2 13 IRQ #13 可编程 QEI 14 IRQ #14 可编程 ADC0 15 IRQ #15 可编程 ADC1 16 IRQ #16 可编程 ADC2 17 IRQ #17 可编程 ADC3 18 IRQ #18 可编程 Watchdog 19 IRQ #19 可编程 T0A 20 IRQ #20 可编程 T0B 21 IRQ #21 可编程 T1A 22 IRQ #22 可编程 T1B 23 IRQ #23 可编程 T2A 24 IRQ #24 可编程 T2B 25 IRQ #25 可编程 Analog_comparator0 26 IRQ #26 可编程 Analog_comparator1 27 IRQ #27 可编程 Analog_comparator2 28 IRQ #28 可编程 System_Control 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 21 页 29 IRQ #29 可编程 FLASH_Control 30 IRQ #30 可编程 GPIOF 31 IRQ #31 可编程 GPIOG 32 IRQ #32 可编程 GPIOH 33 IRQ #33 可编程 UART2 34 IRQ #34 可编程 SSI1 35 IRQ #35 可编程 T3A 36 IRQ #36 可编程 T3B 37 IRQ #37 可编程 I2C1 38 IRQ #38 可编程 QEI1 39 IRQ #39 可编程 CAN0 40 IRQ #40 可编程 CAN1 41 IRQ #41 可编程 CAN2 42 IRQ #42 可编程 Ethernet 43 IRQ #43 可编程 Hibernate 44 IRQ #44 可编程 USB0 45 IRQ #45 可编程 PWM3 46 IRQ #46 可编程 uDMA Software Transfer 47 IRQ #47 可编程 uDMA Error 这 8 个寄存器用于控制 240外设中断的使能与禁止,向其中的对应位写入 1 可以使能相应的中断,中断使能设置寄存器 0 的位 0 对应外部中断 0 号 (GPIOA中断) , 位 1 对应外部中断 1 号 (GPIOB中断) ,依此类推,如表 3.2所示。

      例如使能外部中断 2 的操作,如程序清单 L2.3所示 程序清单 L2.3 使能外部中断 #define HWREG(x) (*((volatile unsigned char *)(x))) #define NVIC_EN0 0xE000 E100 // IRQ0~IRQ31中断使能设置寄存器 HWREG(NVIC_EN0)=1<<2; // 使能外部 2 号中断,即 GPIOC中断 2.中断的挂起与解挂 当中断发生时,正在处理同级或高优先级异常,或者被掩蔽,则中断不能立即得到响应此时中断被挂起 中断的挂起状态可以通过“中断设置挂起寄存器(SETPEND)”和“中断解挂寄存器(CLRPEND)”来读取,还可以写它们来手工挂起中断 挂起寄存器和解挂寄存器也可以有8 对,其用法与前面介绍的使能、禁止能寄存器完全相同,见表2.13 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 22 页 表 2.13 挂起与解挂寄存器 名称 类型 地址 复位值 描述 SETPEND0 R/W 0xE000_E200 0 中断 0-31的使能寄存,共 32 个使能位[n],中断#n 使能(异常号 16+n) SETPEND1 R/W 0xE000_E204 0 中断 32-63使能寄存器,共 32 个挂起位 „ „ „ „ „ SETPEND7 R/W 0xE000_E21C 0 中断 224-239挂起寄存器,16 个挂起位 CLRPEND0 R/W 0xE000_E280 0 0-31解挂,共 32 个解挂位 „ „ „ „ „ CLRPEND7 R/W 0xE000_E29C 0 224-239的解挂寄存器,共 16 个解挂 3.活动状态 每个外部中断都有一个活动状态位。

      在处理器执行了其ISR的第一条指令后,它的活动位就被置1 ,并且直到ISR返回时才硬件清零由于支持嵌套,允许高优先级异常抢占某个ISR然而,哪怕中断被抢占, 其活动状态也依然为1 (请仔细琢磨前文讲到的“直到ISR返回时才清零) 活动状态寄存器的定义,与前面讲的使能、禁止和挂起、解挂寄存器相同,只是不再成对出现它们也能按字、半字、字节访问,但他们是只读的,如表2.14所示 表 2.14 活动状态 名称 类型 地址 复位值 描述 ACTIVE0 RO 0xE000_E300 0 中断 0-31的活动状态寄存器,共 32 个状态位[n],中断#n 活动状态(异常号16+n) ACTIVE1 RO 0xE000_E304 0 中断 32-63的活状态寄存器,共 32 个状态位 „ „ „ „ „ ACTIVE7 RO 0xE000_E31C 0 中断 224-239的活动状态寄存器,共 16 个状态位 4.优先级 使用优先级寄存器将 0 到 255个优先级分别分配给各个中断0 代表最高优先级,255则代表最代优先级 优先级寄存器首先存放最高位当优先级值为 3 位时,存放在字节的位[7:5]中。

      这也意味着某个应用即使不知道可能含有多少个优先级也可以正常工作 从 0xE000_E400开始的地址里,每一个字节对应一个外部中断,例如:0xE000_E400对应外部中断GPIOA、这个字节可以设置 GPIOA的中断优先级、0xE000_E401对应外部中断 GPIOB、这个字节可以设置GPIOB的中断优先级,依次类推如表 2.15所示 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 23 页 表 2.15 优先级表 名称 类型 地址 复位值 描述 PRI_0 R/W 0xE000_E400 0 GPIOA,8 位 PRI_1 R/W 0xE000_E401 0 GPIOB,8 位 „ „ „ „ „ PRI_239 R/W 0xE000_E4EF 0 外中断#239的优先级 系统部分异常也可以编程实验优先设置,如表 2.16所示 表 2.16 系统异常优先级寄存器 地址 名称 类型 复位值 描述 0xE000_ED18 PRI_4 存储器管理 fault的优先级 0xE000_ED19 PRI_5 总线 fault的优先级 0xE000_ED1A PRI_6 用法 fault的优先级 0xE000_ED1B - - - - 0xE000_ED1C - - - - 0xE000_ED1D - - - - 0xE000_ED1E - - - - 0xE000_ED1F PRI_11 SVC优先级 0xE000_ED20 PRI_12 调试监视器的优先级 0xE000_ED21 - - - - 0xE000_ED22 PRI_14 PendSV的优先级 0xE000_ED23 PRI_15 SysTick的优先级 设置 Luminary处理器外部中断优先级:外部 2 号中断> 外部 12 号中断> 外部 7 号中断> 外部 4 号中断,并且 4 号中断的优先级为最低,如程序清单 L2.4所示。

      程序清单 L2.4 设置外部中断优先级 #define HWREGB(x) (*((volatile unsigned char *)(x))) #define PRI2 0xE000E402 // 2号中断优先级设置寄存器 #define PRI4 0xE000E404 // 4号中断优先级设置寄存器 #define PRI7 0xE000E407 // 7号中断优先级设置寄存器 #define PRI12 0xE000E40C // 12号中断优先级设置寄存器 HWREGB(PRI4)=7<<5; // 最低优先级 HWREGB(PRI7)=6<<5; // 优先级比 4 号中断高 HWREGB(PRI12)=5<<5; // 优先级比 7 号中断高 HWREGB(PRI2)=4<<5; // 优先级比 12 号中断高 设置系统异常 PendSV优先级为 7 ,如程序清单 L2.5所示,用汇编实现。

      四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 24 页 程序清单 L2.5 系统异常优先设置(PendSV) LDR R4, =0xE000ED22 ; PendSV的优先级寄存器 LDR R5, =0xFF ; 优先级最高三位为 b111,即为最低(8 位) STR R5, [R4] 5.异常屏蔽寄存器 PRIMASK、FAULTMASK、BASEPRI PRIMASK用于禁止在NMI和硬fault之外的所有异常, 它有效地把当前优先级改为0 (可编程优先级中的最高优先级)该寄存器可以通过MRS和MSR以下例方式访问: ①. 关中断 MOV R0, #1 MSR PRIMASK, R0 ②. 开中断 MOV R0, #0 MSR PRIMASK, R0 此外,还可以通过CPS指令快速完成上述功能: CPSID i ;关中断 CPSIE i ;开中断 FAULTMASK更绝,它把当前优先级改为-1。

      这么一来,连硬fault都被掩蔽了使用方案与PRIMASK的相似但要注意的是,FAULTMASK会在异常退出时自动清零 BASEPRI主要屏蔽优先级等于和低于某一个数值的异常 6.其他异常的配置寄存器 用法fault,总线fault以及存储器管理fault都是特殊的异常,因此给它们开了小灶其中,它们的使能控制是通过“系统Handler控制及状态寄存器(SHCSR)”(地址:0xE000_ED24)来实现的各种faults的悬起状态和大多数系统异常的活动状态也都在该寄存器中,如表2.17所示 表 2.17 系统异常控制及状态寄存器 SHCSR(地址:0xE000_ED24) 位段 名称 类型 复位值 描述 18 USGFAULTENA R/W 0 用法 fault服务例程使能位 17 BUSFAULTENA R/W 0 总线 fault服务例程使能位 16 MEMFAULTENA R/W 0 存储器管理 fault服务例程使能位 15 SVCALLPENDED R/W 0 SVC挂起中本来已经要 SVC服务例程,但是却 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 25 页 被更高优先级异常取代 14 BUSFAULTPENDED R/W 0 总线 fault挂起中,细节同上 13 MEMFAULTPENDED R/W 0 存储器管理 fault挂起中,细节同上 12 USGFAULTPENDED R/W 0 用法 fault挂起中,细节同上 11 SYSTICKACT R/W 0 SysTick异常活动 10 PENDSVACT R/W 0 PendSV异常活动中 9 - 8 MONITORACT R/W 0 Monitor异常活动中 7 SVCALLACT R/W 0 SVC异常活动中 6:4 - 3 USGFAULTACT R/W 0 用法 fault异常活动中 2 - 1 BUSFAULTACT R/W 0 总线 fault异常活动中 0 MEMFAULTACT R/W 0 存储器管理 fault异常活动中 中断控制及状态寄存器ICSR(0xE000_ED04)。

      对于NMI、SysTick定时器以及PendSV,可以通过此寄存器手工悬起它们另外,在该寄存器中,有好多位段都用于调试目的在大多数情况下,它们对于应用软件都没有什么用处,只有悬起位对应用程序常常比较有参考价值,如表2.18所示 表 2.18 中断控制及状态寄存器 ICSR(地址:0xE000_ED04) 位段 名称 类型 复位值 描述 31 NMIPENDSET R/W 0 写 1 可挂起 NMI 28 PENDSVSET R/W 0 写 1 可挂起 PendSV 27 PENDSVCLR W 0 写 1 可清除 PendSV 26 PENDSTSET R/W 0 写 1 可以挂起 SysTick 25 PENDSTCLR W 0 写 1 可清除 SysTick挂起状态 23 ISRPREEMPT R 0 =1 表示一挂起中断将在下一步时进入活动状态 22 ISRPENDING R 0 =1,当前正有外部中断被挂起(不包括 NMI) 21:12 VECTPENDING R 0 挂起的 ISR的编号 11 RETTOBASE R 0 如果异常返回后将回到基级, 并且没有其他异常挂起时,此位为 1 。

      9:0 VECTACTIVE R 0 当前活动的 ISR编号 中断控制与状态寄存器 31 位、28 位、26 位置位可分别挂起 NMI、PendSV、SysTick中断,比如在μ C/OS-II操作系统中,任务切换实际就是去触发一次 PendSV完成,如程序清单 L2.6所示 程序清单 L2.6 PendSV 实现异常 汇编实现方式: MOV R0, #0 ;初值 R0=0 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 26 页 LDR R4,=0xE000ED04 ;中断控制及状态寄存器, 第 28 位置 1 表示挂起 PendSV LDR R5,=0x10000000 ;第 28 位为 1 STR R5,[R4] PendSV ;PendSV中断服务程序 MOV R0, #1 ; ;服务程序使 R0=1 BX LR 或 C 语言实现方式: #define NVIC_INT_CTRL 0xE000 ED04 unsigned char i; void PendSV(void) { i=0; HWREG(NVIC_INT_CTRL)=1<<28; } void PendSV_ISR(void) { i=1; } 7.软件中断 软件中断,包括手工产生的普通中断,能以多种方式产生。

      最简单的就是使能相应的SETPEND寄存器;而更专业更快捷的作法,则是通过使用软件触发中断寄存器STIR,如表2.19所示 表 2.19 软件触发中断寄存器 STIR(0xE000_EF00) 位段 名称 类型 复位值 描述 8:0 INTID W - 影响编号为 INTID的外部中断, 其挂起位被置位例如,写入 8 ,则挂 IRQ#8 程序清单 L2.7通过软件触发一次外部中断 GPIOC口中断 程序清单 L2.7 软件触发外部 2 号中断 #include #define HWREG(x) (*((volatile unsigned long *)(x))) 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 27 页 #define uchar unsigned char #define NVIC_EN0 0xE000E100 // 中断使能寄存器 SETENA/CLRENA #define NVIC_SW_TRIG 0xE000EF00 // 软件触发中断寄存器 STIR uchar a=0; void IRQ2_HandlerCode(void) // 外部 2 号中断服务程序 { a=1; } int main(void) { HWREG(NVIC_EN0)=1<<2; // 设置 2 号外涉中断(GPIOC)使能 HWREG(NVIC_SW_TRIG)=2; // 软件触发一次 2 号外涉中断(GPIOC) while(1); } 8.SysTick 定时器 SysTick定时器被捆绑在NVIC中,用于产生SysTick异常(异常号:15)。

      在以前,操作系统还有所有使用了时基的系统,都必须一个硬件定时器来产生需要的“滴答”中断,作为整个系统的时基滴答中断对操作系统尤其重要例如,操作系统可以为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统; 或者把每个定时器周期的某个时间范围赐予特定的任务等, 还有操作系统提供的各种定时功能,都与这个滴答定时器有关因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律 Cortex-M3处理器内部包含了一个简单的定时器因为所有的CM3芯片都带有这个定时器,软件在不同 CM3器件间的移植工作就得以化简该定时器的时钟源可以是内部时钟(FCLK,CM3上的自由运行时钟),或者是外部时钟( CM3处理器上的STCLK信号)不过,STCLK的具体来源则由芯片设计者决定,因此不同产品之间的时钟频率可能会大不相同 因此, 需要检视芯片的器件手册来决定选择什么作为时钟源 SysTick定时器能产生中断,CM3为它专门开出一个异常类型,并且在向量表中有它的一席之地它使操作系统和其它系统软件在CM3器件间的移植变得简单多了,因为在所有CM3产品间,SysTick的处理方式都是相同的。

      有4 个寄存器控制SysTick定时器,如表2.20至表2.23所示 表 2.20 SysTick 控制及状态寄存器(地址:0xE000_E010) 位段 名称 类型 复位值 描述 16 COUNTFLAG R 0 如果在上次读取本寄器后,SysTick已经计到了0 ,则该位为1 如果读取该位,该位将自动清 0 2 CLKSOURCE R/W 0 0=外部时钟源(STCLK) 1=内核时钟(FCLK) 1 TICKINT R/W 0 0=数到0 时无动作 1=SysTick倒数计数到0 时产生SysTick异常请求 0 ENABLE R/W 0 SysTick定时器的使能位 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 28 页 表 2.21 SysTick重装载数值寄存器(地址:0xE000_E014) 位段 名称 类型 复位值 描述 23:0 RELOAD R/W 0 当倒计数至零时,将被重装载的值 表2.22 SysTick当前值寄存器(地址:0xE000_E018) 位段 名称 类型 复位值 描述 23:0 CURRENT R/W 0 读取时返回当前倒计数的值,写它则使之清0,同时还会清除SysTick控制及状态寄存器标志。

      校准值寄存器提供了这样一个解决方案:它使系统即使在不同的CM3产品上运行,也能产生恒定的SysTick中断频率最简单的作法就是:直接把TENMS的值写入重装载寄存器,这样一来,只要没突破系统的“弹性极限”,就能做到每10ms来一次 SysTick异常如果需要其它的SysTick异常周期,则可以根据TENMS的值加以比例计算只不过,在少数情况下,CM3芯片可能无法准确地提供TENMS的值(如,CM3的校准输入信号被拉低),所以为保险起见,最好在使用TENMS前检查器件的参考手册 表 2.23 SysTick 校准值寄存器的位分配(地址:0xE000_E01C) 位段 名称 类型 复位值 描述 31 NOREF RO - 1=没有外部参考时钟(STCLK不可用) 0=外部参考时钟可用 30 SKEW RO - 1=校准值不是准确的10ms 0=校准值是准确的10ms 23:0 TENMS R/W 0 10ms的时间内倒计数的格数芯片设计者应该通过Cortex-M3 的输入信号提供该数值若该值读回0,则表示无法使用校准功能 SysTick定时器除了能服务于操作系统之外,还能用于其它目的:如作为一个闹铃,用于测量时间等。

      要注意的是,当处理器在调试期间被喊停(halt)时,则SysTick定时器亦将暂停运作 在μ C/OS-II操作系统中,系统要求定时器间隔10ms~100ms产生中断调用系统节拍函数OSTimeTick(),以完成操作系统的正常运行,如程序清单L2.8所示 程序清单 L2.8 SysTick 20ms 定时 #define OS_TICKS_PER_SEC 20 #define NVIC_ST_RELOAD 0xE000E014 // 重装值寄存器 #define NVIC_ST_CTRL 0xE000E010 // 控制与状态寄存器 unsigned int cnts; int main(void) // 主函数(程序入口) { clockInit(); cnts=SysCtlClockGet()/OS_TICKS_PER_SEC; HWREG(NVIC_ST_RELOAD)=cnts-1; 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 29 页 HWREG(NVIC_ST_CTRL)=(1<<1)|1; // bit2:0-> 外部时钟,1-> 内部时钟 // bit1: 1->计满产生中断, 0->不产生中断 // bit0: 0->不使能, 1-> 使能 SysTick计数器 while(1); } void SysTick_ISR(void) // SysTick计数器的中断服务函数 { OSTimeTick() } 2.6存储器保护单元(MPU) 在嵌入式技术中,为了提高应用的稳定可靠性,微处理器通常都配置有存储器管理单元(MMU),用来合理有效的管理系统中的存储器,这也是区分微处理器和微控制器的条件之一。

      比如ARM公司的ARM9、ARM10、ARM11以及ARM Cortex-A系列的处理器都带有MMU在ARM Cortex-M3内核中选配了一个存储器保护单元(MPU),其作用是对存储器(主要是内存和外设寄存器)进行保护,从而使软件更加健壮和可靠MPU有如下的功能可以提高系统的可靠性: 阻止用户应用程序破坏操作系统使用的数据阻止一个任务访问其它任务的数据区,从而把任务隔开 可以把关键数据区设置为只读,从根本上消除了被破坏的可能 检测意外的存储访问,如,堆栈溢出,数组越界 此外,还可以通过MPU设置存储器片块的其它访问属性,比如,是否缓区,是否缓冲等 2.6.1 MPU 寄存器组织及描述 MPU 寄存器总汇,如表 2.24 所示 表 2.24 MPU 寄存器 寄存器名称 类型 地址 复位值 MPU 类型寄存器(MPUTR) 只读 0xE000ED90 0x00000800 MPU 控制寄存器(MPUCR) 读/写 0xE000ED94 0x00000000 MPU 区号寄存器(MPURNR) 读/写 0xE000ED98 - MPU 区域基址寄存器(MPURBAR) 读/写 0xE000ED9C - MPU 区域属性与大小寄存器(MPURASR) 读/写 0xE000EDA0 - MPU 别名1 区基址寄存器() D9C 重叠 0xE000EDA4 - MPU 别名1 区属性与大小寄存器 DA0 重叠 0xE000EDA8 - MPU 别名2 区基址寄存器 D9C 重叠 0xE000EDAC - MPU 别名2 区属性与大小寄存器 DA0 重叠 0xE000EDB0 - MPU 别名3 区基址寄存器 D9C 重叠 0xE000EDB4 - 这部分内容要标选学。

      四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 30 页 MPU 别名3 区属性与大小寄存器 DA0 重叠 0xE000EDB8 - 1. MPU 类型寄存器 使用 MPU 类型寄存器查看 MPU 支持的区域数 如表 2.25 所示, 读取位[15:8] 的内容以判断是否存在 MPU 表 2.25 MPU 类型寄存器 MPUTR (地址:0xE000_ED90) 位 名称 描述 [31:24] - 保留 [23:16] IREGION 因为处理器内核只使用统一的MPU ,所以IREGION 总是包含0x00 [15:8] DREGION 支持的MPU 区域数如果实现包含一个表明有8 个MPU 区的MPU ,那么DREGION 包含0x08,否则包含0x00 [7:0] - 保留 [0] SEPARATE 因为处理器内核只使用统一的MPU ,所以SEPARATE 总是为0 2.MPU 控制寄存器 MPU 控制寄存器如表 2.26 所示 表 2.26 MPU 控制寄存器的位分配 位 名称 定义 [31:2] - 保留 [2] PRIVDEFENA 是否为特权级打开缺省时存储器映射(即背景区域) 1=特权级下打开背景区域 0=不打开背景区域。

      任何访问违例以及对区域外地址区的访问都将引起fault [1] HFNMIENA 1=在NMI和硬fault服务例程中不强制除能MPU 0=在NMI和硬fault服务例程中强制除能MPU [0] ENABLE MPU 使能位:1= 使能MPU 0= 禁能MPU 复位将ENABLE 位清零 MPU 控制寄存器用于:  使能 MPU;  使能缺省时的存储器映射;  在处于硬故障、NMI 和 FAUTMASK 升级处理时使能 MPU 在使能 MPU 时,为了运行 MPU,除非 PRIVDEFENA 位置位,否则必须至少使能一个存储器映射区如果 PRIVDEFENA 位置位而没有区域被使能,那么只能运行特权代码 MPU 禁止时,使用缺省的地址映射,相当于没有 MPU 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 31 页 MPU 使能时, 只有系统分区和向量表装载总是可访问 其他区必须根据区域以及PRIVDEFENA 是否使能才能决定其是否可访问 除非 HFNMIENA 置位,否则 MPU 在异常优先级为-1 或-2 时不能被使能。

      这些优先级仅在处于硬故障、NMI 或当 FAULTMASK 使能时才存在当 HFNMIENA 位和这两个优先级一起工作时,它用于使能 MPU 3. MPU 区号寄存器 MPU 区号寄存器用于选择进行访问的保护区然后写 MPU 区域基址寄存器或 MPU 属性与大小寄存器以对保护区的特性进行配置如表 2.27 所示 表 2.27 MPU 区号寄存器 MPURNR (地址:0xE000_ED98) 位 名称 定义 [31:8] - 保留 [7:0] REGION 选择下一个要配置的区因为只支持8 个区,所以事实上只有[2:0]有意义,在使用“区域属性与大小寄存器”和“区域基址寄存器”时选择进行操作的域首先必须写REGION,但在对地址VALID+REGION 域进行写操作时除外,它覆盖了REGION 4. MPU 区域基址寄存器 MPU 区域基址寄存器各位功能如表 2.28 所示 表 2.28 MPU 区域基址寄存器的位分配 位 名称 定义 [31:N] ADDR 区域基址域N 的值取决于区域的大小,所以基址是按照大小的偶数倍来对齐的 由MPU 区域属性与大小寄存器的SZENABLE 域指定的2 的乘幂决定了使用的基址位数 [4] VALID MPU 区号有效位: 1= MPU 区号寄存器被位3:0(REGION 值)覆写。

      0= MPU 区号寄存器保持不变并被解释 [3:0] REGION MPU 区域覆盖域 MPU 区域基址寄存器用于写区域的基址区域基址寄存器还含有 REGION 域,如果 VALID 置位,你可以将它用于覆盖 MPU 区号寄存器中的 REGION 域 区域基址寄存器为区域设置基址,按照大小对齐那么一个 64KB 大小的区域必须按 64KB 的倍数对齐,例如,0x00010000,0x00020000 等等 区读回的结果总是当前 MPU 的区号Valid 总是当作 0 读回将 VALID 和 REGION 分别设成VALID=1 和 REGION=n 时,区号将变为 n这是写 MPU 区号寄存器一个最快捷的方法 如果不是按字访问,那么寄存器将不可预测 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 32 页 5.MPU 区域属性与大小寄存器 MPU 区域属性与大小寄存器各位的定义如表 2.29 表 2.29 MPU 区属性及容量寄存器 MPURASR(地址:0xE000_EDA0) 位 名称 定义 [31:29] - 保留 [28] XN 指令访问禁止位:1= 禁止取指;0= 使能取指 [27] - 保留 [26:24] AP 访问许可,如下表所示: 值 特权级下的许可 用户级下的许可 典型用法 0b000 禁止 禁止 该区域是无存储器,是空地止 0b001 R/W 禁止 OS及系统软件使用的数据区 0b010 R/W RO 禁止在用户级下不能更改的区 0b011 R/W R/W 共享内存或可该问的设备 0b100 保留 保留 保留 0b101 RO 禁止 OS使用的常量数据 0b110 RO RO 常量数据或只读存储器区 0b111 RO RO 常量数据或只读存储器区 [23:22] - 保留 [21:19] TEX 类型扩展域 [18] S 可共享位:1= 可共享;0= 不可共享 [17] C 可高速缓存的位:1= 可高速缓存;0= 不可高速缓存 [16] B 可缓冲的位:1= 可缓冲;0= 不可缓冲 [15:8] SRD 子区禁止位段。

      每设置SRD的一个位,就会除能与之对应的一个子区容量大于128字节的区都被划分成8 个容量相同的子区容量小于等于128字节的区不能再分 [7:6] - 保留 [5:1] REGION SIZE MPU 保护区大小域见表3.20 [0] SZENABLE 区域使能位 表 2.30 MPU 保护区域大小域 区域 大小 区域 大小 b00000 保留 b10000 128KB b00001 保留 b10001 256KB b00010 保留 b10010 512KB b00011 保留 b10011 1MB b00100 32B b10100 2MB 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 33 页 b00101 64B b10101 4MB b00110 128B b10110 8MB b00111 256B b10111 16MB b01000 512B b11000 32MB b01001 1KB b11001 64MB b01010 2KB b11010 128MB b01011 4KB b11011 256MB b01100 8KB b11100 512MB b01101 16KB b11101 1GB b01110 32KB b11110 2GB b01111 64KB b11111 4GB MPU 区域属性与大小寄存器用于控制 MPU 的访问权限。

      寄存器由两个局部寄存器组成,每个都是半字大小可以使用单独的长度对这些寄存器进行访问,也可以使用字操作同时对它们进行访问 表 2.29中的[15:8]位提到了“子区”的概念由于 8 个区的定义区域较大,因而允许把每个区的内部进一步划分成更小的块,这就是子区但是子区的使用有限制:每个区必须 8 等分,每份是一个子区, 而且所有子区的属性都与“父区”的是相同的 每个子区可以独立地使能或禁止, SRD中的 8 个位,每个位控制一个子区是否被禁止如 SRD.3=0,则 3 号子区被禁止如果某个子区被禁止,且其对应的地址范围又没有落在其它区中,则对该子区覆盖范围的访问将引发 fault子区最小也要有 256字节,如果是对 128字节或者是更小的区划分子区,则后果是不可预料的 表 2.29中的[26:24]为 AP 位段, AP位段用于限定各种访问权限,这也是加以分区保护的最重要组成部分 表 2.29中的位段[28]的名字是 XN(eXecute Never),它决定在本区中是否允许取指如果不允许取指(清零),则任何指令预取都将触发 MemManage fault其作用是可以把新得到的还不受信任的代码先存储到此区,待经过身份鉴定后,再允许它执行。

      表 2.29中的[21:16]位段中 TEX、S 、B 和 C ,对应着存储系统中比较高级的操作Cortex-M3中没有缓存(cache),但是 Cortex-M3是以 v7-M的架构设计的,而 v7-M支持外部缓存以及更先进的存储器系统按 v7-M的规格说明,可以通过对这些位段的编程,来支持多样的内存管理模型这些位组合的详细功能如表 2.31所示: 表 2.31 TEX,C,B 对存储器类型的决定 TEX C B 描述 存储器类型 可否共享 000 0 0 严格按顺序 严格按顺序 总是可以 000 0 1 共享的设备 设备 总是可以 000 1 0 片外或片内的“写通”型内存,没有写allocate 普通 S 位决定 000 1 1 片外或片内的“写回”型内存,没有写allocate 普通 S 位决定 001 0 0 片外或片内的“缓存不可”型内存 普通 S 位决定 001 0 1 保留 保留 保留 001 1 0 已定义的执行 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 34 页 001 1 1 片外或片内的“写回”型,带读和写的allocate 普通 S 位决定 010 1 x 共享不可的设备 设备 总是不可 010 0 1 保留 保留 保留 010 1 x 保留 保留 保留 1BB A A 带缓存的内存。

      BB=适用于片外内存, AA=适用于片内内存 普通 S 位决定 表中最后 TEX 的 MSB=1 时的情况此时,如果该区是片内存储器,则由 C 和 B 决定其缓存属性(AA);如果是片外存储器,则由 TEX 的[1:0]决定其缓存属性(BB)不管是 AA 还是 BB,每个数值的含义都是相同的,如表 3.32 所示 表 2.32 缓存方针编码 存储器属性编码 (AA and BB) 高速缓存策略 00 缓存不可 01 写回,读写均有 allocate 10 写通,写没有 allocate 11 写回,写没有 allocate 2.6.2 MPU 的应用 Cortex-M3中的 MPU可定义 8 个内存区每个区都有一个基址(基址寄存器 MPURBAR)、一个大小(属性及容量寄存器 MPURASR中的[5:1]位)以及相应的属性(属性及容量寄存器 MPURASR)其中区的大小为 2 的幂次方,范围在 32 字节与 4GB间包括 32 字节和 4GB区的基址必须对齐区的大小一个区可以允许或不允许有代码执行体对于特权模式和用户模式,区能被设置成只读访问、读/ 写访问或无访问权每个区内还可创建 8 个子区。

      一旦区已定义并且 MPU使能,对区进行任何一个非法访问将会导致一个内存管理故障,并且故障处理程序将会被激活 在 Cortex-M3 中,MPU 的管理实际是对存储器映射中的区域进行管理,操作如图 2.33 所示 表 2.33 MPU 的在 Cortex-M3 中的管理区域 MPU管理区 MPU操作类型 代码区 特权级代码,包括初始的异常向量表 用户级代码 SRAM区 特权级数据 用户级数据 特权级位带别名区 用户级位带别名区 片上外设区 特权级外设 用户级外设 特权级外设的位带别名区 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 35 页 用户级外设的位带别名区 系统私有区 仅允许特权级访问 例如有一应用项目要求对代码区特权级代码 8MB(0x0000_0000~0x008F_FFFF)全访问,可缓存;对片上 RAM 特权级数据 64K(0x2000_0000~0x2000_FFFF)全访问,可缓存;片上外设 512MB(0x4000_0000~0x5FFF_FFFF)全访问,共享设备;系统私有区 1MB(0xE000_0000~0xE00F_FFFF)特权级访问,严格按顺序。

      操作如程序清单 L2.9 所示 程序清单 L2.9 MPU 操作实例 MpuSetup ; 入口函数,它内部呼叫子程序来完成MPU设置 PUSH {R0-R6,LR} LDR R0, =0xE000ED94 ; MPU 控制寄存器 MOV R1, #0 STR R1, [R0] ; 配置前先禁止MPU ; --- Region #0 --- LDR R0, =0x00000000 ; 区号0: 基址 = 0x00000000 MOV R1, #0x0 ; 区号0: 区号 = 0 MOV R2, #0x16 ; 区号0: 容量 = 0x16 (8MB) MOV R3, #0x3 ; 区号0: 访问许可 = 0x3 ( 全访问) MOV R4, #0x7 ; 区号0: 属性 = 0x7 MOV R5, #0x0 ; 区号0: 子区禁止=0 MOV R6, #0x1 ; 区号0: {XN, Enable} = 0,1 BL MpuRegionSetup ; --- Region #1 --- LDR R0, =0x08000000 ; 区号1: 基址 = 0x20000000 MOV R1, #0x1 ; 区号1: 区号 = 1 MOV R2, #0x0F ; 区号1: 容量 = 0x0F (64KB) MOV R3, #0x3 ; 区号1: 访问许可= 0x3 (全访问) MOV R4, #0x7 ; 区号1: 属性= 0x7 MOV R5, #0x0 ; 区号1: 子区禁止= 0 MOV R6, #0x1 ; 区号1: {XN, Enable} = 0,1 BL MpuRegionSetup ; --- Region #2 --- LDR R0, =0x08000000 ; 区号2: 基址 = 0x40000000 MOV R1, #0x2 ; 区号2: 区号 = 2 MOV R2, #0x1C ; 区号2: 容量 = 0x1C (512MB) MOV R3, #0x3 ; 区号2: 访问许可= 0x3 (全访问) MOV R4, #0x1 ; 区号2: 属性= 0x1 MOV R5, #0x0 ; 区号21: 子区禁止= 0 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 36 页 MOV R6, #0x1 ; 区号2: {XN, Enable} = 0,1 BL MpuRegionSetup ; --- Region #3 --- LDR R0, =0x08000000 ; 区号3: 基址 = 0xE0000000 MOV R1, #0x3 ; 区号3: 区号 = 3 MOV R2, #0x13 ; 区号3: 容量 = 0x13 (1MB) MOV R3, #0x1 ; 区号3: 访问许可= 0x1 (特权访问) MOV R4, #0x0 ; 区号3: 属性= 0x0 MOV R5, #0x0 ; 区号3: 子区禁止= 0 MOV R6, #0x1 ; 区号3: {XN, Enable} = 0,1 BL MpuRegionSetup LDR R0, =0xE000ED94 ; MPU 控制寄存器 MOV R1, #1 STR R1, [R0] ; 使能MPU POP {R0-R6,PC} ; 返回 MpuRegionSetup ; MPU 区 设置及启用子程 ; 入口条件: ; R0 = 基址 ; R1 = 区号 ; R2 = 容量 ; R3 = 访问许可 ; R4 = 属性 ({TEX[2:0], S, C, B}) ; R5 = 子区禁止 ; R6 = {XN,Enable} PUSH {R0-R1, LR} BIC R0, R0, #0x1F ; 清零基址中不会用到的位段 BFI R0, R1, #0, #4 ; 把区号插入到R0[3:0] ORR R0, R0, #0x10 ; 置位VALID位 LDR R1, =0xE000ED9C ; 加载MPU基址寄存器的地址 STR R0, [R1] ; 填写之 AND R0, R6, #0x01 ; 读取使能位 UBFX R1, R6, #1, #1 ; 读取XN位 BFI R0, R1, #28, #1 ; 把 XN 插入到 R0[28] BFI R0, R2, #1 , #5 ; 把区容量(R2[4:0])插入到R0[5:1]中 BFI R0, R3, #24, #3 ; 把AP访问许可(R3[2:0])插入到R0[26:24]中 BFI R0, R4, #16, #6 ; 把属性(R4[5:0])插入到R0[21:16]中 BFI R0, R5, #8, #8 ; 把子SRD子区(R5[7:0])插入到R0[15:8]中 LDR R1, =0xE000EDA0 ; 加载MPU属性及容量寄存器的地址 STR R0, [R1] ; 写入寄存器 四川师范大学成都学院 课时授课计划(教案) 备课日期: 2011 年 03 月 1 日 第 37 页 POP {R0-R1, PC} ; 返回 MpuRegionDisable ; 该子程序用于禁止一个MPU ; 入口条件: R0 = 待禁止的区号 PUSH {R1, LR} AND R0, R0, #0xF ; 区号只取低4 位 ORR R0, R0, #0x10 ; 设置VALID位 LDR R1, =0xE000ED9C ; 加载MPU基址寄存器的地址 STR R0, [R1] ; 填写之 MOV R0, #0 LDR R1, =0xE000EDA0 ; 加载MPU属性及容量寄存器的地址 STR R0, [R1] ; 把它归零,这也蕴涵了除能的命令 POP {R1, PC} ; 返回 。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.