Cortex-M7 异常处理与返回

news2024/10/7 3:28:39

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.coloradmin.cn/o/1570898.html

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

相关文章

LeetCode 19.删除链表的倒数第N个结点

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head [1,2,3,4,5], n 2 输出:[1,2,3,5] 示例 2: 输入:head [1], n 1 输出:[] 示例 3&#x…

Leetcode 39.组合总和

题目 思路 1.确定递归函数的返回值及参数: 返回值是void,参数这里还是先设定两个全局变量。一个是path存放符合条件单一结果。如:(1,2)。一个是result,是所有path的集合[(1,2),(1,3)…]。 此外再设定一个…

前端学习之DOM编程-docmument对象、操作DOM对像内容、操作DOM对象属性方式、操作DOM对象的样式

docmument对象 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>document对象</title> </head> <body><div id"container" nameparent><ul name"parent&qu…

计算机系统结构速成,期末和自考必备

【拯救者】计算机系统结构速成(期末自考)均可用 1️⃣先讲每章对应的基础 2️⃣接着会讲对应的题目巩固 &#x1f357;提供文档下载 这里讲的是【 &#x1f337;速成&#x1f337; 速成&#x1f337; 速成】版本&#xff0c;按课本章节来&#xff0c; 抽取重点&#xff0c;翻…

数据分析——数据规范化

数据规范化是数据分析中的一个重要步骤&#xff0c;其目的在于确保数据的一致性和可比性&#xff0c;提高数据质量和分析结果的准确性。以下是一些数据规范化的常见方法和技术&#xff1a; 数据清洗&#xff1a;此步骤主要清除数据中的重复项、空格、格式错误等&#xff0c;确…

Transformer Based Multi-view Network for Mammographic Image Classification

“C-Tk” means “Classification Token” 辅助信息 作者未提供代码

【python从入门到精通】-- 第四战:语句汇总

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;python从入门到精通&#xff0c;魔法指针&#xff0c;进阶C&#xff0c;C语言&#xff0c;C语言题集&#xff0c;C语言实现游戏&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持创作博文…

C++:函数重载和引用

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习C&#xff1a;函数重载和引用&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 文章目录 函数重载1.函数重载的概念为什么C支持函数重载 引用引用的概念引…

C++中发送HTTP请求的方式

一&#xff0c;简介 使用C编程发送HTTP请求通常需要使用第三方的HTTP库或框架。在C中&#xff0c;有几个受欢迎的HTTP库可供选择&#xff0c;例如Curl、Boost.Beast和cpp-httplib。另外&#xff0c;也可以自己实现socket来发送http请求 二、使用Curl库发送HTTP请求 1. 确认当…

day60 动态规划part17

这两题看了自己写的笔记还不懂的话&#xff0c;看看这个up的思路就行&#xff1a; https://space.bilibili.com/111062940/search/video?keyword%E5%9B%9E%E6%96%87 647. 回文子串 中等 提示 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回…

微带线特性阻抗快速计算---根据介质板参数和特性阻抗得到线宽(Matlab代码)

微带线特性阻抗快速计算—根据介质板参数和特性阻抗得到线宽&#xff08;Matlab代码&#xff09; 参考&#xff1a;https://blog.csdn.net/weixin_45811090/article/details/130045689 《射频电路理论与设计》第2版 黄玉兰著 《射频电路设计——理论与应用》第二版 Reinhold L…

STC89C51学习笔记(三)

STC89C51学习笔记&#xff08;三&#xff09; 综述&#xff1a;本文讲述了通过51单片机控制LED闪烁、流水灯、按键控制LED亮灭、按键控制LED实现二进制、按键控制LED左右移。 一、LED 1.LED闪烁 1&#xff09;原理 如果要实现LED闪烁&#xff0c;不可以直接先使LED亮&…

兼顾性能的数据倾斜处理方案

目录 前言 一、场景描述 二、常见的优化方法 2.1 Mapjoin 2.2 特殊值/空值打散 2.3 热点值打散&#xff0c;副表呈倍数扩散 2.4 热点数据单独处理/SkewJoin 2.5 方案总结 三、Distmapjoin 3.1 核心思路 3.2 代码实现 3.3 真实效果 四、方案总结 文章主要是介绍在支…

手把手教你从入门到精通C# MES通信

前言 我们在上位机软件开发的时候,经常需要与客户的MES系统进行通信,一般与MES系统通信需要实现的功能如下: 1、通过输入员工号来获取登录MES系统的权限 2、上传设备检测的OK/NG结果给MES系统; 3、上传设备生产过程中的异常信息给MES系统; 4、上传设备生产过程中的数据,…

(arxiv2401) CrossMAE

作者团队来自加州大学伯克利分校&#xff08;UC Berkeley&#xff09;和加州大学旧金山分校&#xff08;UCSF&#xff09;。论文主要探讨了在MAE的解码中&#xff0c;图像patch之间的依赖性&#xff0c;并提出了一种新的预训练框架 CrossMAE。 论文的主要贡献包括&#xff1a; …

【C++入门】关键字、命名空间以及输入输出

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

Ant Design Vue table固定列失效问题解决

问题描述&#xff1a;项目中封装好的公共table组件&#xff0c;基于Ant Design Vue table封装&#xff1b;使用中&#xff0c;用到了列固定&#xff0c;但是没生效&#xff0c;找了好久的原因。。。最后是因为外层容器标签导致&#xff1b; 解决方法&#xff1a;如果a-table组件…

Windows系统安装OpenSSH结合VS Code远程ssh连接Ubuntu【内网穿透】

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-AwzyR2lkHKjD9HYl {font-family:"trebuchet ms",verdana,arial,sans-serif;f…

【吊打面试官系列】Redis篇 - Redis单进程单线程好处?

大家好&#xff0c;我是锋哥。今天分享关于 【Redis单进程单线程好处&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; Redis单进程单线程好处&#xff1f; 代码更清晰&#xff0c;处理逻辑更简单 不用去考虑各种锁的问题&#xff0c;不存在加锁释放锁操作&…

使用简单MLP实现0-9数字识别,数据集为MNIST

简介 需求&#xff1a; 基于pytorch实现简单MLP&#xff0c;完成数字识别&#xff0c;采用MNIST手写数字作为数据集&#xff0c;MNIST&#xff1a;有6万张训练图片&#xff0c;1万张测试图片训练结束后&#xff0c;随机取3张测试图片&#xff0c;展示模型的预测结果和真实图片…