You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测RISC-V(Microchip PolarFire MPFS)中函数是否从中断处理程序调用

RISC-V M模式下函数区分中断/主调用上下文的正确实现

针对你遇到的mcause.interrupt无法可靠判断当前是否处于中断上下文的问题,以下是两种在M模式下可用的可靠方案:

方案1:利用mstatus.MIE寄存器位判断

进入中断陷阱时,硬件会自动清除mstatus寄存器的MIE位(全局中断使能位),直到中断处理程序执行mret指令前才会恢复该位。主代码正常运行时(未主动关中断),MIE位是置位状态。

实现代码:

#include <stdint.h>

static inline uint32_t read_mstatus(void) {
    uint32_t val;
    __asm__ volatile ("csrr %0, mstatus" : "=r"(val));
    return val;
}

#define MSTATUS_MIE_MASK (1U << 3)

void your_function(void) {
    // 检查是否处于中断上下文:MIE位未置位则是中断调用
    if (!(read_mstatus() & MSTATUS_MIE_MASK)) {
        // 中断调用时执行的额外操作
        // ...
    }

    // 主代码与中断调用共享的核心逻辑
    // ...
}

方案2:维护全局上下文标记

在中断处理程序的入口和出口分别设置/清除一个全局标记变量,确保函数能通过该变量判断当前上下文。需注意变量的访问要保证原子性,或在关中断环境下操作。

实现代码:

#include <stdbool.h>

// volatile修饰确保编译器不会优化该变量的访问
volatile bool g_in_interrupt = false;

// 中断处理程序示例框架
void interrupt_handler(void) {
    g_in_interrupt = true;

    // 处理中断逻辑,调用目标函数
    your_function();

    g_in_interrupt = false;
    __asm__ volatile ("mret");
}

void your_function(void) {
    if (g_in_interrupt) {
        // 中断调用时的额外操作
        // ...
    }

    // 核心逻辑
    // ...
}

补充说明:mcause.interrupt位的作用仅在进入陷阱时判断触发源是中断还是异常,陷阱退出后该位的状态不会被硬件自动清除,主代码运行时可能保留之前陷阱的状态,因此确实无法用来判断当前是否处于中断上下文。

内容的提问来源于stack exchange,提问作者Vladimir Tichy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 13:02:07