深入解析Cortex-M4中断机制:从NVIC原理到实战避坑指南

深入解析Cortex-M4中断机制:从NVIC原理到实战避坑指南
1. 项目概述在嵌入式系统的世界里中断机制就像是系统对外部事件的“本能反应”。想象一下你正在专心看书这时电话响了你会立刻放下书去接听接完后再回来继续阅读。中断之于微控制器就如同这个电话铃声它能让处理器从当前执行的“主线任务”中抽身优先处理更紧急的“支线任务”。对于基于ARM Cortex-M4内核的微控制器如TI的Tiva™ TM4C1292NCZAD这套“本能反应”系统被设计得异常精密和高效其核心便是嵌套向量中断控制器NVIC。理解NVIC、异常状态与优先级管理是编写稳定、高效且实时响应嵌入式软件的基石。无论是处理电机控制中的过流保护、通信接口的数据收发还是响应按键的即时操作都离不开这套机制的可靠运行。本文将带你深入Cortex-M4的中断腹地不仅解析其工作原理更会结合实战经验探讨如何避免常见陷阱构建健壮的中断驱动应用。2. NVIC中断系统的“交通指挥中心”嵌套向量中断控制器NVIC是Cortex-M4内核中一个高度集成、可配置的硬件模块它远不止是一个简单的中断“接线员”而是一个功能强大的“交通指挥中心”。它的核心职责是接收来自数十个甚至上百个外设如GPIO、UART、定时器或软件的中断请求IRQ并根据一套严格的规则进行仲裁、调度和管理。2.1 NVIC的核心功能与架构NVIC的设计哲学是硬件化、自动化和低延迟。与早期需要软件查询中断标志的架构不同NVIC在硬件层面完成了大部分繁重工作。中断请求的接收与挂起每个中断源都对应NVIC中的一个“挂起位”Pending Bit。当外设例如UART接收到一个字节或软件设置某个中断标志时对应的挂起位会被硬件自动置位。此时该中断进入“挂起”状态就像一个等待被叫号的顾客。NVIC会持续扫描所有挂起的中断。优先级仲裁这是NVIC最核心的功能之一。每个中断都有一个可配置的优先级对于Tiva C系列通常是0-7级数值越小优先级越高。NVIC内部有一个优先级仲裁器它会比较所有处于“挂起”状态的中断的优先级。当处理器处于可中断状态如未屏蔽所有中断时仲裁器会选出当前优先级最高的挂起中断准备提交给处理器核心执行。向量化中断与自动跳转Cortex-M4采用向量中断表Vector Table。这是一个存储在固定内存地址默认为0x00000000可重定位的数组数组的每一项都是一个函数指针指向对应异常或中断的服务例程地址。当NVIC仲裁出一个待处理的中断后它会根据该中断的“向量号”一个唯一的索引直接计算出其在向量表中的位置并自动将程序计数器PC跳转到对应的中断服务程序ISR入口。这个过程完全由硬件完成速度极快是实现低延迟响应的关键。现场自动保存与恢复在跳转到ISR之前NVIC会指挥处理器核心自动将关键的CPU寄存器如R0-R3, R12, LR, PC, xPSR压入当前使用的堆栈主堆栈MSP或进程堆栈PSP。这个被压入的数据结构称为“栈帧”Stack Frame。在ISR执行完毕返回时处理器又会自动将这些寄存器从堆栈中弹出恢复中断前的现场。这个过程对程序员是透明的极大地简化了中断编程。2.2 一个关键陷阱中断清除与写缓冲输入材料中提到了一个非常经典且容易踩坑的问题“NVIC sees the interrupt as still asserted”。这描述了这样一种场景假设一个外设比如GPIO边沿中断触发了一个中断CPU响应并进入了对应的ISR。在ISR中我们通过写外设的某个寄存器来清除中断标志位。然而由于处理器内部可能存在写缓冲Write Buffer或总线延迟对寄存器的“写清除”操作可能没有立即生效并传递到外设模块。如果此时ISR执行了返回指令NVIC可能仍然认为该中断源处于“断言”asserted状态因为它尚未感知到标志位已被清除。这会导致CPU刚从ISR返回立刻又因为同一个中断被挂起而重新进入该ISR形成错误的“重入”严重时会导致系统卡死或逻辑混乱。解决方案在ISR开头清除中断源这是一种保守但安全的做法。一进入ISR首先读取可能引发中断的状态寄存器然后立即执行清除操作。这样即使后续ISR执行时间较长也能确保在退出前有足够的时间让清除操作生效。但需注意有时需要先处理数据再清除标志以防数据丢失。清除操作后增加同步指令在写入清除中断标志的指令后紧跟一条对该外设寄存器或任何内存位置的“读”操作。例如在C语言中在HWREG(INT_CLEAR_REG) FLAG;之后可以加一句volatile uint32_t dummy HWREG(INT_CLEAR_REG);。这条读操作会强制冲刷Flush处理器的写缓冲区确保之前的写操作完成从而让NVIC能及时看到中断源已失效。在ARM汇编中可以使用DSB数据同步屏障或ISB指令同步屏障指令来达到类似效果确保内存操作的可见性和顺序。注意这个“写后读”或使用内存屏障指令的技巧在操作DMA控制器、配置时钟等对时序敏感的寄存器时同样重要。它是确保硬件行为符合软件预期的关键习惯。3. 异常状态机中断的“生命周期”异常Exception是一个比中断Interrupt更广义的概念。在Cortex-M中中断是异常的一种。每个异常包括所有中断在其生命周期中都处于以下四种状态之一理解这些状态是调试中断相关问题的关键。3.1 四种异常状态详解非活动Inactive这是异常的初始和最终状态。异常既没有被触发挂起也没有正在被处理活动。可以理解为这个异常源目前“风平浪静”。挂起Pending异常已被触发但处理器尚未开始执行其处理程序。触发方式可以是硬件触发外设设置中断标志。软件触发通过写NVIC的“中断挂起置位寄存器”如NVIC_ISPR来手动产生一个中断。 当异常处于挂起状态时NVIC的仲裁器会将其纳入优先级比较的候选队列。一个异常可以长时间处于挂起状态直到其优先级足够高且未被屏蔽才会被处理器响应。活动Active处理器已经响应该异常并且正在执行其异常处理程序如ISR。此时该异常在NVIC中的状态位会从“挂起”变为“活动”。一个关键特性是异常嵌套如果一个更高优先级的异常在某个异常处理程序执行期间发生那么这两个异常会同时处于“活动”状态。高优先级的异常处理程序会抢占Preempt低优先级的处理程序。活动且挂起Active and Pending这是一种特殊状态表示处理器正在处理该异常活动但同时同一个异常源又发出了一个新的请求挂起。这通常发生在中断处理速度跟不上中断触发频率时。例如一个高速UART在连续接收数据当前一个字节触发的ISR还在处理时下一个字节又到达并触发了中断。NVIC会记录这个新的挂起请求等待当前活动的中断处理完毕后如果该中断使能且优先级允许会立即再次进入其ISR可能通过尾链机制后文详述。3.2 状转换与软件干预异常状态之间的转换部分由硬件自动管理部分可由软件控制。例如软件可以通过写“中断挂起清除寄存器”NVIC_ICPR来手动清除一个挂起状态即使其硬件源可能仍然有效。这在某些需要软件“忽略”某些误触发或已经过时事件的场景下有用。但软件无法直接将一个异常从“活动”状态变为“非活动”这需要等待处理器执行完异常返回指令。理解这些状态有助于诊断问题。例如如果一个中断似乎只触发了一次就再也不响应了你需要检查中断源是否持续产生信号中断标志是否在ISR中被正确清除了中断是否被意外禁用Masked了或者它是否错误地停留在了“活动”状态4. 异常类型全景图Cortex-M4定义了多种异常类型它们拥有固定的向量号0-15和默认的优先级。中断IRQ是其中数量最多的一类向量号从16开始。向量号异常类型优先级激活方式简要说明与典型应用0---初始栈指针MSP值非异常。1复位Reset-3 (最高)异步上电、复位引脚触发。处理器停止当前操作从向量表0地址加载MSP从0x04地址开始执行。2不可屏蔽中断NMI-2异步最高优先级中断不可被屏蔽除复位外。用于处理电源失效、看门狗报警等最紧急事件。3硬故障Hard Fault-1同步/异步当其他故障处理程序无法处理错误或故障处理程序自身出错时触发。是系统错误的最后防线。4内存管理故障MemManage可编程同步由内存保护单元MPU违规或访问“永不执行”XN区域引发。用于提升系统鲁棒性。5总线故障Bus Fault可编程同步/异步指令预取或数据访问时发生总线错误如访问不存在的地址。6用法故障Usage Fault可编程同步执行未定义指令、非法未对齐访问、无效的状态转换如异常返回错误或除零错误若使能。7-10保留---11超级用户调用SVCall可编程同步由SVC指令触发。在操作系统中应用程序通过此指令请求内核服务。12调试监控Debug Monitor可编程同步用于调试当处理器未被暂停时处理调试事件。13保留---14可挂起的系统调用PendSV可编程异步由软件挂起常用于操作系统中的上下文切换因为它可以被延迟到没有其他中断时执行。15系统节拍定时器SysTick可编程异步系统定时器归零时触发为操作系统提供心跳时钟。16中断IRQ可编程异步来自外设如GPIO、UART、Timer或软件的中断请求。数量由芯片厂商定义。核心要点解析固定优先级复位、NMI、硬故障拥有固定的负优先级-3 -2 -1这意味着它们的优先级永远高于任何优先级可配置的异常默认0-7。这确保了系统在最坏情况下仍有恢复机制。同步 vs 异步同步异常由当前执行的指令直接导致如访问非法内存总线故障、执行未定义指令用法故障或执行SVC指令。它们会立即被处理。异步异常由外部事件或内部定时器触发与当前指令流无关如外设中断、NMI、SysTick。处理器可能在当前指令和异常处理之间执行完另一条指令。故障处理的意义MemManage、BusFault、UsageFault等可配置故障为开发者提供了精细的错误捕获能力。例如你可以通过MPU配置将某个内存区域设置为只读当程序意外写入时触发MemManage Fault在对应的故障处理程序中记录错误信息或进行安全恢复而不是让系统静默地崩溃或跑飞。5. 中断优先级管理与分组策略优先级管理是NVIC的灵魂它决定了在多个中断同时发生时谁先谁后以及能否相互抢占。5.1 优先级数值与抢占规则在Cortex-M4中优先级数值越小优先级越高。例如优先级为1的中断可以抢占优先级为3的中断。如果两个中断同时挂起且优先级相同则向量号较小的中断优先即IRQ编号小的先执行。抢占Preemption当处理器正在执行一个低优先级异常的处理程序时如果发生了一个更高优先级的异常则高优先级异常会抢占当前执行流程。处理器会保存当前上下文转去执行高优先级的处理程序。等高优先级的处理程序执行完毕返回后再恢复执行被抢占的低优先级处理程序。这形成了异常嵌套。非抢占如果新发生的异常优先级等于或低于当前正在处理的异常优先级则它不会发生抢占。新异常会保持“挂起”状态直到当前处理程序执行完毕并返回后才会被仲裁执行。5.2 优先级分组抢占优先级与子优先级为了更灵活地控制中断行为Cortex-M4引入了优先级分组的概念。一个8位的中断优先级寄存器对于Tiva C系列实际使用高3位或4位被划分为两个字段抢占优先级Group Priority 或称Preemption Priority决定中断之间是否能相互抢占。子优先级Subpriority在抢占优先级相同的情况下决定哪个中断先被处理。分组通过应用程序中断和复位控制寄存器AIRCR中的PRIGROUP字段来配置。例如假设我们使用3位优先级值0-7PRIGROUP设置为2则表示高2位bit[7:6]表示抢占优先级0-3共4级。低1位bit[5]表示子优先级0-1共2级。仲裁规则抢占优先级高的中断可以无条件抢占抢占优先级低的中断。这是第一仲裁准则。如果两个中断的抢占优先级相同则比较它们的子优先级子优先级高的先执行数值小为高。如果抢占优先级和子优先级都相同则比较它们的硬件中断编号IRQ Number编号小的先执行。配置示例与实战意义 假设系统中有三个中断高速ADC采样IRQ20 要求实时性最高、UART通信IRQ21 中等、按键扫描IRQ22 最低。我们希望ADC能抢占任何其他中断而UART和按键之间不能相互抢占但UART应先于按键处理。步骤1确定分组。我们需要至少2级抢占优先级ADC一级UART和按键共享一级。子优先级至少2级区分UART和按键。可以选择PRIGROUP配置使得抢占优先级占2位4级子优先级占1位2级。步骤2分配优先级。ADC中断抢占优先级 0最高子优先级 0。编码后优先级值 0b00_0 0。UART中断抢占优先级 1子优先级 0。编码后优先级值 0b01_0 2。按键中断抢占优先级 1子优先级 1。编码后优先级值 0b01_1 3。结果ADC抢占优先级0可以抢占UART和按键抢占优先级1。当UART按键同时挂起时由于抢占优先级相同比较子优先级UART子优先级0优先于按键子优先级1执行。实操心得优先级分组策略需要在系统设计初期规划好。一个常见的策略是将最紧急的、关乎系统安全的中断如急停、看门狗设为最高的抢占优先级。将时间敏感但可短暂延迟的中断如通信接口设为中等抢占优先级。将非实时性的后台任务如LED闪烁、非关键状态查询设为最低抢占优先级甚至共享同一抢占优先级用子优先级或自然顺序区分。避免滥用高抢占优先级过多的嵌套会增加栈空间消耗和响应时间的不确定性。6. 异常进入与返回的微观过程异常处理流程的细节直接影响着系统的实时性和可靠性。Cortex-M4对此进行了高度优化。6.1 异常进入压栈与取向量当NVIC仲裁出一个需要响应的异常且处理器允许响应未通过PRIMASK等寄存器屏蔽时硬件会自动执行以下序列完成当前指令处理器会完成当前正在执行的指令除少数长指令外。保存上下文压栈将8个寄存器xPSR PC LR R12 R3 R2 R1 R0自动压入当前活跃的堆栈MSP或PSP。如果使用了浮点单元FPU且上下文包含浮点状态则会额外压入S0-S15和FPSCR寄存器。这个过程称为“栈帧”创建。取向量同时处理器从向量表中取出对应异常处理程序的起始地址。更新寄存器将异常返回值EXC_RETURN加载到链接寄存器LR中。这个特殊值如0xFFFFFFF1 0xFFFFFFF9等指示了返回时应使用的堆栈指针MSP或PSP以及返回模式线程模式或处理模式。跳转执行将取出的向量地址加载到程序计数器PC开始执行异常处理程序。6.2 异常返回出栈与恢复异常处理程序执行完毕后必须通过特定的序列返回通常是将EXC_RETURN值加载到PC。这通过执行一条BX LR或POP {..., PC}等指令实现。当处理器发现PC被加载了EXC_RETURN值时会触发异常返回序列恢复上下文出栈从堆栈中弹出之前保存的寄存器恢复中断前的现场。返回原模式根据EXC_RETURN的值切换回之前的处理器模式线程模式或处理模式和堆栈指针。继续执行程序从被中断的指令处继续执行。6.3 高级机制尾链与迟到为了最小化中断延迟Cortex-M4引入了两个精妙的硬件优化机制尾链Tail-Chaining假设当前正在执行中断A的ISR。在ISR即将返回时NVIC检测到另一个已挂起的中断B且B的优先级足够高。在传统的处理器中流程是A返回 - 出栈A的上下文 - 可能执行几条主程序指令 - B触发 - 压栈B的上下文 - 执行B。尾链优化省去了中间不必要的出栈和压栈操作。当A的ISR返回时硬件发现B已在等待它会跳过A的上下文出栈和B的上下文压栈直接跳转到B的ISR执行。这节省了大量时间特别适合连续处理多个中断的场景。迟到Late-Arriving假设处理器已经开始为中断A保存上下文压栈。在压栈操作完成之前一个更高优先级的中断B到达了。此时处理器会立即转向处理中断B但不会中断正在进行的压栈操作因为A和B需要保存的上下文是相同的。压栈操作完成后处理器直接取B的向量并执行B的ISR。这保证了更高优先级的中断能获得尽可能快的响应即使它“迟到”了一点。B处理完毕后再通过尾链机制处理A如果A仍挂起。注意事项尾链和迟到机制是硬件自动完成的对软件透明。但它们意味着在编写ISR时不能假设ISR一结束处理器就立刻回到被中断的线程。高优先级中断的“插入”可能比你想象的更频繁和迅速。这强调了保持ISR尽可能短小精悍的重要性也影响了在ISR和主程序之间共享数据时对临界区的保护策略。7. 故障处理系统的“安全气囊”故障Fault是系统运行异常的“警报器”。Cortex-M4提供了丰富的故障类型帮助开发者定位深层错误。7.1 主要故障类型与排查硬故障Hard Fault这是“最后的兜底”故障。当其他可配置故障如内存管理、总线、用法故障被禁用或者这些故障处理程序自身出错时错误会**升级Escalate**为硬故障。硬故障无法被屏蔽除复位和NMI外优先级最高-1。任何无法归类的严重错误都会落到这里。内存管理故障MemManage Fault通常由MPU配置引发。例如用户模式线程试图访问特权区域或访问了标记为“永不执行”XN的代码区域。即使MPU被禁用访问XN区域也会触发此故障。总线故障Bus Fault在读取指令预取失败或读写数据时访问了无效的内存地址例如向未初始化的外部存储器写数据或者总线返回错误响应。用法故障Usage Fault由非法指令流引起如执行未定义的指令、尝试进行非法的未对齐内存访问在Cortex-M4上通常只有对多字节的原子访问要求对齐、尝试切换到无效的处理器状态如从Thumb状态切换到ARM状态或异常返回时使用了无效的EXC_RETURN值。7.2 故障状态寄存器与调试技巧当故障发生时仅仅进入故障处理程序是不够的必须知道“为什么”会发生。Cortex-M4提供了一系列故障状态寄存器寄存器名称所属故障作用HFAULTSTAT硬故障指示硬故障的具体原因如由总线故障升级而来FORCED 或向量表读取失败VECT。MFAULTSTAT内存管理故障指示是取指IERR、数据访问DERR还是栈操作MSTKE/MUSTKE导致的违规。BFAULTSTAT总线故障区分是精确总线错误PRECISE 能精确定位到出错指令还是非精确总线错误IMPRE 可能由写缓冲导致难以直接定位。UFAULTSTAT用法故障指示是未定义指令UNDEF、非法未对齐访问UNALIGN、除零DIV0还是无效状态INVSTAT/INVPC等。MMADDR/FAULTADDR内存管理/总线故障故障地址寄存器。记录触发故障的内存访问地址。这是定位野指针或数组越界的利器。实战调试流程在故障处理程序如HardFault_Handler中首先保存现场如果可能。立即读取上述故障状态寄存器保存到全局变量中。因为后续的其他操作如调用函数可能会覆盖这些寄存器。同时可以读取链接寄存器LR的值。在进入故障处理程序时LR中保存的是EXC_RETURN但其值也包含了返回地址的信息。更可靠的方法是分析堆栈帧。在故障发生时被压入堆栈的PC值指向了触发故障的指令对于同步故障或故障发生后即将执行的下一条指令对于异步故障。通过调试器查看这些保存的信息结合反汇编就能精确定位到出错的代码行。一个简单的HardFault处理函数示例基于CMSIS// 全局变量用于存储故障信息 volatile uint32_t g_hardfault_sp; volatile uint32_t g_hardfault_pc; volatile uint32_t g_hardfault_lr; volatile uint32_t g_hardfault_psr; volatile uint32_t g_hardfault_cfsr; // 组合故障状态寄存器包含M/B/U Fault状态 __attribute__((naked)) void HardFault_Handler(void) { __asm volatile( tst lr, #4\n\t // 检查EXC_RETURN的bit2判断使用的是MSP还是PSP ite eq\n\t mrseq r0, msp\n\t // 如果使用MSP将其值存入R0 mrsne r0, psp\n\t // 如果使用PSP将其值存入R0 ldr r1, g_hardfault_sp\n\t str r0, [r1]\n\t // 保存堆栈指针值 ldr r1, [r0, #24]\n\t // 从栈帧中获取PC (栈帧中PC在偏移24字节处) ldr r2, g_hardfault_pc\n\t str r1, [r2]\n\t ldr r1, [r0, #20]\n\t // 获取LR ldr r2, g_hardfault_lr\n\t str r1, [r2]\n\t ldr r1, [r0, #28]\n\t // 获取xPSR ldr r2, g_hardfault_psr\n\t str r1, [r2]\n\t ldr r1, 0xE000ED28\n\t // CFSR寄存器地址 ldr r1, [r1]\n\t ldr r2, g_hardfault_cfsr\n\t str r1, [r2]\n\t bkpt #0\n\t // 触发调试断点方便查看变量 b .\n\t // 无限循环等待调试器介入 ); }重要提示在实际产品中故障处理程序除了记录信息还应尝试进行系统恢复或安全关闭例如重置关键外设、保存日志到非易失存储器然后触发软件复位。8. 中断编程实战与避坑指南理解了原理最终要落实到代码。以下是一些基于Tiva C系列TM4C1292NCZAD和典型驱动库如TivaWare的实战要点。8.1 中断配置标准流程外设级使能首先配置具体的外设使其能产生中断事件。例如使能UART的接收中断UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);。NVIC级使能与优先级设置然后在NVIC层面使能该中断通道并设置其优先级。// 设置UART0中断的优先级为2假设抢占优先级分组已设好 IntPrioritySet(INT_UART0, 2 5); // TivaWare中优先级值左移5位对齐 // 在NVIC中使能UART0中断 IntEnable(INT_UART0);全局中断使能最后使用__enable_irq()或IntMasterEnable()指令开启处理器的全局中断响应。8.2 ISR编写黄金法则快进快出ISR应尽可能短小。只做最必要的工作如读取数据、清除标志、设置事件标志或发送信号量。复杂的处理应放到主循环或低优先级任务中。及时清除中断标志必须在ISR内清除触发本次中断的外设标志位防止重复进入。清除顺序有讲究对于可能因读取数据而自动清除的标志如UART的RX标志先读数据再清除或检查对于需要显式写入清除的标志参考第2.2节的“写后读”技巧。避免阻塞操作严禁在ISR中使用delay()、等待循环、或可能引起阻塞的库函数如某些printf实现。谨慎使用浮点运算如果主程序使用了FPU且中断可能发生在浮点上下文需注意FPU状态的自动保存与恢复。对于时间敏感的ISR应避免使用浮点运算以减少上下文保存开销。共享数据保护如果ISR和主程序或其他ISR共享变量必须使用临界区保护。最简方法是使用__disable_irq()和__enable_irq()临时关闭全局中断但会增大中断延迟。更优方案是使用原子操作或信号量在RTOS中。8.3 常见问题排查清单现象可能原因排查步骤中断完全不触发1. 外设中断未使能。2. NVIC中断未使能。3. 全局中断未开启。4. 中断优先级配置错误如设为最低且被屏蔽。5. 向量表地址错误或未正确初始化。1. 检查外设配置寄存器。2. 检查IntEnable调用。3. 确认__enable_irq()已执行。4. 检查PRIMASK,FAULTMASK,BASEPRI寄存器。5. 确认启动文件正确向量表已链接到正确地址。中断只触发一次1. ISR中未清除中断标志。2. 清除标志的时机或方式不对见2.2节。3. 外设硬件问题无法再次产生标志。1. 仔细检查ISR中的清除代码。2. 在清除操作后添加__DSB()或读操作。3. 用逻辑分析仪或调试器查看外设中断信号。系统进入HardFault1. 栈溢出最常见。2. 访问非法地址空指针、数组越界。3. 未对齐访问。4. 故障处理程序本身出错。1. 检查HFAULTSTAT,CFSR寄存器。2. 检查MMADDR/FAULTADDR寄存器。3. 分析故障时的堆栈和PC值见7.2节。4. 增大栈空间检查指针和数组索引。中断响应延迟过长1. 被更高优先级中断或长时间ISR阻塞。2. 全局中断被长时间关闭。3. 使用了大量需要关中断的临界区。1. 优化高优先级ISR的代码。2. 审查代码减少__disable_irq()的持续时间。3. 使用更精细的同步机制如原子标志。中断嵌套行为异常1. 优先级分组配置错误。2. 抢占优先级和子优先级概念混淆。3. 在ISR中错误地修改了优先级。1. 确认AIRCR.PRIGROUP设置符合设计。2. 重新计算并设置每个中断的优先级值。3. 避免在运行时动态修改正在活动的中断的优先级。8.4 电源管理中的中断唤醒Cortex-M4支持睡眠Sleep和深度睡眠Deep Sleep模式以降低功耗。中断是唤醒处理器的主要方式。WFIWait For Interrupt执行WFI指令后处理器进入睡眠直到有足够优先级的中断发生才会唤醒并执行该中断。WFEWait For Event执行WFE指令后处理器检查一个内部事件寄存器。如果为0则睡眠为1则清0并继续执行。事件可由SEV指令、外部事件信号或通过配置任何挂起的中断即使被禁用设置。Sleep-on-Exit这是一个很有用的特性当设置SCR.SLEEPONEXIT位后处理器在完成所有异常处理程序后不会返回线程模式执行主循环而是直接进入睡眠。这特别适合纯事件驱动的应用处理器只在有中断需要处理时才醒来极大地降低了平均功耗。使用建议在低功耗应用中合理配置中断的唤醒能力至关重要。确保用于唤醒的中断已被正确使能并且其优先级足够高或未被屏蔽。在进入低功耗模式前通常需要清理外设状态配置好唤醒源然后执行WFI或WFE。唤醒后应检查唤醒源进行相应的处理。