
1. 项目概述深入MPC8313E的中枢神经在嵌入式系统开发尤其是网络通信处理器这类对实时性要求苛刻的领域中断管理的好坏直接决定了系统的“反应速度”和“多任务协调能力”。想象一下一个路由器需要同时处理来自多个网口的数据包、定时器事件、DMA传输完成信号以及各种外设的请求如果所有事件都靠CPU轮询来检查那CPU将疲于奔命效率低下。中断机制就是让这些外部事件能够“插队”通知CPU“嘿我这儿有急事快来处理一下”而中断控制器IPIC就是这个“插队”系统的总调度员。MPC8313E作为Freescale现NXPPowerQUICC II Pro系列中的经典通信处理器其集成的**IPICIntegrated Programmable Interrupt Controller**是一个功能强大且高度可配置的模块。它远不止是一个简单的中断收集器而是一个具备优先级仲裁、中断类型管理、向量化处理等高级功能的硬件单元。对于驱动工程师和系统架构师而言吃透IPIC的寄存器配置是优化系统性能、确保稳定性的关键一步。很多新手在面对手册中密密麻麻的寄存器描述时容易发怵觉得配置中断就是“依葫芦画瓢”设置几个位。但实际上如果不理解每个寄存器位背后的设计意图和联动关系很容易掉进坑里导致中断丢失、响应延迟甚至出现难以复现的诡异问题。本文将聚焦于IPIC最核心的中断屏蔽与优先级配置机制以SIMSR系统内部中断屏蔽寄存器和SIPRR系统内部中断优先级寄存器等关键寄存器为例拆解其每一位的含义并结合实际应用场景手把手带你理解如何动态调整像SYSD0P、MIXA0P这样的字段来定制一套符合你项目需求的中断调度策略。无论你是正在为MPC8313E编写BSP板级支持包还是希望深入理解PowerPC架构的中断子系统这篇文章都将提供从原理到实操的详细指南。2. IPIC核心架构与中断处理流程拆解在深入寄存器细节之前我们必须先建立起对MPC8313E IPIC整体工作流程的宏观认知。这有助于理解后续每个寄存器在哪个环节发挥作用而不是孤立地记忆位定义。2.1 中断信号的分类与流向IPIC管理的中断源五花八门但大致可以分为三类内部中断由芯片内部外设产生如eTSEC以太网控制器、UART、I2C、SPI、DMA、定时器PIT/RTC等。这些中断通过芯片内部总线通知IPIC。外部中断通过芯片的IRQ[0:4]这5个引脚从外部输入。可以配置为电平触发或边沿触发。错误中断MCP Machine Check Exception属于非屏蔽中断NMI的一种用于报告严重的系统错误如看门狗超时、总线错误等。其处理流程与常规中断不同优先级最高且通常不可屏蔽。所有中断请求的汇聚与分发可以概括为以下流程中断源内部/外部 - 中断状态寄存器SIPNR/SEPNR置位 - 经过中断屏蔽寄存器SIMSR/SEMSR过滤 - 进入优先级仲裁逻辑 - 根据优先级和类型生成对应的CPU异常信号INT, CINT, SMI - CPU跳转到对应的异常向量表入口执行中断服务程序ISR。这个流程中屏蔽和优先级仲裁是两个最关键的环节也是我们通过寄存器主要配置的部分。2.2 优先级体系分组、散布与最高优先级IPIC的优先级设计非常灵活它不是简单的固定优先级列表而是一个多层次的、可编程的体系。理解下表是掌握优先级配置的关键概念说明可编程性影响中断组Group将多个中断源如UART1, I2C1, SEC等归为一个逻辑组如SYSD组、MIXA组、MIXB组。组内成员固定但组内优先级可动态调整。决定了哪些中断可以放在一起比较优先级。组内优先级在一个组内如SYSD组哪个中断源排第一优先级最高。通过SIPRR_D.SYSD0P等字段配置。可动态编程。实现“旋转优先级”防止低优先级中断饿死。组间优先级不同组如MIXA组 vs SYSD组谁更重要。通过“Grouped”集中或“Spread”散布模式静态选择不可运行时动态切换。决定了不同功能模块的中断延迟。最高优先级中断HPI可以指定任意一个中断源为全局最高优先级超越所有组间优先级规则。通过SICFR[HPI]可动态编程。用于处理最紧急的单一事件如关键报警。“Grouped”与“Spread”模式详解 这是IPIC一个独特且重要的设计。以MIXA组为例它包含了RTC SEC、PIT、PCI和外部中断IRQ0-3。Grouped模式该组的所有中断优先级位置在总表中是连续排列的例如在表8-31中MIXA0-3占据优先级2-5。这种模式让该组所有中断都能获得非常低的延迟适合组内所有中断源都是高速、高频率事件的场景。Spread模式该组的中断优先级位置在总表中被打散插入到其他中断组之间例如MIXA1在优先级11MIXA2在25MIXA3在39。这种模式避免了单个组“霸占”高优先级区域让其他组的中断也有机会被及时响应适合系统需要平衡多个不同功能模块响应时间的场景。注意Grouped/Spread模式是在芯片设计或系统初始化时通过特定配置可能涉及其他未在本文片段中列出的寄存器如SICFR选择的一旦选定在运行中通常不能动态更改。这与组内优先级可以动态调整的特性有本质区别。3. 关键寄存器详解与配置实战现在我们切入核心逐一剖析那些控制中断命运的关键寄存器。手册中的描述是准确的但我们需要将其翻译成工程师能直接理解和操作的逻辑。3.1 系统内部中断屏蔽寄存器SIMSR_H/L这是中断进入调度队列的“第一道门卫”。功能用于使能或禁止屏蔽特定的内部中断源。每个位对应一个内部中断源如UART1、eTSEC1 Tx等。当某个中断被屏蔽时即使该中断事件发生且对应的状态位SIPNR被置1IPIC也不会向CPU核心提交中断请求。寄存器位SIMSR_H和SIMSR_L是两个32位寄存器共同覆盖所有内部中断源。具体哪个中断对应哪一位需要查阅手册中的Table 8-7和Table 8-9输入片段中未完全列出。操作写1使能解除屏蔽中断写0屏蔽中断。读取则返回当前屏蔽状态。核心操作与避坑指南// 假设我们要使能UART1中断假设其在SIMSR_L的bit 2并屏蔽eTSEC1接收中断假设其在SIMSR_H的bit 8 volatile uint32_t *simsr_l (uint32_t *)0xAddr_SIMSR_L; // 实际地址需查手册 volatile uint32_t *simsr_h (uint32_t *)0xAddr_SIMSR_H; // 1. 读取-修改-写入操作确保不干扰其他位 uint32_t temp *simsr_l; temp | (1 2); // 设置bit2为1使能UART1中断 *simsr_l temp; temp *simsr_h; temp ~(1 8); // 清除bit8为0屏蔽eTSEC1 Rx中断 *simsr_h temp;重要警告来自手册Note如果在清除某个SIMSR屏蔽位即屏蔽中断的同一时刻对应的中断源恰好发出了请求这个请求会被静默丢弃。即使你稍后重新设置SIMSR位使能中断那个被丢弃的请求也不会再被处理。这意味着在动态屏蔽/使能中时存在一个极小的竞争窗口可能导致中断丢失。对于可靠性要求高的场景安全的做法是先确保外设本身不再产生中断如关闭外设中断使能再操作SIMSR或者在屏蔽后主动查询并清除对应的中断状态寄存器SIPNR。3.2 系统内部中断优先级寄存器SIPRR_D这是调度员的“排班表”决定了同一组SYSD组内部谁先“发言”。功能SIPRR_D寄存器用于配置SYSD组包含UART1, UART2, SEC, eTSEC1/2 1588 Timer, I2C1, I2C2, SPI等中断源内部8个优先级位置SYSD0P至SYSD7P分别由哪个中断源占据。SYSD0P优先级最高SYSD7P最低。关键字段解析以SYSD0P为例位域Bits[0:2]对应SYSD0P。编码000代表 UART1 占据最高优先级位置SYSD0001代表 UART2以此类推111代表 SPI。动态性手册明确指出“These bits can be changed dynamically.” 这意味着你可以在系统运行时根据负载情况动态调整优先级。例如在系统启动初期UART调试输出很重要可以将UART1设为最高优先级而在正常运行后网络处理成为关键则可以将eTSEC1的中断优先级调高。配置示例 假设我们需要将SYSD组的优先级顺序配置为最高优先级给eTSEC1 1588定时器其次是SEC然后是UART1。volatile uint32_t *siprr_d (uint32_t *)0xAddr_SIPRR_D; uint32_t priority_config 0; // 配置SYSD0P (bits 0-2) 为 eTSEC1 1588 Timer (编码011) priority_config | (0x3 0); // 011 // 配置SYSD1P (bits 3-5) 为 SEC (编码010) priority_config | (0x2 3); // 010 // 配置SYSD2P (bits 6-8) 为 UART1 (编码000) priority_config | (0x0 6); // 000 // 注意bits 12-15, 28-31是保留位写入被忽略我们通常置0。 // 写入寄存器 *siprr_d priority_config;致命陷阱手册用加粗强调“The user should not program the same code to more than one priority position (0–7).” 这意味着绝对不要将同一个中断源编码分配给两个不同的SYSDxP位置。例如你不能同时设置SYSD0P000(UART1) 和SYSD1P000(也是UART1)。这样做会导致未定义的行为很可能造成中断响应混乱甚至系统挂起。在编写配置函数时必须加入有效性检查逻辑。3.3 系统内部中断控制寄存器SICNR这个寄存器决定了高优先级中断以何种“紧急程度”通知CPU。功能它只为SYSA0-1和SYSD0-1这四个特定的高优先级位置定义其输出给CPU的中断信号类型。其他所有优先级位置固定输出INT类型。中断类型INT普通外部中断。最常见的中断类型。CINT临界中断。具有比INT更高的硬件优先级用于处理非常紧急的事件。SMI系统管理中断。通常用于电源管理、热事件等系统级管理任务。配置考量 例如如果你将某个对实时性要求极高的任务如电机控制PWM的故障保护关联的中断源通过SIPRR_D配置到了SYSD0位置那么你可以通过SICNR的SYSD0T字段将其设置为CINT。这样当该中断发生时CPU会以处理临界中断的方式响应可能伴随更快的上下文切换和更低的延迟。配置示例将SYSD0位置的中断类型设置为临界中断CINT。volatile uint32_t *sicnr (uint32_t *)0xAddr_SICNR; uint32_t temp *sicnr; // 清除SYSD0T字段 (bits 0-1) temp ~(0x3 0); // 设置SYSD0T为10代表CINT temp | (0x2 0); // 10 *sicnr temp;注意手册提到“These bits cannot be changed dynamically. (to change it, software must make sure the corresponding interrupt source is masked or it cannot happen during the change)”。这意味着修改SICNR时必须确保对应的中断源例如当前在SYSD0位置的中断源被屏蔽SIMSR相应位为0或者绝对不可能在此期间发生中断。否则在改变中断类型的瞬间如果发生中断行为是未定义的。安全做法是先屏蔽相关中断修改SICNR然后再使能中断。3.4 系统外部中断控制寄存器SECNR这个寄存器主要管理来自芯片引脚的外部中断行为。功能定义中断类型为MIXA0-1和MIXB0-1这四个优先级位置定义输出中断类型INT/CINT/SMI功能同SICNR。配置触发方式通过EDIxExternal Detect Interrupt位域bits 16-23配置IRQ[0:4]每个引脚的中断触发方式是电平敏感还是边沿敏感。0低电平有效电平敏感。只要引脚为低就持续产生中断请求。1高到低跳变边沿敏感。仅在下降沿时产生一次中断请求。触发方式的选择至关重要电平触发适合需要持续通知CPU的中断直到外部条件解除。ISR中断服务程序必须清除导致低电平的外部条件否则退出ISR后由于电平依然有效会立即再次触发中断导致CPU陷入无限中断循环。边沿触发适合通知一次性事件。即使事件持续也只在变化沿触发一次。对硬件消抖有一定要求避免毛刺导致误触发。配置示例配置IRQ1为边沿触发IRQ2为低电平触发并将MIXA0位置的中断类型设置为SMI。volatile uint32_t *secnr (uint32_t *)0xAddr_SECNR; uint32_t config 0; // 1. 配置触发方式IRQ1 (bit17) 边沿触发 IRQ2 (bit18) 电平触发 config | (1 17); // EDI1 1 config ~(1 18); // EDI2 0 (或明确写0) // 2. 配置MIXA0T (bits 8-9) 为 SMI (编码01) config | (0x1 8); *secnr config;4. 混合中断组与动态优先级配置实战SMPRR_A和SMPRR_B是配置混合中断组MIXA, MIXB优先级的寄存器。这两个组的特点是混合了内部和外部中断源提供了极大的灵活性。4.1 SMPRR_A 寄存器解析与配置SMPRR_A管理MIXA组该组包含内部中断RTC SEC、PIT、PCI。外部中断IRQ0, IRQ1, IRQ2, IRQ3 (注意IRQ0需配置为外部可屏蔽中断即SEMSR[SIRQ0]0)。功能与SIPRR_D类似SMPRR_A定义了MIXA组内8个优先级位置MIXA0P-MIXA7P分别由哪个中断源占据。编码定义以MIXA0P为例bits 0-2000: RTC SEC001: PIT010: PCI011: 保留100: IRQ0101: IRQ1110: IRQ2111: IRQ3动态配置场景 假设我们的系统有一个周期性定时任务PIT和一个来自外部FPGA的高速数据接收中断IRQ1。在数据接收阶段我们希望IRQ1有最高优先级在空闲阶段则希望PIT有较高优先级以执行后台任务。volatile uint32_t *smpRR_a (uint32_t *)0xAddr_SMPRR_A; void set_high_priority_for_data_receive(void) { uint32_t temp *smpRR_a; // 设置MIXA0P为IRQ1 (101) temp ~(0x7 0); // 清零MIXA0P字段 temp | (0x5 0); // 设置为101 // 可以同时调整其他位置例如将PIT放到MIXA1P temp ~(0x7 3); // 清零MIXA1P字段 temp | (0x1 3); // 设置为001 (PIT) *smpRR_a temp; } void set_high_priority_for_timer(void) { uint32_t temp *smpRR_a; // 设置MIXA0P为PIT (001) temp ~(0x7 0); temp | (0x1 0); // 将IRQ1放到稍低优先级例如MIXA2P temp ~(0x7 6); temp | (0x5 6); *smpRR_a temp; }再次强调同一个中断源编码不能出现在两个不同的优先级位置上。在动态调整函数中必须确保逻辑严谨避免冲突。4.2 中断屏蔽寄存器SEMSR与强制寄存器SEFCR/SIFCRSEMSR功能与SIMSR对应但用于屏蔽外部中断IRQ[0:4]。特别注意其SIRQ0位bit 16它决定了IRQ0引脚的功能是作为普通外部中断0还是外部MCP请求1。这是一个重要的硬件功能选择。SEFCR和SIFCR中断强制寄存器。这是一个非常实用的调试和测试功能。通过向这些寄存器的特定位写1可以软件模拟一个外部或内部中断事件。这对于在不连接真实硬件的情况下测试中断服务程序ISR的逻辑是否正确以及中断优先级配置是否生效具有不可替代的价值。// 强制产生一个IRQ1中断模拟外部信号 volatile uint32_t *sefcr (uint32_t *)0xAddr_SEFCR; *sefcr | (1 1); // 设置IRQ1强制位 // 在ISR中需要像处理真实中断一样清除强制位通常通过写1清除但需查证有些设计是写0清除或自动清除 // 更重要的是清除中断状态寄存器SEPNR的对应位5. 中断服务程序ISR编写与问题排查实录理解了寄存器配置最终都要落实到中断服务程序上。一个健壮的ISR是系统稳定的基石。5.1 ISR编写模板与关键操作一个典型的ISR需要完成以下步骤现场保存由编译器或汇编入口代码完成。中断源识别读取系统中断向量寄存器SIVCR。这是最关键的一步。SIVCR中锁存了当前最高优先级待处理中断的7位向量号。根据这个向量号跳转到对应的处理函数。手册中的Table 8-6输入片段未包含是向量号与中断源的映射表必须熟记或定义成常量数组。清除中断标志对于外部边沿中断需要手动清除SEPNR中的对应位写1清除。对于外部电平中断必须先操作硬件使中断引脚恢复无效电平如拉高SEPNR位会自动清除。对于内部中断需要清除外设模块自身的中断状态寄存器例如UART的Status Register中的中断标志位。仅仅清除IPIC的SIPNR通常是不够的必须清除产生中断的外设的标志位否则退出ISR后会立即再次进入。中断重入与嵌套考虑PowerPC架构在进入中断后会自动屏蔽外部中断MSR[EE]0。如果允许中断嵌套需要在ISR中适时地重新使能MSR[EE]位。但必须谨慎处理避免栈溢出或数据竞争。现场恢复与返回使用rfi指令返回。// 伪代码示例基于向量号的中断分发 void __attribute__((interrupt)) isr_handler(void) { uint32_t vector; // 1. 读取中断向量 vector *(volatile uint32_t *)SIVCR_ADDR; // 提取高7位有效向量号 (根据手册可能是特定位域) vector (vector 24) 0x7F; // 2. 根据向量号跳转 switch(vector) { case VECTOR_UART1: uart1_isr(); break; case VECTOR_ETSEC1_RX: etsec1_rx_isr(); break; case VECTOR_PIT: pit_isr(); break; // ... 其他中断源 default: // 未识别的中断向量进入错误处理 undefined_interrupt_handler(); break; } // 3. 清除中断等操作在具体的xxx_isr()函数中完成 } // 具体的UART1 ISR示例 void uart1_isr(void) { // 1. 读取UART状态寄存器确定中断类型接收、发送、错误 uint32_t uart_status *(volatile uint32_t *)UART1_SR_ADDR; // 2. 处理接收中断 if (uart_status UART_SR_RX_INT_MASK) { // 读取数据寄存器存入缓冲区 uint8_t data *(volatile uint8_t *)UART1_RDR_ADDR; rx_buffer[rx_index] data; // 清除UART模块的接收中断标志位具体操作依赖外设 *(volatile uint32_t *)UART1_CR_ADDR | UART_CR_CLEAR_RX_INT; } // 3. 处理发送中断 if (uart_status UART_SR_TX_INT_MASK) { // 检查并发送下一个字节 if (tx_index tx_length) { *(volatile uint8_t *)UART1_TDR_ADDR tx_buffer[tx_index]; } else { // 发送完成禁用发送空中断 *(volatile uint32_t *)UART1_CR_ADDR ~UART_CR_TX_INT_EN; } // 清除UART模块的发送中断标志位 *(volatile uint32_t *)UART1_CR_ADDR | UART_CR_CLEAR_TX_INT; } // 注意通常不需要直接操作IPIC的SIPNR来清除内部中断标志 // 除非外设设计如此。重点是清除外设自身的中断源。 }5.2 常见问题排查与调试技巧在实际开发中中断相关的问题往往令人头疼。下面是一个基于经验的排查清单问题现象可能原因排查步骤与解决方案中断根本进不来1. 中断未使能。2. 屏蔽寄存器SIMSR/SEMSR配置错误。3. 中断向量表地址未正确设置或未启用。4. CPU全局中断未使能MSR[EE]。1. 检查外设模块的中断使能位。2. 读取SIMSR/SEMSR确认对应位为1。3. 确认IVPR中断向量基址寄存器和IVORx中断向量偏移寄存器已正确初始化。4. 在main函数或启动代码中确保执行mtmsr(mfmsr()中断只触发一次1. 电平中断ISR未清除导致电平有效的硬件条件。2. 边沿中断SEPNR位未清除。3. 外设中断标志位未清除。1. 对于电平中断检查硬件电路确保ISR能复位中断信号。2. 在ISR中对SEPNR对应位写1清除。3.重点检查在ISR中是否清除了外设自身的中断状态寄存器这是最常见的原因。中断响应速度慢1. 中断被低优先级中断长时间阻塞。2. 中断服务程序ISR本身执行时间过长。3. 使用了“Spread”模式且高优先级中断被分配在靠后的位置。1. 优化优先级配置提高关键中断的优先级使用HPI或调整组内顺序。2. ISR应尽可能短小只做最紧急的数据搬运或标志设置耗时任务放到主循环或任务中。3. 评估是否应使用“Grouped”模式将关键中断组集中到高优先级区域。错误的中断向量1. SIVCR读取时机不对在中断被应答前读取。2. 向量号与ISR映射表错误。1. 确保在ISR入口处、清除任何中断标志之前读取SIVCR。2. 仔细核对手册中的中断向量表Table 8-6确保代码中的常量定义与之完全一致。系统偶尔死锁或跑飞1. 中断嵌套导致栈溢出。2. 在修改优先级寄存器如SIPRR_D或控制寄存器如SICNR时未屏蔽相关中断导致竞态条件。3. 错误地清除了不应清除的寄存器位。1. 增大栈空间或谨慎使用中断嵌套。2.严格遵守手册在动态修改SIPRR_D、SICNR等寄存器前务必先屏蔽SIMSR相关中断源修改完成后再使能。3. 使用“读取-修改-写入”模式操作寄存器避免误写其他位。对保留位Reserved写入0。一个高级调试技巧利用强制中断寄存器。当你怀疑是硬件信号问题还是软件配置问题时可以尝试使用SEFCR或SIFCR强制产生一个中断。如果强制中断能正常进入ISR说明中断通道、向量表、CPU中断使能等软件配置基本正确问题可能出在外设配置或硬件信号上。反之则需重点检查软件配置。6. 实战为一个数据采集系统配置中断假设我们基于MPC8313E设计一个数据采集系统需求如下一个高速ADC通过FPGA连接到IRQ1边沿触发数据就绪后产生中断要求响应延迟最小。系统通过UART1与上位机通信接收控制命令重要性次之。一个看门狗定时器WDT用于系统监控其超时中断MCP必须最高优先级。使用PIT定时器产生1ms的系统心跳。配置策略最高优先级处理看门狗是MCP中断属于错误中断其优先级在硬件上已固定为最高无需在IPIC中配置。只需确保SERMR中对应位使能。关键外部中断将IRQ1分配到MIXA组并设置为该组最高优先级MIXA0P。因为MIXA组在Grouped模式下位于总优先级表的第2位仅次于HPI响应极快。在SECNR中配置IRQ1为边沿触发EDI11。通信中断将UART1分配到SYSD组。由于其实时性要求稍低可以将其优先级设置在SYSD组内中等位置例如SYSD3P。在SIMSR_L中使能UART1中断。定时器中断将PIT也分配到MIXA组但优先级低于IRQ1例如MIXA1P。这样ADC数据采集总能打断定时器任务。动态调整考虑在系统初始化阶段可以将UART1的优先级调高便于调试。进入正常运行后再动态调整SIPRR_D降低其优先级。部分配置代码示意void interrupt_system_init(void) { // 1. 初始化IVPR, IVOR等向量表相关寄存器此处省略 // 2. 配置触发方式IRQ1边沿触发 volatile uint32_t *secnr (uint32_t *)SECNR_ADDR; *secnr | (1 17); // EDI1 1 // 3. 配置MIXA组优先级MIXA0P IRQ1, MIXA1P PIT volatile uint32_t *smpRR_a (uint32_t *)SMPRR_A_ADDR; uint32_t mixa_prio 0; mixa_prio | (0x5 0); // MIXA0P 101 (IRQ1) mixa_prio | (0x1 3); // MIXA1P 001 (PIT) // 其他位置可按需配置或留默认值 *smpRR_a mixa_prio; // 4. 配置SYSD组优先级将UART1放在中等位置例如SYSD3P volatile uint32_t *siprr_d (uint32_t *)SIPRR_D_ADDR; // 假设默认优先级顺序是UART1在SYSD0我们需要调整。 // 先读取当前值然后重新编排。这是一个简化的例子实际需完整配置8个位置。 // 假设我们希望顺序是[SYSD0]SEC, [SYSD1]eTSEC1, [SYSD2]I2C1, [SYSD3]UART1... uint32_t sysd_prio 0; sysd_prio | (0x2 0); // SYSD0P SEC (010) sysd_prio | (0x3 3); // SYSD1P eTSEC1 1588 (011) sysd_prio | (0x5 6); // SYSD2P I2C1 (101) sysd_prio | (0x0 9); // SYSD3P UART1 (000) // ... 配置其他位置 *siprr_d sysd_prio; // 5. 使能中断屏蔽位 volatile uint32_t *simsr_l (uint32_t *)SIMSR_L_ADDR; *simsr_l | (1 UART1_BIT_POS); // 使能UART1中断 // 注意PIT、IRQ1等中断的使能位可能在SIMSR_H或SEMSR中需根据具体位定义设置 volatile uint32_t *semsr (uint32_t *)SEMSR_ADDR; *semsr | (1 1); // 使能IRQ1中断 (bit1对应IRQ1) // 6. 最后使能CPU全局中断 __asm__ volatile(mfmsr %0 : r(msr)); msr | MSR_EE_BIT; __asm__ volatile(mtmsr %0 : : r(msr)); }通过这样的配置我们构建了一个层次清晰、响应及时的中断系统。ADC数据中断能获得近乎最快的响应而UART和定时器则在保证功能的前提下合理分配了系统资源。记住中断配置没有一成不变的“最佳方案”只有最适合当前系统负载和业务需求的“权衡方案”。最好的方式是在系统集成测试阶段结合实际的中断触发频率和ISR执行时间利用性能分析工具进行微调。