RISC-V Local Interrupt 深度解析:从 CLINT 到 CLIC,再到 Zephyr 驱动实现

本文基于:

  • RISC-V Privileged Architecture Specification
  • RISC-V CLIC Specification
  • Zephyr RTOS interrupt controller driver
  • QEMU RISC-V virt DeviceTree

上一篇介绍了 RISC-V PLIC(Platform-Level Interrupt Controller ,分析了 UART、GPIO、SPI 等外设中断如何通过 PLIC 汇聚后进入 CPU。

但是 RISC-V 中还有另一类中断:

  • Timer Interrupt
  • Software Interrupt
  • Inter-Processor Interrupt

这些中断并不经过 PLIC,而属于 Hart Local Interrupt,由 CLINT 管理。

同时,为了满足实时系统更低延迟的需求,RISC-V 又提出了新的中断架构:

CLIC(Core Local Interrupt Controller

本文继续按照:

Spec → DeviceTree → Zephyr Code

分析 RISC-V Local Interrupt 的完整实现。


一、RISC-V 中断编号来源

在 DeviceTree 中,经常可以看到:

其中:3 7 11

这些数字来自哪里?


RISC-V 定义了标准 Interrupt Cause:

|-------------------------------|-----------|--------|
| Interrupt | Cause | 含义 |
| Machine Software Interrupt | 3 | 软件中断 |
| Machine Timer Interrupt | 7 | 定时器中断 |
| Supervisor External Interrupt | 9 | 外部中断 |
| Machine External Interrupt | 11 | 外部中断 |

因此:

复制代码
Cause=3  → MSI  (Machine Software Interrupt)

Cause=7  → MTI  (Machine Timer Interrupt)

Cause=11 → MEI  (Machine External Interrupt)

这些编号属于 CPU架构定义,不是 CLINT 或 PLIC 定义。


二、RISC-V 中断整体架构

一个完整的 RISC-V SoC:

复制代码
UART / GPIO / SPI
        |
        |
        v
       PLIC
        |
        |
        | Cause=11
        |
        v
     cpu-intc
        |
        |
        v
      Trap


mtime / MSIP
        |
        |
        v
      CLINT
        |
        |
        | Cause=3 / Cause=7
        |
        v
     cpu-intc
        |
        |
        v
      Trap

其中:

  • PLIC:平台外设中断
  • CLINT:CPU本地中断
  • cpu-intc:CPU最终中断入口

三、CPU Local Interrupt Controller(cpu-intc)

查看 QEMU RISC-V virt DTS:

CPU节点中的:

复制代码
compatible = "riscv,cpu-intc";

这里的 cpu-intc 不是一个外设 IP。

它表示:

RISC-V Hart 内部的中断控制接口。

对应 CPU 内部:

  • mie
  • mip
  • mcause
  • mtvec

等 CSR。

所有中断最终都进入 cpu-intc:

复制代码
CLINT
  |
  | Cause=7
  |
  v
cpu-intc
  |
  v
Trap

以及:

复制代码
PLIC
  |
  | Cause=11
  |
  v
cpu-intc
  |
  v
Trap

四、CLINT(Core Local Interruptor)

4.1 DeviceTree描述

QEMU DTS:

复制代码
clint: clint@2000000 {

    compatible = "sifive,clint0";

    reg = <0x2000000 0x10000>;

    interrupts-extended =
        <&hlic0 3
         &hlic0 7>;
};

CLINT包含三个关键属性:


compatible

复制代码
compatible = "sifive,clint0";

表示硬件类型。

Zephyr 根据 compatible 匹配对应驱动。


reg

复制代码
reg = <0x2000000 0x10000>;

表示:

复制代码
CLINT Base Address = 0x02000000
Size              = 64KB

Zephyr通过:

复制代码
sys_read32()

sys_write32()

访问这些寄存器。


interrupts-extended

重点:

复制代码
interrupts-extended =
        <&hlic0 3
         &hlic0 7>;

表示:

CLINT连接到CPU的两个中断入口:

复制代码
CLINT
 |
 +---- Cause=3  --> Machine Software Interrupt
 |
 +---- Cause=7  --> Machine Timer Interrupt

五、CLINT硬件结构


CLINT主要包含:

复制代码
+----------------+
| MSIP           |
+----------------+
| MTIME          |
+----------------+
| MTIMECMP       |
+----------------+

六、Software Interrupt(MSI)

MSIP用于软件触发中断。

典型场景:

  • SMP核间通信
  • CPU唤醒
  • Scheduler通知

流程:

复制代码
CPU0
 |
 | Write CPU1 MSIP
 |
 v
CLINT
 |
 | Cause=3
 |
 v
CPU1 cpu-intc
 |
 v
Trap Handler

含义:

CPU0通过写CLINT寄存器,让CPU1收到:

复制代码
Machine Software Interrupt

对应:

复制代码
Cause = 3

七、Timer Interrupt(MTI)

CLINT提供系统Timer。

核心寄存器:

复制代码
mtime

mtimecmp

工作流程:

复制代码
mtime Counter
      |
      |
      v
mtime >= mtimecmp
      |
      |
      v
CLINT
      |
      | Cause=7
      |
      v
cpu-intc
      |
      |
      v
Trap Handler

操作系统利用该机制实现:

  • Scheduler Tick
  • timeout
  • sleep
  • timer subsystem

八、CLINT与PLIC区别

|----------|----------------|---------------|
| | CLINT | PLIC |
| 作用 | CPU本地中断 | 外设中断 |
| 来源 | Timer/Software | UART/GPIO/SPI |
| Cause | 3月7日 | 11 |
| 是否Hart独立 | 是 | 共享 |
| 主要用途 | OS调度 | 设备驱动 |

整体:

复制代码
UART
 |
 v
PLIC
 |
 | Cause=11
 |
 v
cpu-intc
 |
 v
Trap

mtime
 |
 v
CLINT
 |
 | Cause=7
 |
 v
cpu-intc
 |
 v
Trap

九、为什么需要CLIC?

传统架构:

复制代码
Peripheral
 |
 v
PLIC
 |
 v
CPU
 |
 v
Trap
 |
 v
Software Dispatch
 |
 v
ISR

存在问题:

  • 中断入口固定
  • 软件分发耗时
  • 实时响应有限

因此提出:

CLIC

Core Local Interrupt Controller

目标:

  • 更低延迟
  • 支持向量中断
  • 支持嵌套抢占

十、CLIC架构

传统:

复制代码
Peripheral
 |
 v
PLIC
 |
 v
CPU Trap
 |
 v
ISR

CLIC:

复制代码
Peripheral
 |
 v
CLIC
 |
 v
Vector Table
 |
 v
ISR

区别:

|-----|----------|----------|
| | PLIC | CLIC |
| 分发 | 软件 | 硬件 |
| 向量 | 无 | 支持 |
| 优先级 | 简单 | 细粒度 |
| 实时性 | 普通 | 更高 |


十一、CLIC寄存器

https://github.com/pulp-platform/clic/blob/master/doc/clic.adoc

CLIC Specification Register Map

vb 复制代码
`M-mode CLIC memory map
  Offset
  ###   0x0008-0x003F              reserved    ###
  ###   0x00C0-0x07FF              reserved    ###
  ###   0x0800-0x0FFF              custom      ###

  0x0000         1B          RW        cliccfg
  0x0004         4B          R         clicinfo


  0x0040         4B          RW        clicinttrig[0]
  0x0044         4B          RW        clicinttrig[1]
  0x0048         4B          RW        clicinttrig[2]
  ...
  0x00B4         4B          RW        clicinttrig[29]
  0x00B8         4B          RW        clicinttrig[30]
  0x00BC         4B          RW        clicinttrig[31]


  0x1000+4*i     1B/input    R or RW   clicintip[i]
  0x1001+4*i     1B/input    RW        clicintie[i]
  0x1002+4*i     1B/input    RW        clicintattr[i]
  0x1003+4*i     1B/input    RW        clicintctl[i]
  ...
  0x4FFC         1B/input    R or RW   clicintip[4095]
  0x4FFD         1B/input    RW        clicintie[4095]
  0x4FFE         1B/input    RW        clicintattr[4095]
  0x4FFF         1B/input    RW        clicintctl[4095]`

主要寄存器:

|-------------|---------|
| 寄存器 | 作用 |
| cliccfg | 全局配置 |
| clicinfo | 能力信息 |
| clicintattr | 中断属性 |
| clicintctl | 优先级控制 |
| clicintie | Enable |
| clicintip | Pending |


CLIC可以实现:

复制代码
High Priority Interrupt
          |
          v
     Preempt
          |
          v
Low Priority Interrupt

这对于实时控制系统非常重要。


十二、ECLIC(Nuclei扩展)

https://doc.nucleisys.com/nuclei_spec/isa/eclic.html

Nuclei提出:

复制代码
ECLIC
=
Enhanced CLIC

它基于CLIC思想增强:

  • 更灵活优先级
  • 更快响应
  • MCU优化

架构:

复制代码
Peripheral
 |
 v
ECLIC
 |
 v
Vector Table
 |
 v
CPU ISR

注意:

  • CLIC:RISC-V标准扩展
  • ECLIC:Nuclei实现

十三、Zephyr驱动对应关系

PLIC

源码:

复制代码
drivers/interrupt_controller/intc_plic.c

CLINT

源码主要位于:

复制代码
arch/riscv/
drivers/timer/

负责:

  • Machine Timer
  • System Tick

CLIC

源码:

复制代码
drivers/interrupt_controller/intc_clic.c

负责:

  • enable
  • priority
  • vector mode

总结

RISC-V中断体系:

复制代码
UART/GPIO/SPI
        |
        v
      PLIC
        |
        | Cause=11
        |
        v
    cpu-intc


mtime/MSIP
        |
        v
      CLINT
        |
        | Cause=3/7
        |
        v
    cpu-intc


cpu-intc
        |
        v
      mtvec
        |
        v
    Zephyr ISR

理解这套关系后:

DTS中的:

复制代码
interrupts-extended =
<&hlic0 3>
<&hlic0 7>
<&hlic0 11>

就可以对应到:

  • 3:Software Interrupt
  • 7:Timer Interrupt
  • 11:External Interrupt

这也是从 RISC-V Spec 到 Zephyr 驱动实现之间最关键的一条链路。

相关推荐
weixin_727535621 天前
计算机组成原理:从晶体管到你面前这块屏幕的史诗之旅
risc-v
hongmai6668884 天前
ESP32-C61-WROOM-1-N8R2:Wi-Fi 6与RISC-V融合的中坚力量
人工智能·单片机·嵌入式硬件·物联网·智能家居·risc-v
国科安芯5 天前
在轨能源中枢:AS32S601型抗辐射MCU在卫星电源管理与配电系统中的控制策略研究
嵌入式硬件·架构·能源·risc-v·sps·电源管理·卫星
nh752714 天前
(一)HPM自定义工程创建实操
单片机·risc-v·hpm·先楫
蓝速科技16 天前
蓝速科技 RISC-V+ 鸿蒙终端:一机多场景信创改造实效评测
科技·harmonyos·risc-v
MounRiver_Studio18 天前
RISC-V IDE MRS2调试秘籍(三):通过栈帧可视化模块定位栈溢出、栈内存非法篡改等运行时错误
mcu·risc-v·代码调试
MounRiver_Studio18 天前
RISC-V IDE MRS2调试秘籍(一):通过Memory内存导出对比,锁定隐性内存异常代码
mcu·调试技巧·risc-v·代码调试
蓝速科技22 天前
蓝速科技 RISC-V 鸿蒙信创终端全场景落地方案
科技·harmonyos·risc-v
国科安芯22 天前
ASC4T245S分组双向控制架构深度解析:独立DIR/OE控制、QFN16封装与混合方向总线桥接
单片机·嵌入式硬件·物联网·fpga开发·架构·risc-v