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

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 著 宋岩 译

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/560191.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

freertos里面用到的汇编语言总结

汇编语言基础知识多重存储器访问MRS 和 MSRisb 和 dsbldr 和 strmovbl 和 bxcps多重存储器访问 感叹号!表示要自增(Increment)或自减(Decrement)基址寄存器 Rd 的值,时机是在每次访问前(Before)或访问后(After)。增/减,单位:字&am…

freertos内核 任务定义与切换 原理分析

freertos内核 任务定义与切换 原理分析主程序任务控制块任务创建函数任务栈初始化就绪列表调度器总结任务切换主程序 这个程序目的就是,使用freertos让两个任务不断切换。看两个任务中变量的变化情况(波形)。 下面这个图是任务函数里面delay(100)的结果。 下面这个…

freertos临界段保护

freertos临界段保护中断的基础知识cortex-m里面开中断、关中断指令关中断和开中断进入临界段和退出临界段中断的基础知识 嵌套: 嵌套向量中断控制器 NVIC(Nested Vectored Interrupt Controller与内核是紧耦合的。提供如下的功能:可嵌套中断支持、向量…

改进版的CBOW模型

复习 首先复习一下之前的CBOW笔记。 采用推理的方法认知单词、CBOW模型这里面主要是: CBOW模型的核心思路:给出周围的单词(上下文)时,预测目标词处会出现什么单词。 要用神经网络处理单词,需要先将单词…

freertos空闲任务、阻塞延时

freertos空闲任务、阻塞延时空闲任务阻塞延时SysTick实验现象阻塞态:如果一个任务当前正在等待某个外部事件,则称它处于阻塞态。 rtos中的延时叫阻塞延时,即任务需要延时的时候,会放弃CPU的使用权,进入阻塞状态。在任务阻塞的这段…

树莓派配置

树莓派配置1.安装操作系统2.修改镜像源3.配置VNC连接1.安装操作系统 安装操作系统,首先在官网下载https://www.raspberrypi.com/software/operating-systems/ 下载出来的解压后是一个光盘映像文件,接下来就需要把这个文件写入到树莓派的tf卡里。 安装树…

远程桌面连机器人

这里需要PC和机器人处于同一局域网下。 PC使用xhell连接机器人,通过 ifconfig 查看机器人的无线 IP 地址。 然后退出xshell,打开NoMachine软件进行远程桌面连接。输入机器人无线ip地址。 输入用户名和密码 然后就远程连接上了 现在开一个终端如下所示&…

RNNLM

RNNLM 基于RNN的语言模型称为RNNLM(Language Model)。 Embedding 层:将单词ID转化为单词的分布式表示(单词向量)。 RNN层:向下一层(上方)输出隐藏状态,同时也向下一时刻的RNN层(右边)输出隐藏状态。 对于“you say …

使用c#制作赛尔号登录器

使用c#制作赛尔号登录器 需求: 打开赛尔号官网,发现我的chrome浏览器无法运行Flash。这是因为Adobe 公司放弃了对 Flash Player 的支持。 那么如果我想要玩游戏,又不想下载别的浏览器,只好自己写一个登陆器了。 创建项目 首先…

普通RNN的缺陷—梯度消失和梯度爆炸

之前的RNN,无法很好地学习到时序数据的长期依赖关系。因为BPTT会发生梯度消失和梯度爆炸的问题。 RNN梯度消失和爆炸 对于RNN来说,输入时序数据xt时,RNN 层输出ht。这个ht称为RNN 层的隐藏状态,它记录过去的信息。 语言模型的任…

LSTM的结构

RNN和LSTM 简略表示RNN层:长方形节点中包含了矩阵乘积、偏置的和、tanh函数的变换。将下面这个公式表示成一个tanh节点。 LSTM:Long Short-Term Memory(长短期记忆),长时间维持短期记忆。 LSTM与RNN的接口(输入输出)…

STM32 USART 补充

串口通讯的数据包:发送设备通过自身的TXD接口传输到接收设备的RXD接口。 串口通讯的协议层中,规定了数据包的内容,由起始位、主体数据、校验位、停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据。 异步通讯&#xf…

ROS TF变换

静态坐标转换:机器人本体中心到雷达中心的转换。因为激光雷达可能没安装到机器人的中心。 动态坐标转换:机器人中心和里程计坐标的变换。机器人从起点出发后,里程计坐标相对于本体就会产生一个偏移,这个偏移随着机器人的运动不断…

ROS底盘控制节点 源码分析

先在机器人端通过launch文件启动底盘控制。 robot:~$ roslaunch base_control base_control.launch ... logging to /home/jym/.ros/log/3e52acda-914a-11ec-beaa-ac8247315e93/roslaunch-robot-8759.log Checking log directory for disk usage. This may take a while. Pres…

ROS + OpenCV

视觉节点测试 先进行一些测试。并记录数据。 圆的是节点,方的是话题。 1.robot_camera.launch robot:~$ roslaunch robot_vision robot_camera.launch ... logging to /home/jym/.ros/log/bff715b6-9201-11ec-b271-ac8247315e93/roslaunch-robot-8830.log Check…

ROS+雷达 运行数据记录

先测试一下雷达,记录数据。方便接下来分析源码。 1.roslaunch robot_navigation lidar.launch robot:~$ roslaunch robot_navigation lidar.launch ... logging to /home/jym/.ros/log/7136849a-92cc-11ec-acff-ac8247315e93/roslaunch-robot-9556.log Checking l…

ROS 找C++算法源码的方法

在gmapping的launch文件中看到,type“slam_gmapping”,这里的slam_gmapping是c编译后的可执行文件。 如果想要修改gmapping算法,就需要找到slam_gmapping的c源码。 但是这是用apt下载的包,是二进制类型的,没有下载出…

ros 雷达 slam 导航 文件分析

ros 雷达 slam 导航 文件分析robot_slam_laser.launchrobot_lidar.launchlidar.launchraplidar.launchkarto.launchgmapping.launchcartographer.launchrobot_navigation.launchmap.yamlmap.pgmamcl_params.yamlmove_base.launchcostmap_common_params.yamllocal_costmap_param…

Apprentissage du français partie 1

Apprentissage du franais partie 1 键盘转换图: 字母:26个 元音字母:a、e、i、o、u、y b浊辅音(声带)-p清辅音 d-t 音符 音符:改变字母发音。 :闭音符 [e] :开音符 /ε/ :长音符 /ε/…

stm32基本定时器

定时器分类 stm32f1系列,8个定时器,基本定时器(TIM6,7)、通用定时器(TIM2,3,4,5)、高级定时器(TIM1,8)。 基本定时器:16位,只能向上计数的定时器,只能定时,没有外部IO 通用定时器:16位&#…