1. 中断控制器概述:中断的基本概念、中断控制器在RISC-V系统中的作用、常见中断控制器类型(PLIC、CLINT、AIA)
1.1 中断到底是什么?
说实话,很多刚入行的朋友会把中断和轮询搞混。我当年也犯过这个错。
中断,说白了就是让CPU停下当前工作,去处理一个更紧急的事情。你想想看,你正在写代码,突然电话响了——你会不会先接电话?这就是中断。电话铃声就是中断信号,接电话就是中断服务程序。
在数字芯片里,中断有几个关键要素:
- 中断源:谁发出的中断?可能是UART收到数据了,也可能是定时器溢出了。
- 中断请求:中断源向CPU喊一声“我有事!”
- 中断响应:CPU说“好,我来了”,然后保存现场、跳转处理。
- 中断返回:处理完了,回到原来的工作继续干。
核心要点:中断机制让CPU从“主动查询”变成了“被动响应”。效率高了一个数量级。
1.2 RISC-V里的中断控制器——它到底管什么?
RISC-V架构里,中断控制器不是CPU核的一部分。它是一个独立的外设模块。我刚开始接触RISC-V时,总觉得这设计有点绕——为什么不能像ARM那样把中断控制器集成到核里?
后来做项目才明白,这种分离设计给了芯片架构师极大的灵活性。你可以选PLIC,也可以选CLINT,甚至自己搓一个。
中断控制器在RISC-V系统里干三件事:
- 收集中断:把几十上百个外设的中断请求收上来。
- 仲裁优先级:多个中断同时来了怎么办?谁急谁先上。
- 路由到目标核:多核系统里,这个中断该发给哪个核?
我的经验:在单核系统里,中断路由看起来不重要。但一旦上了多核,路由策略直接决定了系统的实时性。我曾经在一个4核的AI芯片项目里,因为中断路由没配好,导致核0忙死、核1闲死——后来改成了按优先级动态路由,才解决问题。
1.3 三种常见中断控制器——PLIC、CLINT、AIA
RISC-V生态里,主流的中断控制器就这三种。我一个个说。
1.3.1 CLINT——最基础的定时器+软件中断
CLINT全称是Core Local Interruptor。它只处理两种中断:
- 定时器中断:mtime比较器触发
- 软件中断:一个核给另一个核发中断
CLINT不处理外设中断。外设中断得靠PLIC或者AIA。CLINT的设计非常简单,寄存器就那么几个。我建议初学者先从CLINT入手,理解RISC-V的中断机制。
注意:CLINT的定时器是内存映射的,不是CSR寄存器。很多新手在这里踩坑——想用csrr指令读mtime,结果读出来全是0。
1.3.2 PLIC——外设中断的“大管家”
PLIC(Platform Level Interrupt Controller)是RISC-V里最常用的外设中断控制器。它支持:
- 最多1023个中断源
- 7级优先级(0~6,0最低)
- 多核中断分发
PLIC的工作流程是这样的:
- 外设拉高中断请求线
- PLIC检测到请求,查优先级表
- PLIC向目标核发送中断信号
- 目标核读取claim寄存器,拿到中断号
- 处理完后写complete寄存器,通知PLIC释放
我在一个IoT芯片项目里用过PLIC。当时有个坑——PLIC的claim和complete操作必须成对出现。有个同事忘了写complete,结果那个中断再也没触发过。查了两天才找到原因。
关键点:PLIC的优先级是静态配置的。一旦配好,运行期间不能改。如果你需要动态优先级,得考虑AIA。
1.3.3 AIA——新一代的“智能”中断控制器
AIA(Advanced Interrupt Architecture)是RISC-V国际基金会推的新标准。它解决了PLIC的几个痛点:
| 特性 | PLIC | AIA |
|---|---|---|
| 优先级 | 静态配置 | 动态可调 |
| 中断嵌套 | 不支持 | 原生支持 |
| 虚拟化支持 | 弱 | 强 |
| 寄存器接口 | 内存映射 | CSR+内存映射 |
AIA引入了几个新概念:
- IMSIC:每个核有自己的中断文件,减少总线竞争
- APLIC:高级平台中断控制器,替代PLIC
- 中断消息传递:通过MSI(消息信号中断)传递,不再依赖专用中断线
说实话,AIA的设计确实更现代。但它的硬件复杂度也上去了。我建议:
- 做低功耗IoT芯片,用CLINT+PLIC就够了
- 做高性能计算或虚拟化场景,上AIA
我的建议:如果你在选型阶段,先看看你的外设数量。少于16个外设,PLIC完全够用。超过64个,考虑AIA。中间范围,看预算和团队经验。
1.4 三种控制器的关系——一张图说清楚
下面这张SVG图展示了RISC-V系统中三种中断控制器的层级关系:
从这张图可以看出来:
- CLINT和PLIC是并行的,各自管各自的中断类型
- AIA是更上层的架构,可以替代PLIC,同时兼容CLINT的功能
- 所有中断最终都汇聚到CPU核的mie/mip寄存器
1.5 选型建议——别盲目追新
我见过不少团队,一上来就说“我们要用AIA,因为新”。结果开发周期拉长了一倍,最后发现根本用不上虚拟化特性。
我的建议很简单:
- 学生/爱好者:从CLINT+PLIC开始,寄存器少,好理解
- 工业级MCU:PLIC足够,稳定可靠
- 高性能SoC:AIA,特别是需要虚拟化或多核负载均衡的场景
避坑提醒:我曾经在一个项目里选了AIA,结果发现RISC-V的工具链对AIA的支持还不完善。编译器生成的中断向量表不对,手工调了一周。所以选型时,不光看硬件,还要看软件生态。
好了,这一章就到这里。中断控制器的概念和分类讲清楚了。下一章我们会深入PLIC的寄存器级编程,到时候我会带着大家一步步写驱动代码。