Nuclei RISC-V 中断体系学习笔记

📅 2026/7/22 19:10:06 👁️ 阅读次数 📝 编程学习
Nuclei RISC-V 中断体系学习笔记

一、中断基础与架构模式

1.1 核心术语

  • 中断请求:外设 / 内核向 CPU 发起的异步处理请求

  • 中断源:产生中断的硬件模块,分为外部中断(UART、GPIO 等外设)与内部中断(软件中断、定时器中断、核内自研中断)

  • 中断服务程序(ISR):处理中断请求的专用代码段

  • 上下文保存与恢复:中断进入 / 退出时,通过软件压栈 / 出栈保存内核寄存器与运行状态,保证主程序无缝继续执行

  • 中断仲裁:多个中断同时触发时,按规则选出优先响应的中断

  • 抢占与嵌套:高优先级中断可打断低优先级中断的执行,形成多层嵌套

1.2 中断类型分类

大类子类说明
外部中断-由核外外设发起,对接 UART、GPIO 等片上外设
内部中断软件中断通过 msip/ssip 寄存器软件触发,对应特权级分别为机器模式 / 监管模式
定时器中断内核内置 TIMER 单元通过 mtime/mtimecmp 产生计时中断
Nuclei 自研内部中断部分型号核额外实现的专属内部中断

1.3 两种中断架构对比

通过mtvec寄存器最低位可切换中断工作模式,二者特性差异如下:

维度CLINT 模式(传统模式)CLIC 模式(增强模式)
核心架构CLINT 管内部中断 + PLIC 管外部中断,分体式管理ECLIC 统一管理全部内部 + 外部中断,统一式管理
控制方式依赖 mie/mip 等标准 CSR,外部中断由 PLIC 寄存器二次配置mie/mip 被硬件旁路(无效),完全由 ECLIC 内存映射寄存器控制
优先级能力仅外部中断支持优先级配置,内部中断无等级全中断源支持层级 + 优先级二维配置
核心特性无硬件向量中断、不支持嵌套、无尾链优化支持向量 / 非向量双模式、多级抢占嵌套、中断尾链优化
中断延迟延迟固定,相对较高延迟更低,向量模式可做到 6 周期响应

1.4 两级中断屏蔽机制

  1. 全局中断屏蔽

    1. 作用对象:机器模式下所有中断,作为总开关

    2. 实现方式:通过mstatus.MIE位统一开关所有机器模式中断

  2. 单源中断屏蔽

    1. CLINT 模式:内核 CSR 级(mie 寄存器单比特控制)+ PLIC 外设级(单路中断独立使能)两级屏蔽

    2. CLIC 模式:所有中断源通过 ECLIC 的clicintie[i]寄存器独立使能 / 屏蔽


二、CLIC 模式中断处理核心机制

2.1 中断仲裁规则

  1. 仲裁参与条件

中断源需同时满足 使能位 IE=1 且 挂起位 IP=1,才可参与仲裁。

  1. 仲裁优先级(从高到低)
    1. 中断层级(Level)数值越大,优先级越高(抢占唯一判断依据)

    2. 层级(Level)相同时,中断优先级(Priority)数值越大,优先级越高(同级仲裁第二依据)

    3. 层级(Level)与优先级(Priority)均相同时,中断 ID 号越大,优先级越高

  1. 最终输出规则

仲裁胜出的中断,仅当其层级Level 大于 mth阈值寄存器值 时,ECLIC 才会向 CPU 内核发送中断请求。

2.2 中断进入流程(硬件单周期自动完成)

中断响应所有硬件操作在单个时钟周期同步完成,核心动作如下:

  1. PC 跳转

    1. 向量模式(clicintattr[i].shv=1):PC = mtvt + 4 * 中断ID,直接跳转专属 ISR 入口

    2. 非向量模式(clicintattr[i].shv=0):PC = mtvec / mtvt2,跳转统一公共入口

  2. CSR 寄存器自动更新

    1. mepc:保存被中断指令的 PC 地址,用于中断返回

    2. mstatus:将 MIE 原值保存到 MPIE,随后 MIE 清 0(关闭全局中断,默认禁止嵌套);将原特权模式保存到 MPP,切换为机器模式

    3. mcauseEXCCODE写入当前中断 ID;MPIL保存中断前的系统中断层级;记录中断前特权模式与全局中断使能状态

    4. mintstatusMIL字段更新为当前中断的层级,用于后续抢占判断

  3. 模式切换

    1. 特权模式自动切换为机器模式

    2. 机器子模式:将原子模式保存到msubm.PTYPmsubm.TYP更新为中断处理模式

核心结论:进入 ISR 前,硬件已自动完成返回地址保存、中断原因记录、全局中断关闭,上下文保存需软件实现。

2.3 中断退出流程(mret 指令触发)

软件执行mret指令触发中断返回,硬件单周期完成逆过程恢复:

  1. mepc恢复 PC 值,回到被中断的指令处继续执行

  2. CSR 状态恢复

    1. mcause.MPIL恢复mintstatus.MIL,还原中断层级

    2. mcause.MPIE恢复mstatus.MIE,还原全局中断使能状态

    3. mcause.MPP恢复特权模式

  3. msubm.PTYP恢复机器子模式

2.4 向量 vs 非向量模式(每个中断源可独立配置clicintattr[i].shv

两种中断处理模式对比

特性向量模式(shv=1)非向量模式(shv=0)
跳转方式硬件直接查 mtvt 表,跳专属入口统一跳公共入口(mtvec/mtvt2),软件分发
响应延迟约 6 个周期(无上下文保存)约 4+3+8+5 ≈ 20 周期(含保存)
抢占默认关闭(MIE=0),需软件手动开原生支持(通过 csrrw ra, CSR_JALMNXTI, ra 指令)
尾链不支持支持(仅非向量)
C 函数要求必须加 __attribute__((interrupt)),且建议为叶子函数无特殊要求
维度非向量模式(shv=0,默认)向量模式(shv=1)
跳转逻辑统一跳转公共入口,软件识别中断号分发硬件直接查向量表,跳转专属 ISR 入口
响应延迟较高,包含公共入口跳转、上下文保存、软件分发开销极低,理想情况 6 周期到达 C 函数首指令
抢占支持原生支持抢占默认关闭(硬件自动关 MIE),需软件手动开中断开启
尾链支持支持,优化收益显著不支持
适用场景绝大多数通用外设中断,兼容性好对延迟要求极高的关键中断
非向量模式细节
  1. 公共入口配置

    1. mtvt2.MTVT2EN=0:公共入口复用 mtvec 地址,异常与非向量中断共用入口

    2. mtvt2.MTVT2EN=1:公共入口由 mtvt2 寄存器指定,中断与异常入口分离,性能更优

  2. 标准处理流程

    1. 压栈保存 mepc、mcause、msubm 等 CSR 与通用寄存器上下文

    2. 执行csrrw ra, CSR_JALMNXTI, ra指令:获取下一个待处理中断并跳转,同时自动开全局中断支持抢占,且具备跳转链接特性支撑尾链

    3. ISR 执行完成后,关中断、恢复上下文、执行 mret 返回

  3. 尾链实现原理 中断返回时回到 JALMNXTI 指令处,自动检测挂起中断;若存在同级 / 低优先级挂起中断,直接跳转对应 ISR,省去 “上下文恢复→返回主程序→重新保存上下文” 的往返开销。

向量模式细节
  1. 核心特性:硬件自动查表跳转,跳转前不保存上下文,延迟极低

  2. 函数约束:C 语言 ISR 需添加attribute((interrupt))属性;若为叶子函数无额外开销,若调用子函数,编译器会自动插入上下文保存代码,延迟与非向量模式相当

  3. 抢占开启方式:需在 ISR 开头手动保存关键 CSR,然后置位 mstatus.MIE 开中断;退出前先关中断再恢复上下文

  4. 向量表:一段连续内存空间,每个表项存储对应中断 ISR 的入口地址,基地址由mtvt寄存器定义

2.5 中断抢占与嵌套

  • 抢占判断依据:仅当新中断的层级 高于当前 mintstatus.MIL 时,才可抢占正在执行的低层级中断

  • 多级嵌套规则:支持多层级嵌套,中断退出时按优先级从高到低依次返回

  • 层级与优先级的区别:Level 决定抢占权,Priority 仅决定同级内的响应顺序,不参与抢占判断

2.6 中断尾链

  • 触发场景:当前中断处理期间,有同级 / 低优先级中断挂起,无法抢占,需等待当前中断处理完成

  • 优化效果:省去上下文恢复 + 重新保存的往返开销,连续处理多个挂起中断

  • 支持范围:仅非向量模式支持,向量模式无尾链特性


三、ECLIC 单元与寄存器详解

3.1 ECLIC 概述

  • 单核专属中断控制器,仅服务单个处理器核

  • 通过mtvec寄存器最低位切换为 ECLIC 模式,与 PLIC 功能互斥,不可同时启用

  • 内部逻辑:每路中断源独立经过触发检测、挂起标记、层级优先级配置、使能控制,最终通过全局仲裁选出最高优先级中断提交给 CPU

3.2 中断源 ID 分配

ECLIC 最多支持 4096 个中断源,ID 分配规则固定:

  • 0~18 号:内核预留内部中断

    • 3 号:机器模式软件中断

    • 7 号:机器模式定时器中断

    • 其余为保留位,部分型号扩展额外内部中断

  • 19~4095 号:用户可用外部中断,对接片内外设

  • 硬件实际支持的中断源总数可通过clicinfo.NUM_INTERRUPT读取

3.3 ECLIC 内存映射寄存器

ECLIC 为内存映射外设,基址由具体芯片手册定义,寄存器仅支持字节 / 半字 / 字对齐访问。

全局配置类寄存器
寄存器名地址偏移位宽权限核心功能与关键位域
cliccfg0x00008bit读写全局配置:nlbits[4:1] 划分 clicintctl 的位域,高 nlbits 位为层级,剩余有效位为优先级
clicinfo0x000432bit只读硬件参数查询:NUM_INTERRUPT[12:0] 中断源总数;CLICINTCTLBITS[24:21] clicintctl 有效位宽;VERSION[20:13] 硬件版本
mth0x000b8bit读写中断阈值等级:仅层级高于该值的中断可向 CPU 发起请求,用于批量屏蔽低等级中断
单中断源控制寄存器

每个中断号i对应一组寄存器,地址计算公式:0x1000 + 4*i + 组内偏移

寄存器名组内偏移位宽权限核心功能与关键说明
clicintip[i]08bit读写中断挂起标志:IP[0] 标记中断待处理状态- 电平触发:IP 随输入电平实时变化,软件写无效- 边沿触发:检测到对应边沿硬件置位,中断响应后硬件自动清除,软件可手动修改
clicintie[i]18bit读写中断使能开关:IE[0]=1 使能中断参与仲裁,IE[0]=0 完全屏蔽该中断
clicintattr[i]28bit读写中断属性配置- trig[2:1]:触发方式(00 电平触发、01 上升沿、11 下降沿)- shv[0]:处理模式(0 非向量、1 向量)
clicintctl[i]38bit读写层级与优先级控制:有效位由 CLICINTCTLBITS 决定,高位为层级(抢占依据),低位为同级优先级,数值越高优先级越高

3.4 内核中断相关 CSR 寄存器

通过 CSR 专用指令访问,分为 RISC-V 标准寄存器与 Nuclei 自定义扩展寄存器。

RISC-V 标准中断 CSR
寄存器名CSR 地址核心功能中断关键位域
mstatus0x300全局状态寄存器MIE:全局中断总使能;MPIE:保存中断前的全局中断使能状态;MPP:保存中断前的特权模式
mtvec0x305异常 / 中断入口配置ADDR[31:6]:入口基地址;MODE[5:0]:值为 0x3 时启用 ECLIC 模式,其余为 CLINT 模式
mepc0x341异常程序计数器保存中断触发前的 PC 值,mret 指令执行时恢复
mcause0x342陷阱原因寄存器INTERRUPT[31]:1 为中断,0 为异常;EXCCODE[11:0]:中断 / 异常编号;MPIL[23:16]:中断前的系统层级;MPIE[27]、MPP[29:28]:与 mstatus 对应字段镜像
mie / mip0x304 / 0x344中断使能 / 挂起ECLIC 模式下完全无效,读写被硬件忽略,仅 CLINT 模式生效
Nuclei 自定义中断扩展 CSR
寄存器名CSR 地址核心功能关键说明
mtvt0x307向量中断表基址存放向量模式中断向量表的起始地址,对齐要求随中断数提升
mtvt20x7ec非向量公共入口配置MTVT2EN[0]:1 时非向量中断入口由本寄存器指定,0 时复用 mtvec 地址
mnxti0x345下一中断处理寄存器读取即可获取下一个待处理中断的服务函数入口,同时自动更新中断状态,支撑尾链与快速嵌套
jalmnxti0x7ed跳转下一中断寄存器mnxti 增强版,读取时自动完成开中断 + 跳转,进一步降低延迟,具备链接特性支撑尾链
mintstatus0x346当前中断状态MIL[31:24]:当前机器模式活跃中断等级,用于抢占判断
mscratchcsw0x348特权模式栈切换不同特权级切换时,快速交换 mscratch 与 SP,实现栈空间隔离
mscratchcswl0x349中断等级栈切换中断进出时快速切换任务栈与中断栈,是中断入口汇编栈切换的硬件支撑

四、Zephyr RTOS 中断工程实现

4.1 系统三套陷阱路径

所有陷阱事件按类型走三条独立路径,互不干扰:

  1. 异常(Exception)

    1. 入口:永远走 mtvec 寄存器

    2. 目标:_isr_wrapper统一处理

    3. 说明:非法指令、访存错误、系统调用等所有异常均走此路径,与 shv 配置无关

  2. 向量中断(shv=1)

    1. 入口:mtvt 指向的硬件向量表

    2. 目标:直接跳转对应中断的专属处理函数

    3. 说明:不经过_isr_wrapper,响应速度最快,需显式配置启用

  3. 非向量中断(shv=0,默认)

    1. 入口:MTVT2EN=0 时走 mtvec 寄存器

    2. 目标:先跳转_isr_wrapper,再软件分发到对应处理函数

    3. 说明:系统默认路径,绝大多数外设中断走此路径

4.2 中断注册与模式选择

Zephyr 通过两个注册宏决定中断工作模式:

1.IRQ_CONNECT(默认,非向量模式)
  • 展开后调用ARCH_IRQ_CONNECT,保持shv=0默认值

  • 仅完成两件事:在软件中断表注册处理函数与参数、配置中断优先级

  • 不修改 shv 位,中断触发后走_isr_wrapper统一入口,经软件查表分发

2.IRQ_DIRECT_CONNECT(向量模式)
  • 展开后调用ARCH_IRQ_DIRECT_CONNECT,额外执行z_riscv_irq_vector_set()

  • 该函数会将对应中断的clicintattr[i].shv位置 1,开启向量模式

  • 中断触发后硬件直接从 mtvt 向量表取地址跳转,跳过软件分发流程


核心要点速记

  1. ECLIC 模式下,层级 Level 决定抢占,优先级 Priority 决定同级顺序,二者不可混淆

  2. 硬件仅自动保存 mepc、mcause 等少量 CSR,通用寄存器上下文必须软件保存

  3. 向量模式默认关中断不支持抢占,非向量模式原生支持抢占与尾链

  4. Zephyr 默认使用非向量模式,经_isr_wrapper软件分发;关键中断可使用IRQ_DIRECT_CONNECT开启向量模式降低延迟

  5. mtvec控制模式切换与异常 / 非向量入口,mtvt控制向量表基址,mtvt2控制非向量入口是否与异常分离