ARM CORTEX-M3 内核架构理解归纳

来源:网络 个人觉得对CM3架构归纳的非常不错,因此转载

基于《ARM-CORTEX M3 权威指南》做学习总结;

在我看来,Cotex-M3内核的主要包括:嵌套向量中断控制器(NVIC),取值单元,指令译码器,算数逻辑单元(ALU),寄存器组,存储器映射(4GB统一编址各区域功能的划分与界定),对于开发者而言,其实主要关注的主要分为三大块:

1、寄存器组2、地址功能划分映射3、中断机制(NVIC)。

1)寄存器组

Cortex-M3内核共有19组32位寄存器:

R0——R12(通用寄存器);

低寄存器组R0——R7

32位Thumb-2指令与16位Thumb指令均可访问

高寄存器组R8——R12

32位Thumb-2指令与极少数16位Thumb指令可访问

R13(堆栈指针寄存器);

主堆栈寄存器MSP(main-SP)/进程堆栈寄存器PSP(Process-SP)同一时间只能使用其中一个。MSP供操作系统内核及中断(异常)处理子程序使用,PSP只供用户的应用程序代码使用(详细使用详见3、嵌套向量中断控制器(NVIC)的总结)。

堆栈指针是4字节对齐的,故最低两位永远是00;

R14(连接寄存器)

用于存储程序返回的地址及PC的返回地址;

R15(程序寄存器)指向当前程序执行的地址;

2)特殊功能寄存器组

xPSR(程序状态字寄存器组),32位,可分为三个寄存器分别进行访问,也可以PSR或xPSR的名字直接组合访问。

应用程序PSR(APSR)

中断号PSR(IPSR)

执行PSR (EPSR)

中断屏蔽寄存器

PRIMASK    单一比特位,置位后,除NMI与硬fault外,其他中断都不响应;

FAULTMASK  单一比特位,置位后,除NMI外,其他中断都不响应;

BASEPRI     共有9位,中断号小于等于该寄存器设置值的中断都不响应;

控制寄存器control

Control[0] 0决定特权级线程模式;1用户级线程模式;

Control[1] 0主堆栈;1进程堆栈;

控制寄存器只能在特权级模式下改写,handler模式永远是特权级,且只允许使用主堆栈MSP

复位后,处理器进入特权级+线程模式下;

2、地址功能划分映射

Cortex-m3是一个32位处理器,其地址总线、数据总线都是32位的,故可在4G的地址范围上资源寻址。Cortex-m3内核把4G空间划定了基本的框架,定义不同的使用用途。

0x0000 0000 ----0x1FFF FFFF (512MB) 该区域为code区(flash区),供指令总线与数据总线取指取数使用;可以执行指令;

0x2000 0000 ----0x3FFF FFFF (512MB) 该区域为片上SRAM区,芯片制造商可在此布设RAM,可以将代码复制到此处运行,该区域也是可以执行指令code的;低1MB空间可位寻址,通过位带别名可扩展为32Mb的位寻址。

0x4000 0000 ----0x5FFF FFFF (512MB)该区域为"片上外设"区 ,主要为片上外设的相关寄存器,即特殊功能寄存器区,同理低1MB也可位寻址;该区域不可执行代码;

0x6000 0000 ----0x9FFF FFFF(1G)该区域为片外RAM区,该区域可执行代码;

0xA000 0000 ----0xDFFF FFFF(1G)该区域为片外外设区,该区域不可执行代码;

0xE000 0000 ----0xFFFF FFFF(1G)该区域为系统区,该区域不可执行代码;

所以不同地址片段的起始地址可简记为0,2,4,6,10,E,

该系统区又分为两部分:

内部私有外设区0xE000 0000 ----0xE003 FFFF(256KB)主要有NVIC,FPB,DWT,ITM等

外部私有外设区0xE004 0000 ----0xE00F FFFF(512+256=768KB)有ROM表,ETM,TPIU等

数据的大小端模式:CM-3既支持大端模式也支持小端模式,其中对于大端模式,ARM7中使用的是字不变大端模式,CM3中则为字节不变大端模式。虽说大小端模式都支持,但依然建议在绝大多数情况下使用小端模式,如果一些外设是大端模式,可以通过REV/REVH指令便可轻松完成端模式的转换。

3、中断机制(NVIC)

既然称之为MCU而非MPU,那么就是以控制为主,控制的一个关键指标就是实时性,能够及时对变化的情况作出反应,而这主要是通过中断机制来完成的,可以说除却运算性能,cortex-M3内核的主要修为都体现在控制的实时性上——也即中断的即时响应机制。

CM3对中断是怎么定义的呢?

一个是CM3内核异常导致当前运行程序的中断,一个是外部事件引入导致的。

系统异常主要是CM3内核层面的,复位,NMI,硬fault,这三者优先级固定且最高,此外还有总线fault、内存管理fault、用法fault等,svc系统调用服务、systick等的优先级可以通过编程来设定;这些都放在一个向量表里,存储的是中断服务函数的入口地址,32位,共256项,前16个是系统内的中断,除去保留位,系统中断共有16-5-1=10个,剩余240个外部中断IRQ,其中有三个的优先级是固定的:复位,NMI,硬fault,中断号分别为-3,-2,-1,中断号越小,优先级也就越高,其他优先级都是可编程的。此外,对于复位启动过程,M3内核的MCU与传统的单片机复位是不一样的,传统的单片机是直接从地址0处开始运行,然后再执行地址0处的跳转指令,跳转到设定的程序起始段;而CM3复位后首先是在地址零处0x0000 0000取出主堆栈MSP的初始值,(因为CM3的堆栈是向下生长型的,所以这个初始值一般设为RAM区的末地址+1,以保证堆栈足够大,再啰嗦下,比方说RAM区为0x2000 0000——0x3FFF FFFF那么初始值就设置为0x4000 0000);然后通过复位中断号找到存放复位程序入口地址的地址单元(0x00000004),地址单元(0x00000004)存放着第一条指令执行的地址(0x0000 0100)并赋给PC,PC就从这个地址里存放的指令依次执行。关于指令执行的地址需要严重关切:CM3运行在thumb状态,所以加载到PC中的值的最低位LSB必须置1,以区别ARM状态(ARM为偶数),所以若想指向0x0000 0100的地址值,中断向量表中存的复位程序入口地址应为0x0000 0101,用0x0000 0101表示0x0000 0100,这里不要把存储数据的地址和PC的指向地址搞混,只有PC的执行地址LSB不能等于0,其他总线访问地址则没有此限制。(为了把问题解释清楚,啰嗦的我自己都受不了了)为什么要首先初始化堆栈MSP呢?因为在复位的过程中也可能发生中断,例如NMI,硬fault等。

中断从发生到结束主要需要经过以下这么几个步骤:1捕获并响应中断,2现场保护,3中断程序入口,4返回。下面就根据这个脉络来总结cortexM3在提高中断响应速度方面所涉及的重要知识点(这个讲解顺序针对已具备一定的基础人员):

说到中断必涉及到优先级、涉及到嵌套,在CM3中用8位来编程中断的优先级数,可实现256级优先级,其中这8位又分为两段,一段决定抢占优先级的级数,一个决定亚优先级的级数,其中规定抢占优先级不得少于3位(8级优先级),亚优先级最少不得少于1位,所以抢占优先级在M3中最多128级,在哪一位开始分组由NVIC中的寄存器中(应用程序中断及复位控制寄存器)的PRIGROUP来决定;但实际中,芯片制造商一般只使用最高几位,比如5位,高三位(7,6,5)编程抢占优先级,剩下的两个次高位(4,3)用来决定亚优先级,从第4位处作为亚优先级的分组,这里通过一个分组寄存器来决定从哪一位做亚优先级分组。

优先级确定好了,那么在众多不同优先级的中断面前,CM3又是以什么样的机制来提高响应速度的呢?这就需要表一表在响应之前,处理器必须要做的工作——现场保护即保护当前的程序运行环境,依次入栈以下8个寄存器:程序状态寄存器XPSR,程序计数器PC,返回地址寄存器LR(连接寄存器),R12,R0——R3,这些都是硬件自动完成的。如果当前正在使用堆栈,则压入相应的堆栈寄存器MSP/PSP值,当前在用PSP就压入PSP,反之则压入MSP,进入中断服务程序就将一直用MSP了;好了,请注意,提高中断的响应速度就在这些寄存器的入栈顺序上,我们知道,堆栈是建立在片上RAM中的,通过系统总线(system code)来操作(为什么要建立在RAM上,因为堆栈需要不停地做出栈、入栈等动作,需要不断改变存储的值,而flash或rom只在烧写的时候写入数据),指令是存放在flash中的即code区通过指令总线(code bus)来操作,所以在入栈的时候先压入xPSR的值,再压入PC的值,压入PC的值后,就可以通过指令总线,根据中断向量号取出中断服务函数的地址赋给PC新的指令地址,进行指令的预取,而堆栈仍然可以通过系统总线继续压入其他寄存器的值,与取指令操作并行不悖,互不干扰,加快了中断的响应速度。相关寄存器可查询权威手册。

在响应中断前所做的准备工作都做好了,那么当众多中断前来叫门时,应该如何以最短的延时处理一系列的中断呢?第一级中断自不必说,根据中断号来进行仲裁,当发生中断嵌套的时候,CM3中的一些响应机制就能加快整个中断响应过程的速度了,低优先级由于高优先级中断的抢占而处于挂起状态,当高优先级中断处理完毕,按照传统的嵌套中断处理流程,高优先级中断处理完成后应该出栈弹出内容,然后再入栈压入先前弹出的内容,再处理被挂起的低优先级中断,按书中所说,这就是砸锅炼铁再铸锅的过程,完全没有必要,于是CM3内核在处理一系列嵌套的中断时,总共只执行一次入栈,出栈工作,这样处理连续的几个嵌套中断时,就减少了很多环节,缩短了时间,尤其是嵌套级别计较深的时候,尤为明显。但是要注意的是:不要嵌套太深,因为每嵌套一级就至少入栈8个32位的寄存器值(32B),如果本身就是中断进程,当前代码正在使用堆栈,还要将堆栈的值再入栈,这样无疑加大了堆栈的存储压力,如果用穿堆栈,发生溢出,程序十有八九就跑飞了,是很危险的,所以在应用中,要尽量减小中断的嵌套深度。

之前的中断响应机制发生在高级中断打断低优先级中断完成响应之后,译者将其名曰:咬尾中断;下面的中断则发生在高优先级中断打断低优先级中断准备响应之时,当高优先级中断还没来的时候,低优先级中断已经把前期准备工作给做完了,这时候高优先级中断来了,那么此时高优先级中断会直接利用低优先级中断的前期工作成果,直接开始响应,进入服务中断服务程序,而之前的低级中断则被迫挂起,为别人做嫁衣了,没办法,内核就是这样规定的,译者将其译为"晚到(的高优先级)异常"我将其名为"后来居上"中断。

中断延迟时间:从检测到中断,到执行中断服务程序的第一条指令,其间所流逝的时间。

书中云:如果存储系统足够快,入栈与取指令可以分别进行,且中断可以即刻得到响应不被抢占,那么所耗费的时间就是固定的12个周期(满足硬实时要求的确定性)。如果多级嵌套中断响应,算上咬尾中断省去的出入栈时间,每个中断可减少至6个周期。

最后再说说异常即fault,内核活动层面的东西,这个本应是需要大书特书的东西,尤其是在调试程序的时候找bug上,是体现一个人技能水平的很重要的方面,但是限于时间与研究深度,暂时不深究了,

就一句话吧:运行时出现的系统错误有时候不是编程上的语法错误,如果不了解内核架构和一些使用准则,是很难发现bug在哪里,这就需要追溯到底是程序运行到哪里出了问题,导致内核运行出现了错误,得益于CM3完备的调试架构,很多fault的产生都会被监测到,并记录在对应的寄存器中,按图索骥就知道问题出在哪里,是哪条指令导致的,借此针对性的自查、分析、修改。

转载点击此处。

ARM CORTEX-M3 内核架构理解归纳相关推荐

  1. Cortex M3内核架构

    CortexM3内核架构 宗旨:技术的学习是有限的,分享的精神是无限的. 1.ARMCortex-M3处理器 Cortex-M3处理器内核是单片机的中央处理单元( CPU). 完整的基于CM3的MCU ...

  2. ARM® Cortex®-M内核单片机STM32家族介绍,覆盖STM32F、STM32H、STM32L全系列

     STM32是ARM®Cortex®-M内核单片机.目前提供10大产品线(F0, F1, F2, F3, F4, F7, H7, L0, L1, L4),超过700个型号.STM32产品广泛应用于 ...

  3. i.MX6UL: i.MX 6UltraLite处理器 - 低功耗,安全,Arm® Cortex®-A7内核

    i.MX6UL: i.MX 6UltraLite处理器 - 低功耗,安全,Arm® Cortex®-A7内核 概述 i. MX6UltraLite作为i.MX6系列的扩展,一系列高性能.超高效的处理器 ...

  4. 32 位 ARM® Cortex®-M0+内核 单片机

    PY32F003 系列微控制器采用高性能的 32 位 ARM® Cortex®-M0+内核,宽电压工作范围的 MCU.嵌入高达 32Kbytes flash 和 4Kbytes SRAM 存储器,最高 ...

  5. 32位ARM®Cortex®-M0+内核单片机 XL32F003系列MCU

    XL32F003系列微控制器采用高性能的32位ARM®Cortex®-M0+内核,宽电压工作范围的MCU.嵌入高达64 Kbytes flash和8 Kbytes SRAM存储器,最高工作频率32 M ...

  6. ARM Cortex M3指令集

    一.跳转指令 跳转指令用于实现程序流程的跳转,在ARM 程序中有两种方法可以实现程序流程的跳转: Ⅰ.使用专门的跳转指令. Ⅱ.直接向程序计数器PC 写入跳转地址值. 通过向程序计数器PC 写入跳转地 ...

  7. The Definitive Guide to ARM Cortex M3 and Cortex M4 Processors, 3rd Edition.pdf

    在网上找不到可以直接下载的直链,要不是要登录就是要付费,挺麻烦的,百度都搜不到什么好东西,谷歌一下发现了可以直接下载的连接如下 https://www.academia.edu/35524606/ 直 ...

  8. linux 返回非法指令,linux – ARM Cortex A7在内核模式下返回PMCCNTR = 0,在用户模式下返回非法指令(即使在PMUSERENR = 1之后)...

    我想在Raspberry Pi 2上读取循环计数寄存器(PMCCNTR),它有一个ARM Cortex A7内核.我为它编译了一个内核模块,如下所示: #include #include int in ...

  9. STM32 快速入门(内核架构,启动方式,开发参考资料,芯片选型)

    文章目录 1.启动方式(Start up) 2.开发参考资料 2.1 STM32 中文参考手册 3.通常的芯片选型步骤 4.存储器和总线构架 4.1 系统构架 4.1.1 ICode 总线 4.1.2 ...

最新文章

  1. Android 停止调试程序
  2. UVa512 - Spreadsheet Tracking
  3. BZOJ 1444 [JSOI2009]有趣的游戏 (AC自动机、概率与期望DP、矩阵乘法)
  4. laravel上传到七牛图片插件
  5. dhtml是基于html的一门语言,什么是DHTML
  6. GitLab 自动触发 Jenkins 构建
  7. java图形用户登录界面_Java简单登录图形界面
  8. Pandas常用操作总结
  9. 第四周Java学习总结
  10. java 切换主线程_Java线程切换(一)
  11. 别等找工作时才明白:程序员只会敲代码是不行的!不看后悔!
  12. 游戏配置文件加密工具(附源码)
  13. 全国通用 专升本计算机基础(简答题背诵可用)
  14. Hacker News API
  15. 大厂Java面试过程中如何介绍自己的项目经历?
  16. 洛谷:P1129 [ZJOI2007] 矩阵游戏(二分图最大匹配)
  17. 文件删除终结者 v1.2 免费
  18. WebRequest 类和 WebResponse 类
  19. 【接口测试】Jenkins+ant+jmeter接口自动化测试及邮件发送
  20. perl环境配置以及Eclipse安装perl开发插件

热门文章

  1. 网络计算机显示器接口,科普四种常见的电脑显示器连接线接口
  2. 机器人无限火力无限e符文_2021LOL无限火力机器人天赋符文、出装推荐-无限火力机器人玩法介绍-色彩电竞...
  3. Linux配置SSH免密码登录(非root账号)
  4. PHP 实现301转向代码
  5. java mqtt发布_使用kura或MQTT将消息发布到kapua
  6. jpg图片太大怎么压缩变小
  7. Java编程公鸡5元一只,母鸡3元一只,小鸡1元三只,问100元怎样可以买100鸡?
  8. 华为手机上html怎么打开,华为手机root权限怎么开启?详细的步骤以及图文教程...
  9. jzy3D安装到弃坑
  10. 槃星—第1天任务—植物大战僵尸游戏数据修改(Hex Editor Neo)