首页 > 其他分享 >《ARM Cortex - M3与Cortex - M4权威指南》第8章深入了解异常处理详解

《ARM Cortex - M3与Cortex - M4权威指南》第8章深入了解异常处理详解

时间:2025-01-13 13:03:05浏览次数:3  
标签:处理 压栈 M4 指令 Cortex M3 寄存器 异常 处理器

8.1 简介

8.1.1 关于本章

本章主要聚焦于ARM Cortex - M3与Cortex - M4处理器中异常处理的深入知识。旨在让读者全面理解异常处理机制,包括异常处理的实现方式、栈帧的管理以及异常流程中的各种细节,这些知识对于开发高效、可靠的基于这两款处理器的嵌入式系统至关重要。

8.1.2 C实现的异常处理

在C语言中实现异常处理,通常需要借助编译器提供的特定机制。由于ARM Cortex - M3与M4处理器的硬件架构特性,C语言实现异常处理需要考虑如何与硬件的异常机制进行交互。

  • 函数定义:异常处理函数通常没有显式的形式参数,因为异常的相关信息一般通过硬件寄存器或特定的全局变量来传递。例如,异常原因可能存储在特定的硬件寄存器中,C函数通过读取该寄存器来确定如何处理异常。
  • 代码示例
// 假设硬件提供了一个函数来获取异常原因寄存器的值
extern int get_exception_cause(); 

// 异常处理函数
void exception_handler(void) { 
    int cause = get_exception_cause(); // 获取异常原因
    if (cause == 0x01) { 
        // 处理特定类型的异常,例如内存访问错误
        // 这里可以添加修复错误或记录日志等操作
    } else if (cause == 0x02) { 
        // 处理另一种类型的异常,如总线错误
    }
}
  • 设计模式:这里采用了一种简单的条件判断模式。根据获取到的异常原因,通过if - else语句分支来执行不同的异常处理逻辑。这种模式简单直接,适用于异常类型相对较少且处理逻辑较为明确的情况。

8.1.3 栈帧

栈帧是在函数调用过程中,在栈上为该函数分配的一块内存区域,用于存储函数的局部变量、参数以及返回地址等信息。在异常处理中,栈帧同样起着关键作用。

  • 栈帧结构:当异常发生时,硬件会自动将部分寄存器的值压入栈中,形成异常处理的栈帧。这些寄存器通常包括程序计数器(PC)、链接寄存器(LR)以及部分通用寄存器(如R0 - R3)等。压入栈中的这些值记录了异常发生时处理器的运行状态,以便在异常处理结束后能够恢复到原来的执行状态。
  • 栈帧管理:异常处理函数在执行过程中,可能需要进一步在栈上分配空间来存储临时变量等。例如,如果异常处理函数需要进行复杂的计算或调用其他函数,就需要在栈帧中为这些操作预留空间。异常处理结束后,栈帧需要正确地恢复,确保处理器能够准确地回到异常发生前的状态继续执行。
  • 设计模式:栈帧管理遵循一种后进先出(LIFO)的模式。异常发生时压入栈的信息,在异常处理结束时按照相反的顺序弹出。这种模式与栈的特性相匹配,保证了状态的正确恢复和函数调用的正确性。

8.1.4 exc_return

exc_return是一个特殊的值,用于在异常返回时告诉处理器如何恢复执行。它存储在链接寄存器(LR)中。

  • 值的含义exc_return的值的不同位编码了不同的信息,例如返回的模式(线程模式还是处理模式)、使用的栈指针(主栈指针还是进程栈指针)等。例如,当exc_return的最高位为1时,表示返回线程模式;为0时,表示返回处理模式。
  • 作用:在异常返回时,处理器根据exc_return的值来正确地恢复寄存器的值,并切换到合适的执行模式和栈指针。这确保了异常处理结束后,处理器能够准确地回到异常发生前的上下文继续执行。
  • 设计模式exc_return采用了一种编码设计模式,通过特定的位组合来传递丰富的控制信息。这种设计模式使得在有限的寄存器空间内能够传递多种关键的恢复信息,提高了系统的灵活性和效率。

8.2 异常流程

8.2.1 异常进入和压栈

  • 异常检测:当处理器检测到一个异常事件,如中断、错误等,异常处理流程开始。处理器会暂停当前正在执行的指令,准备进入异常处理程序。
  • 硬件压栈:处理器自动将部分寄存器的值压入栈中,这些寄存器包括程序计数器(PC)、链接寄存器(LR)、R0 - R3以及xPSR(扩展程序状态寄存器)。压栈的顺序和方式由硬件规定,确保了异常发生时的现场能够被完整保存。例如,PC寄存器的值被压入栈,记录了异常发生时正在执行的指令地址,以便在异常处理结束后能够继续执行。
  • 寻找异常向量:处理器根据异常类型,在异常向量表中查找对应的异常处理程序入口地址。异常向量表是一段存储异常处理程序入口地址的内存区域,每个异常类型对应一个特定的地址。
  • 设计模式:异常进入和压栈过程采用了一种状态保存与转移的模式。首先保存当前处理器的运行状态(通过压栈),然后根据异常类型转移到相应的处理程序。这种模式保证了系统在遇到异常时能够安全地暂停当前任务,并切换到合适的处理流程。

8.2.2 异常返回和出栈

  • 恢复寄存器:异常处理程序执行完毕后,通过读取链接寄存器(LR)中的exc_return值,处理器按照特定规则从栈中弹出之前压入的寄存器值,恢复到异常发生前的状态。例如,将栈中的PC值弹出,恢复到程序计数器,使得处理器能够继续从异常发生处的下一条指令开始执行。
  • 栈指针调整:在出栈过程中,栈指针会相应地调整,恢复到异常发生前的位置。这确保了栈的状态与异常发生前一致,为后续的函数调用等操作提供正确的栈环境。
  • 返回执行:处理器根据exc_return的值确定返回的模式(线程模式还是处理模式),然后返回到异常发生前的上下文继续执行。
  • 设计模式:异常返回和出栈过程是异常进入和压栈的逆过程,遵循后进先出的原则。这种模式保证了系统能够准确地恢复到异常发生前的状态,继续正常的执行流程。

8.3 中断等待和异常处理优化

8.3.1 什么是中断等待

中断等待是指当一个中断请求到达时,由于当前正在执行的指令处于一个不适合被中断的阶段(例如一些多周期指令正在执行中),处理器不能立即响应中断,而是需要等待当前指令执行完毕后才进入中断处理流程。这种等待机制确保了指令执行的完整性,避免因中断而导致数据或状态的不一致。

8.3.2 多周期指令执行时的中断

在ARM Cortex - M3与M4处理器中,某些指令需要多个时钟周期才能完成执行。当这些多周期指令正在执行时,如果有中断请求到来,处理器不会立即响应中断。例如,一个乘法指令可能需要多个时钟周期来完成运算和结果存储。在这个过程中,处理器会继续执行该指令,直到其完成,然后才检查是否有中断请求并进入中断处理流程。这样可以保证指令操作的原子性,防止中断干扰指令的正常执行。

8.3.3 末尾连锁

末尾连锁是一种优化机制,用于提高异常处理的效率。当一个异常处理程序即将结束,并且此时又有一个新的异常请求到达时,处理器可以直接从当前异常处理程序跳转到新的异常处理程序,而不需要先完全返回主程序再进入新的异常处理。这样减少了异常处理的额外开销,例如不需要重新进行栈的切换和寄存器的保存/恢复等操作。例如,在一个实时系统中,可能会频繁地出现多个中断请求,末尾连锁机制可以使得系统能够更快地响应新的中断,提高系统的实时性。

8.3.4 延迟到达

延迟到达是指当一个异常请求到达时,由于当前正在处理一个更高优先级的异常,该异常请求会被暂时搁置,直到高优先级异常处理完成后才被处理。这种机制确保了高优先级异常能够得到及时处理,而低优先级异常不会干扰高优先级异常的处理流程。例如,在一个系统中,硬件故障相关的异常可能具有较高优先级,而一些普通的外设中断具有较低优先级。当硬件故障异常正在处理时,普通外设中断请求会被延迟到达,等待硬件故障异常处理完毕。

8.3.5 出栈抢占

出栈抢占是指在异常处理过程中,当一个更高优先级的异常请求到达时,处理器可以在当前异常处理的出栈过程中暂停,转而处理新的更高优先级异常。这样可以确保高优先级异常能够得到更及时的响应,而不需要等待当前异常处理完全结束。例如,在一个同时处理多个任务的嵌入式系统中,可能会出现一些紧急任务的中断请求,出栈抢占机制可以让系统快速响应这些紧急任务。

8.3.6 惰性压栈

惰性压栈是一种优化策略,它不是在异常发生时立即将所有需要保存的寄存器都压入栈中,而是在实际需要时才进行压栈操作。例如,如果一个异常处理程序不需要使用某些寄存器的值,那么这些寄存器的值就不需要在异常发生时立即压栈。这样可以减少异常处理的时间开销,提高系统的性能。例如,在一些简单的中断处理程序中,可能只需要处理特定的标志位,而不需要涉及到所有寄存器,惰性压栈就可以避免不必要的压栈操作。

标签:处理,压栈,M4,指令,Cortex,M3,寄存器,异常,处理器
From: https://blog.csdn.net/qq_40844444/article/details/145072919

相关文章

  • 《ARM Cortex-M3与Cortex-M4权威指南》 第2章 嵌入式软件开发简介
    2.1ARM微控制器是怎样构成的ARM微控制器通常由处理器内核(如Cortex-M3或Cortex-M4)、片上外设(如定时器、串口、ADC等)、内存(包括Flash用于存储程序代码,SRAM用于数据存储)以及总线系统组成。处理器内核负责执行指令,片上外设实现与外部设备的交互,内存用于存储程序和数据,总线......
  • 在keil中ARMCC v6 编译器中用C语言实现ARM cortex-M4 实现startup代码
    #include"stdint.h"#defineStack_Size0x00000800U#defineHeap_Size0x00000400Uuint8_tStack_Mem[Stack_Size]__attribute__((section("STACK")));uint32_t*const__initial_sp=(uint32_t*)&Stack_Mem[Stack_Size];uint8_tHeap_......
  • STM32中的内存映射
     STM32中的内存映射在STM32中,内存映射通常如下:Flash:存储.text段(代码)、.rodata段(只读数据)和.data段的初始值。RAM:存储.data段(运行时)、.bss段、栈和堆。4. 程序启动过程在STM32中,程序启动时会发生以下操作:从Flash中加载.data段的初始值到RAM。将.bss......
  • 【STM32】利用SysTick定时器定时1s
    1.SysTick简单介绍SysTick定时器是一个24位的倒计数定时器,当计数到0时,将从RELOAD寄存器中自动重装载定时初值,开始新一轮计数。SysTick定时器用于在每隔一定的时间产生一个中断,即使在系统睡眠模式下也能工作。关于SysTick详细说明,请查看该文章:STM32—delay和操作系统共用Sys......
  • JSP客制化键盘网站ql5m4(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表技术要求: 开发语言:JSP前端使用:HTML5,CSS,JSP动态网页技术后端使用SpringBoot,Spring技术主数据库使用MySQL开题报告内容一、项目背景随着电子竞技的迅猛......
  • STM32之LWIP网络通讯设计-上(十四)
    STM32F407系列文章-LWIP-Network(十四)目录前言一、以太网简介二、网络协议简介1.OSI模型2.TCP/IP协议3.协议层报文间的封装与拆封4.lwIP1.lwIP特性2.lwIP开源网址3.lwIP参考书籍三、通讯连接示意四、STM32内部ETH 1.内部MAC2.内部DMA五、PHY驱动芯片1.功......
  • exam4-作业整理(包含部分统考真题)
    exam4-作业整理(包含部分统考真题)H1概述相关CPU提速计算答案是D这里把这道题拿过来,主要是因为容易出小错误,速度提升50%,不意味着时间变成50%v=v*3/2;t=t*2/3CPI与时间答案是C这里要算时间,CPI*指令数量*指令周期时间机器字长的寄存器机器字长......
  • SENT协议深度解析-----使用STM32发送SENT信号
    一、SENT信号的结构在上一期中,我们介绍了SENT信号的接收,这一期我们来讲解一下SENT信号的发送,在讲解之前,我们需要先了解一下SENT信号的结构,SENT信号分为两种类型:快速通道类型、慢速通道类型,慢速通道分为短串行数据、增强串行数据,一共三种信号结构发送方式,在汽车MCU领域中,SEN......
  • 【STM32】MCU运行多段代码,Flash程序更新的实现方式之一
    【STM32】MCU运行多段代码,Flash程序更新的实现方式之一文章目录BootLeader跳转到BootLeader跳转到Flash其他位置MCU运行多段代码其他程序更新烧录方式附录:Cortex-M架构的SysTick系统定时器精准延时和MCU位带操作SysTick系统定时器精准延时延时函数阻塞延时非阻塞延时......
  • STM32垃圾分类系统设计与实现
    引言垃圾分类作为现代环保和资源回收的重要环节,已经成为了各地政府和环保组织高度关注的议题。合理的垃圾分类不仅能够有效减少垃圾的填埋量,还能提高资源的回收利用率,减少环境污染。随着物联网技术的发展,智能垃圾分类系统的设计和实现成为了当前研究的热点。本文将介绍如......