Cortex-M7 异常处理与返回

1 前言

        当CM3开始响应一个中断时,会在它小小的体内奔涌起三股暗流:
         入栈: 把8个寄存器的值压入栈;
         取向量:从向量表中找出对应的服务程序入口地址;
         选择堆栈指针MSP/PSP,更新堆栈指针SP,更新LR,更新程序计数器PC;
                                                                 ---引自《Cortex-M3权威指南》

        为了提高异常响应的实时性,Cortex-M7采用了如下机制:

        ① 支持基于优先级的中断抢占

        即便CPU当前正在进行异常处理,当新到异常的优先级较高时,即可进行抢占,转而处理该优先级较高的异常,即支持中断嵌套处理;

        ② 异常返回

        如果当前无尚pending等待响应的异常,且没有被晚到(late-arriving)机制打断,当前异常处理完成后,就会进行异常返回;

        ③ 尾链机制(咬尾中断,tail-chaining)

        为了加速异常响应速度,当一个异常处理完成后,如果还有处于pending状态的异常等待响应,则不会进行堆栈恢复,而是转而处理该pending的异常;

        ④ 晚到机制(late-arriving)

        该机制主要是为了加速优先级抢占;若当前异常(A)响应正处于现场保护(压栈,保护现场等操作异常处理准备阶段),而新到一个优先级更高的异常B,则之前的准备工作都变成了为他人做嫁衣了,当然这些准备工作也不会浪费(这些准备工作也是新到的异常B处理所必须的),CPU会转而处理该优先级较高的异常,进行其对应的中断向量取指工作,待到异常B处理完成后,尾链机制生效,继续处理异常A;

        当然,这种半路截胡的事情只限于异常处理准备阶段,一旦异常A进入异常处理(开始执行ISR),则只能按照普通的抢占处理,这就意味着需要进行当前异常处理的现场保护,需要更多的CPU耗时和压栈处理。

        总的来看,整个异常处理过程可大概理解为图1的流程:

        图1 异常处理过程

2 异常响应的具体行为分析

2.1 异常响应

        一个异常能够得到CPU响应的情况,主要分为以下两种:

        ① 异常来临时,CPU处于线程模式(Thread mode),抢的毫无悬念;

        ②异常来临时,CPU正在处理异常,但新到异常的优先级更高,照抢不误;

        当然,以前描述的情况都是在异常没有被屏蔽的情况下讨论的,PRIMASK, FAULTMASK以及BASEPRI是三个可以用于异常使能或除能的特殊功能寄存器。

2.2 压栈

        如果当前异常不是以晚到机制或尾链机制进行处理的,那么在毕竟要亲自动手进行异常处理前的准备活动,包括保护现场,对诸多寄存器进行压栈(依次把xPSR, PC, LR, R12以及R3-R0由硬件自动压入适当的堆栈中),这8个寄存器由硬件(强制)自动完成压栈,其集合称之为栈帧(stack frame)。当Cortex-M7选配的FPU使能时,同时也需要对FPU相关寄存器进行压栈处理,具体如图2所示。

​图2 stack frame

        其中:

        ① 栈帧中PC存储的是中断返回后执行的地址,为被中断打断的程序的下一条指令地址;

        ② 压栈等准备工作完成后,若没有被更高优先级的中断抢占,则正式进入中断处理阶段,该中断的状态会从pending变为active,开始执行ISR;反之,若新到一个更高优先级的异常,则该中断的状态会停留在pending状态,CPU会转而处理该新到异常;

        此外,在进入ISR前,xPSR, PC, LR, R12以及R3-R0由硬件自动压入适当的堆栈(MSP或PSP)中,而其他寄存器如果由保护需求,则需要在ISR中手动入栈。例如,PortPendSVHandler代码中r4-r11,r14及FPU相关寄存器的相关入栈操作就是在ISR中完成的:

void xPortPendSVHandler( void )
{/* This is a naked function. */__asm volatile("	mrs r0, psp							\n""	isb									\n""										\n""	ldr	r3, pxCurrentTCBConst			\n"/* Get the location of the current TCB. */"	ldr	r2, [r3]						\n""										\n""	tst r14, #0x10						\n"/* Is the task using the FPU context?  If so, push high vfp registers. */"	it eq								\n""	vstmdbeq r0!, {s16-s31}				\n""										\n""	stmdb r0!, {r4-r11, r14}			\n"/* Save the core registers. */"	str r0, [r2]						\n"/* Save the new top of stack into the first member of the TCB. */"										\n""	stmdb sp!, {r0, r3}					\n""	mov r0, %0 							\n""	cpsid i								\n"/* Errata workaround. */"	msr basepri, r0						\n""	dsb									\n""	isb									\n""	cpsie i								\n"/* Errata workaround. */"	bl vTaskSwitchContext				\n""	mov r0, #0							\n""	msr basepri, r0						\n""	ldmia sp!, {r0, r3}					\n""										\n""	ldr r1, [r3]						\n"/* The first item in pxCurrentTCB is the task top of stack. */"	ldr r0, [r1]						\n""										\n""	ldmia r0!, {r4-r11, r14}			\n"/* Pop the core registers. */"										\n""	tst r14, #0x10						\n"/* Is the task using the FPU context?  If so, pop the high vfp registers too. */"	it eq								\n""	vldmiaeq r0!, {s16-s31}				\n""										\n""	msr psp, r0							\n""	isb									\n""										\n"#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */#if WORKAROUND_PMU_CM001 == 1"			push { r14 }				\n""			pop { pc }					\n"#endif#endif"										\n""	bx r14								\n""										\n""	.align 4							\n""pxCurrentTCBConst: .word pxCurrentTCB	\n"::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ));
}

2.3 异常返回

        在异常处理模式(Handler mode)下,将EXC_RETURN加载至PC,则会触发异常返回,通常有以下三种方式:

• An LDM or POP instruction that loads the PC.
• An LDR instruction with PC as the destination.
• A BX instruction using any register.

        在ISR执行前,EXC_RETURN的值会被存储到LR,用于指示中断返回后使用的堆栈指针(MSP还是PSP)及处理器模式(线程模式还是异常处理模式),一旦EXC_RETURN被加载到PC,则标志着ISR执行完毕,随即触发中断返回序列。EXC_RETURN的bits[31:5]恒为1,而低5位用于存储返回信息,具体见表1:

表1 EXC_RETURN定义的异常返回行为

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

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

相关文章

C语言 | Leetcode C语言题解之第2题两数相加

题目: 题解: struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {struct ListNode *head NULL, *tail NULL;int carry 0;while (l1 || l2) {int n1 l1 ? l1->val : 0;int n2 l2 ? l2->val : 0;int sum n1 n2 …

「每日跟读」英语常用句型公式 第3篇

「每日跟读」英语常用句型公式 第3篇 1. I don’t know how to ____ 我不知道如何_____ I don’t know how to play soccer (我不知道怎么踢足球) I don’t know how to study(我不知道如何学习) I don’t know how to play chess (我不知道如何下国…

使用 Kafka 保证消息不丢失的策略及原理解析

✨✨祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心!✨✨ 🎈🎈作者主页: 喔的嘛呀🎈🎈 目录 一、引言 二. 持久化存储 2.1持久化存储原理: 2.2使用示例: …

数据结构:详解【树和二叉树】

1. 树的概念及结构(了解) 1.1 树的概念 树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝…

Qt --- 常用控件

目录 1. 前言 2. QWidget核心属性 2.1. enabled(控件是否可用) 2.2. geometry(尺寸) 2.2.1. windowframe的影响 2.3. windowTitle(窗口标题) 2.4. windowIcon(窗口图标) 2.5. 使用qrc文件资源管理 2.6. windowOpacity(半透明效果) 2.7. cursor(设置鼠标光标) 2.8. fo…

DAY15|二叉树的层序遍历,226.翻转二叉树,101.对称二叉树

文章目录 二叉树的层序遍历226.翻转二叉树(层序遍历的衍生题)101.对称二叉树 二叉树的层序遍历 文字讲解:二叉树的层序遍历 视频讲解:二叉树的层序遍历 状态:看了文字讲解后理解了,熟悉队列来遍历每层子节点…

哈佛大学商业评论 --- 第四篇:一家公司的AR经验

AR将全面融入公司发展战略! AR将成为人类和机器之间的新接口! AR将成为人类的关键技术之一! 请将此文转发给您的老板! --- 专题作者:Michael E.Porter和James E.Heppelmann 虽然物理世界是三维的,但大多…

LIN总线基础

文章目录 1 什么是LIN 总线?1.1 LIN总线的历史 2.LIN总线的特点2.1 LIN总线的电气特性 3. 应用4 LIN总线基本概念4.1 LIN报文帧结构4.1.1 主节点与从节点4.1.2 调度表4.1.3网络管理4.1.4 帧头结构4.1.4.1 电平4.1.4.2 同步间隔段(间隔场)4.1.…

算法学习18:动态规划

算法学习18:动态规划 文章目录 算法学习18:动态规划前言一、线性DP1.数字三角形:f[i][j] max(f[i - 1][j - 1] a[i][j], f[i - 1][j] a[i][j]);2.1最长上升子序列:f[i] max(f[i], f[j] 1);2.2 打印出最长子序列3.最长公共子序…

免版权素材库:在营销和宣传中的重要性与应用

title: 免版权素材库:在营销和宣传中的重要性与应用 date: 2024/4/5 18:21:43 updated: 2024/4/5 18:21:43 tags: 免版权素材库营销宣传高质量素材节省成本避免侵权创意启发数字营销 免版权素材库在宣传和营销中的重要性不言而喻。在当今数字化时代,图片…

基于Python的微博舆论分析,微博评论情感分析可视化系统,附源码

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

刷题之Leetcode34题(超级详细)

34. 在排序数组中查找元素的第一个和最后一个位置 力扣链接(opens new window)https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/ 给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始…

c# wpf template ItemsPanel 简单试验

1.概要 2.代码 <Window x:Class"WpfApp2.Window9"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/…

【御控物联】JavaScript JSON结构转换(14):对象To数组——规则属性重组

文章目录 一、JSON结构转换是什么&#xff1f;二、术语解释三、案例之《JSON对象 To JSON数组》四、代码实现五、在线转换工具六、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换&#xff0…

中医肝胆笔记

目录 肝胆的经络足厥阴肝经足少阳胆经 疏肝健脾的药舒肝益脾颗粒&#xff1a;逍遥丸&#xff1a;疏肝颗粒 -> 疏肝理气的力度大-> 肝郁的程度深&#xff0c;逍遥丸没用的是时候用这个加味逍遥丸 -> 清热的力度最大->适用 肝郁火大&#xff0c;舌苔黄丹栀逍遥丸->…

LangChain Demo | 如何调用stackoverflow并结合ReAct回答代码相关问题

背景 楼主决定提升与LLM交互的质量&#xff0c;之前是直接prompt->answer的范式&#xff0c;现在我希望能用上ReAct策略和能够检索StackOverflow&#xff0c;让同一款LLM发挥出更大的作用。 难点 1. 怎样调用StackOverflow step1 pip install stackspi step 2 from la…

基于单片机的有害气体检查系统设计

**单片机设计介绍&#xff0c;基于单片机的有害气体检查系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的有害气体检查系统设计旨在实现对环境中各种有害气体的实时监测与报警&#xff0c;保障人员健康和环境…

如何使用NumPy处理数组翻转与变形

NumPy是Python中一个强大的库&#xff0c;主要用于处理大型多维数组和矩阵的数学运算。处理数组翻转与变形是NumPy的常用功能。 1.对多维数组翻转 n np.random.randint(0,100,size(5,6))n# 执行结果array([[ 9, 48, 20, 85, 19, 93], [ 1, 63, 20, 25, 19, 44], …

用 Wireshark 解码 H.264

H264&#xff0c;你不知道的小技巧-腾讯云开发者社区-腾讯云 这篇文章写的非常好 这里仅做几点补充 init.lua内容&#xff1a; -- Set enable_lua to false to disable Lua support. enable_lua trueif not enable_lua thenreturn end-- If false and Wireshark was start…