cortex-m3

  • 操作模式
  • 寄存器组
  • 异常类型
  • 堆栈
  • 中断
  • 参考

操作模式

处理器的操作模式:为了区别正在执行代码的类型。复位后,处理器进入线程模式、特权级。

处理者模式(handler mode):异常服务例程的代码 ,包括中断服务例程的代码。handler 模式总是特权级的。

线程模式(thread mode):普通应用程序的代码。

特权级:在特权级下,程序可以访问所有范围的存储器、可以执行所有指令。运行主应用程序时(线程模式),既可以使用特权级,也可以使用用户级;但是异常服务例程必须在特权级下执行。

用户级:从用户级到特权级的唯一途径就是异常:如果在程序执行过程中触发了一个异常,处理器总是先切换入特权级,并且在异常服务例程执行完毕退出时,返回先前的状态,也可以手工指定返回的状态。

用户级到特权级:执行一条系统调用指令(SVC),触发 SVC 异常,然后由异常服务例程接管,如果批准了进入,则异常服务例程修改 CONTROL寄存器,才能在用户级的线程模式下重新进入特权级。

寄存器组

R0‐R12:都是 32 位通用寄存器,用于数据操作。

R0‐R7 ,低组寄存器,所有指令都能访问它们,字长全是 32 位,复位后的初始值不可预料。

R8‐R12,高组寄存器,只有很少的 16 位 Thumb 指令能访问它们,32 位的指令则不受限制,它们也是 32 位字长,且复位后的初始值不可预料。

R13:堆栈指针 SP,有两个堆栈指针MSP、PSP,任一时刻只能使用其中的一个。运行在线程模式的用户代码使用 PSP, 而异常服务例程则使用 MSP。

MSP:主堆栈指针(MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包括中断服务例程)。

PSP:进程堆栈指针(PSP):由用户的应用程序代码使用。

R14:连接寄存器(LR):当呼叫一个子程序时,由 R14 存储返回地址。把返回地址直接存储在寄存器中,提高了子程序调用的效率。

R15:程序计数寄存器(PC):指向当前的程序地址。

特殊功能寄存器:它们只能被专用的 MSR 和 MRS 指令访问,而且它们也没有存储器地址。

程序状态字寄存器组(xPSR):记录 ALU 标志(0 标志,进位标志,负数标志,溢出标志),执行状态,以及当前正服务的中断号。

其中的EPSR,它里面含 T 位,在 CM3 中 T 位必须是 1。

中断屏蔽寄存器组(PRIMASK, FAULTMASK, BASEPRI)

这里面的PRIMASK 和 BASEPRI 对于暂时关闭中断是非常重要的。

MSR BASEPRI, R0 ;写入 R0 到 BASEPRI 中

控制寄存器(CONTROL)

control[1]:handler 模式中,CONTROL[1]总是 0。在线程模式中则可以为 0 或 1。当处于特权级的线程模式下,此位才可写。

control[0]:仅当在特权级下操作时才允许写该位。一旦进入了用户级,唯一返回特权级的途径,就是触发一个(软)中断,再由服务例程改写该位。

指令集:

Thumb状态:在 Thumb 状态下,指令是 16 位的。

异常类型

SVCall:系统服务调用。用户程序使用 SVC 发出对系统服务函数的呼叫请求,以这种方法调用它们来间接访问硬件。这使得用户程序无需在特权级下执行。

SVC 异常通过执行”SVC”指令来产生。该指令需要一个立即数,充当系统调用代号。

SVC 异常是必须立即得到响应的,若无法立即响应,将上访成硬fault。

PendSV:为系统设备而设的“可悬挂请求”(pendable request)。

PendSV可以像普通的中断一样被悬起,OS 可以利用它缓期执行一个异常—直到其它重要的任务完成后才执行动作。悬起 PendSV 的方法是:手工往 NVIC 的 PendSV 悬起寄存器中写 1。

上下文切换时(在不同任务之间切换)可以用到PendSV。

ISR:中断服务例程。

IRQ:中断请求(通常是指外部中断的请求)

硬fault :总线 fault、存储器管理 fault 以及用法 fault 上访的结果。

如下图所示,在产生 SysTick 异常时正在响应一个中断请求IRQ,则 SysTick 异常会抢占其 ISR(中断服务例程)。在这种情况下,OS 不得执行上下文切换(将使中断请求IRQ被延迟,实时系统不能容忍),OS 在某中断活跃时尝试切入线程模式,将触犯用法 fault 异常。

PendSV 异常会自动延迟上下文切换的请求, 直到其它的 ISR (中断服务例程)都处理完才放行。为实现这个机制,需要把 PendSV 编程为最低优先级的异常。如果 OS 检测到某 IRQ 正在活动并且被 SysTick 抢占,它将悬起一个 PendSV 异常, 以便缓期执行上下文切换。

下图,1.任务A叫SVC(系统服务调用)来请求任务切换。2.OS收到请求,做好上下文切换准备,pend一个PendSV异常。3.CPU退出SVC,立即进入PendSV,执行上下文切换。4.PendSV执行完,返回任务B,进入线程模式。5.发生一个IRQ(中断),ISR(中断服务程序)开始执行。6.ISR执行过程中,发生SysTick异常,抢占该ISR。7.OS执行必要操作,pend起PendSV异常做好上下文切换准备。8.SysTick退出,回到先前被抢占的ISR中,ISR继续执行。9.ISR执行完并退出后,PendSV服务例程执行,在里面执行上下文切换。10.PendSV执行完,回到任务A,系统再次进入线程模式。

这个简而言之,PendSV其实起到了啥作用呢,如果产生 SysTick 异常时(为了进行上下文切换)正在响应一个中断请求IRQ,则 SysTick 异常会抢占其 ISR,用了PendSV的话,SysTick退出后不会立即执行上下文切换,而是在SysTick退出后继续执行ISR,执行完ISR之后再执行PendSV服务例程,进行上下文切换。这样好处就是不会使中断请求被延迟,有助于增加系统的实时性。

Cortex‐M3 一部分异常类型如下。

向量表:为了决定 handler 的入口地址,CM3使用了向量表查表机制。

如果发生了异常11(SVC),则NVIC会计算出偏移移量是11x4=0x2C,然后取出服务例程的入口地址并跳入。

堆栈

堆栈:由一块连续的内存,以及一个栈顶指针组成。堆栈操作就是对内存的读写操作,其地址由 SP 给出。功能就是把寄存器的数据放入内存,以便将来能恢复之。

当 PUSH/POP 指令执行时,SP 指针的值也根着自减/ 自增。

一个例子如下,执行 Fx1 的功能,中途就算改变 R0-R2 的值,回来的时候R0-R2 的值又变回来了,这就是恢复的功效。

实现堆栈:栈是后进先出的,使用的是“向下生长的满栈”模型。堆栈指针 SP 指向最后一个被压入堆栈的 32 位数值。

入栈时,SP 先自减 4,再存入新的数值。如下图。

出栈时,先读出上一次被压入的值,再把 SP 指针自增 4。

双堆栈机制:

当 CONTROL[1]=1 时,进程堆栈指针选用PSP,handler堆栈指针选用MSP。

在特权级下,可以指定具体的堆栈指针,而不受当前使用堆栈的限制。

MRS R0, PSP ; 读取进程堆栈指针到 R0
MSR PSP, R0 ; 写入 R0 的值到进程堆栈中

通过读取 PSP 的值,OS 就能够获取用户应用程序使用的堆栈,进一步地就知道了在发生异常时,被压入寄存器的内容,而且还可以把其它寄存器进一步压栈(使用STMDB和LDMIA 的书写形式)。OS 还可以修改 PSP,用于实现多任务中的任务上下文切换

中断

CM3开始响应一个中断时,进行以下操作:

入栈: 把8个寄存器的值压入栈。取向量:从向量表中找出对应的服务程序入口地址。 选择堆栈指针MSP/PSP,更新堆栈指针SP,更新连接寄存器LR,更新程序计数器PC。

入栈:是自动保存现场的必要部分。把xPSR, PC, LR, R12以及 R3‐R0由硬件自动压入适当的堆栈中。响应异常时,代码正使用PSP,使用线程堆栈;否则使用主堆栈。进入服务例程,一直使用主堆栈。

入栈顺序和入栈后堆栈中的内容如下图。假设入栈开始时,SP的值为N。下图的地址从上到下看,是由高到低的。

数据总线(系统总线)进行入栈操作,与此同时,指令总线(I‐Code总线)从向量表中找出正确的异常向量,然后找出对应的服务程序入口地址。

入栈和取向量工作做完,执行服务例程之前,会更新一系列的寄存器。

SP,在入栈中把堆栈指针更新到新位置。PSR,IPSR位段更新为新响应的异常编号。PC,向量取完后,PC将指向服务例程入口地址。LR,值更新为EXC_RETURN,在异常返回时使用。在NVIC中,新响应异常的悬起位将被清除,同时其活动位将被置位。

异常服务例程执行完毕后,要启动中断返回序列,为的是恢复先前的系统状态,使被中断的程序继续执行。

有3种途径可以触发异常返回序列(都需要用到先前储的LR的值),在CM3中,是通过把EXC_RETURN往PC里写来识别返回动作的。

启动了中断返回序列后,就进行下面操作:恢复先前压入栈中的寄存器,内部的出栈顺序与入栈时的相对应,堆栈指针的值也改回去;更新NVIC寄存器,活动位被硬件清除。(倘若中断输入再次被置为有效,悬起位也将再次置位,进行新一轮的中断响应)

EXC_RETURN:这 是一个高28位全为1的值,只有[3:0]的值有特殊含义。当异常服务例程把这个值送往PC时,就会启动处理器的中断返回序列。合法的EXC_RETURN值共3个:

参考

Cortex-M3 权威指南 Joseph Yiu 著 宋岩 译

cortex-m3 操作模式 寄存器组 异常类型 堆栈 中断相关推荐

  1. 43.XDMA寄存器详解7-MSI-X Vector Table and PBA寄存器组剖析及MSI-X中断详解

    目录 1.上节回顾 2.MSI-X Table and PBA由来 3.XDMA MSI-X Table and PBA寄存器 4.MSI和MSI-X中断机制 5.MSI和MSI-X对比 6.MSI/ ...

  2. 《计算机组成与CPU设计实验》实验3:寄存器组(堆)实验

    实验目的 掌握寄存器的HDL描述方法; 掌握HDL参数化设计方法; 理解寄存器组(堆)的电路结构,并能用HDL描述; 了解逻辑电路成本的概念. 实验原理 寄存器 寄存器定义 锁存器和触发器都是寄存器, ...

  3. Android心得4.1--文件的保存与读取及文件的操作模式详解.doc

    一.保存到手机内存 1.  很多时候我们的软件需要对处理后的数据进行存储或再次访问.Android为数据存储提供了多种方式,分别有如下几种: l     文件(采用IO数据流的方式) l     Sh ...

  4. cortex m3的操作模式和状态

    1.操作状态(operation state): debug state:处理器在调试器发起halt或匹配到断点时,会进入debug state并停止执行指令. thumb state:处理器正在运行 ...

  5. Cortex M3寄存器组

    寄存器组 宗旨:技术的学习是有限的,分享的精神是无限的. 1.通用目的寄存器R0~R7 R0-R7 也被称为低组寄存器.所有指令都能访问它们.它们的字长全是 32 位,复位后的初始值是不可预料的. 2 ...

  6. Cortex-A7 MPCore 架构详细介绍(九种运行模式、内核寄存器组R0~R15,有特定的名字和功能)

    目录 0.ARM架构的历史简介 1.Cortex-A7 MPCore(即多核) 简介 2.Cortex-A 处理器九种运行模式 3.Cortex-A 寄存器组(内核寄存器) 3.1通用寄存器 3.1. ...

  7. Cortex M3处理器工作模式及中断过程

    来自::http://blog.csdn.net/ffgamelife/article/details/6947300 1.      工作模式 线程模式(Thread mode):处理器复位或异常退 ...

  8. Cortex‐M3的Faults异常究竟是什么?

    关注+星标公众号,不错过精彩内容 作者 | strongerHuang 微信公众号 | strongerHuang 有许多朋友在学习,或者开发STM32时都遇到过HardFault_Handler的情 ...

  9. Cortex‐M3和Cortex‐M0是否都能位带操作

    最近在进行stm32l011f4的编程,想到stm32有位带操作,便想试一试,但是事与愿违,先贴下位带操作代码 Cortex‐M0的位带操作代码 //IO输出方向设置 #define SDA_IN() ...

最新文章

  1. 低调的苹果罕见发表论文,揭开自动驾驶汽车技术的冰山一角
  2. android高仿微信UI点击头像显示大图片效果
  3. python class函数报错_Python 的函数是第一类 First-Class 对象
  4. oracle 取当天日期减一天 应该如何写
  5. 列举php magic方法,如何在PHP中實現__isset()魔術方法?
  6. Java中的HashCode(1)之hash算法基本原理
  7. 区块链相关名词解释(一)
  8. c语言cad改变字体大小,cad怎么改变默认文字字体
  9. vscode设置eclipse快捷键
  10. 标准更新|这次是OTA的EN301908-13即增加TRP和TRS的测试要求
  11. 极速office(excel)如何查找出重复内容
  12. Elasticsearch 摄取节点(Ingest Node)使用Pipeline预处理文档
  13. 科林明伦杯哈理工第九届——分布式服务(概率期望+思维)
  14. 在象棋算式中不同的棋子代表不同的数,设计一个算法求这些棋子个代表那些数字(回溯)
  15. pandas取第一行数据_Pandas DataFrame 取一行数据会得到Series的方法
  16. BIOS追code之PEI phase
  17. 基于蝙蝠算法优化BP神经网络的数据分类算法及其MATLAB实现-附代码
  18. 批量修改文件名 两种方法
  19. 使用飞桨完成手写数字识别模型
  20. java练习 输出100以内的质数

热门文章

  1. Ext.grid.CheckboxSelectionModel状态设置
  2. 10分钟带你学会微信小程序的反编译
  3. mysql5.6.24安装perl_mysql5.6源码安装
  4. maven仓库理解、下载及设置
  5. java重命名package_AndroidStudio怎么重命名java目录下的包名(如cn.zsn.app)
  6. kafka集群脚本启动失败,在kafkaServer.out中提示nohup: failed to run command `java’: No such file or directory
  7. easyexcel安全扫描报php,easyExcel使用以及踩过的坑
  8. 查找服务器大文件内容,Linux查找大文件命令,springmvc基础面试题
  9. linux 改变文件夹属性,技术|在Linux中用chattr和lsattr命令管理文件和目录属性
  10. matlab 判断鼠标按下_Simulink(其他校验模块)+Matlabgui(鼠标响应事件)+Stateflow汽车运动逻辑状态(二)...