4. GPIO与中断控制器实战

在 PolarFire SoC 的实时控制系统中,GPIO 是最基础也最常用的外设接口,而中断控制器则是系统实时响应能力的核心。本节围绕 GPIO 配置与读写、MPFS GPIO 中断机制、PLIC 中断优先级与使能、外部按键中断响应实验以及中断延迟测量五个方面展开,帮助读者建立从引脚操作到中断响应的完整工程能力。

一、GPIO 配置与读写

PolarFire SoC 的 GPIO 由 MSS GPIO 模块管理,每个引脚可独立配置为输入、输出或复用功能。配置流程通常包括:使能 GPIO 时钟、设置引脚方向、选择中断触发方式(若需要)、配置上拉或下拉电阻。以 MPFS 的 GPIO 为例,寄存器层面主要涉及 GPIO_CFG、GPIO_IRQ、GPIO_IN 和 GPIO_OUT 等寄存器。实际开发中更常用的是通过 HAL 或裸机驱动提供的 API 完成配置。

以下是一个典型的 GPIO 输出配置示例,假设使用 GPIO0 驱动 LED:

// 使能 GPIO0 为输出模式
GPIO_init(GPIO0, GPIO_OUTPUT);
// 输出高电平点亮 LED
GPIO_write(GPIO0, 1);
// 输出低电平熄灭 LED
GPIO_write(GPIO0, 0);

对于输入引脚,例如连接按键的 GPIO1,需要配置为输入并启用内部上拉,以避免悬空导致误触发:

GPIO_init(GPIO1, GPIO_INPUT);
GPIO_set_pullup(GPIO1, ENABLE);
uint32_t val = GPIO_read(GPIO1);

读写操作看似简单,但在实时控制中需要注意:GPIO 输出翻转的时序直接影响执行器响应,输入采样则要考虑消抖。软件消抖通常采用延时二次采样,硬件消抖则依赖 RC 滤波或施密特触发器。

二、MPFS GPIO 中断机制

MPFS GPIO 支持边沿触发和电平触发两种中断方式。每个 GPIO 可独立配置为上升沿、下降沿或双边沿触发。中断产生后,GPIO 模块会置位对应的中断状态寄存器,CPU 通过读取该寄存器判断是哪个引脚触发了中断。关键寄存器包括 GPIO_IRQ_ENABLE、GPIO_IRQ_TYPE 和 GPIO_IRQ_STATUS。

配置 GPIO 中断的典型步骤为:设置引脚为输入、配置触发类型、使能该引脚的中断、在 PLIC 中使能对应的 GPIO 中断源、最后使能全局中断。需要注意的是,GPIO 中断状态寄存器在中断服务程序中必须手动清除,否则会反复进入中断。

三、PLIC 中断优先级与使能

PLIC(Platform-Level Interrupt Controller)是 RISC-V 架构中负责管理外部中断的核心组件。PolarFire SoC 的 PLIC 支持多个中断源,每个中断源可配置优先级(0~7),优先级越高越先被响应。PLIC 还支持中断使能位和阈值寄存器,只有优先级高于阈值的中断才能被传递给 CPU。

PLIC 的关键操作包括:设置中断源优先级、使能中断源、设置优先级阈值、使能全局中断。以下代码展示了将 GPIO 中断源(假设中断号为 10)配置为优先级 3 并使能的过程:

PLIC_set_priority(10, 3);      // 设置优先级为3
PLIC_enable_interrupt(10);     // 使能该中断源
PLIC_set_threshold(0);         // 阈值设为0,允许所有优先级
__enable_irq();                // 使能全局中断

在实时控制中,合理分配优先级至关重要。例如,电机过流保护中断应设为最高优先级,按键中断可设为较低优先级,以确保关键安全事件优先响应。

GPIO 外部按键中断响应链路与延迟测量点 外部按键 GPIO1 输入 电平变化 MPFS GPIO 边沿检测 IRQ_STATUS 置位 中断请求 PLIC 优先级仲裁 使能判断 阈值比较 CPU 中断 RISC-V CPU 跳转 ISR 执行中断服务 中断延迟测量区间(t_trigger → t_isr_entry) T1: 按键动作 T2: ISR 首条指令 关键配置与测量方法 GPIO 配置 输入 + 上拉 + 下降沿触发 PLIC 配置 优先级 3,阈值 0,使能中断源 延迟测量 GPIO 翻转 + 示波器/逻辑分析仪 测量方法:在 ISR 入口翻转另一个 GPIO(如 GPIO2),用示波器同时捕获按键信号与 GPIO2 翻转信号, 两信号上升沿之间的时间差即为中断延迟。典型值在 1~5 μs 量级,取决于 PLIC 仲裁与流水线状态。 优化方向:提高中断优先级、减少 ISR 入口指令、关闭不必要的调试功能。

四、外部按键中断响应实验

实验目标:按下按键后,系统通过 GPIO 中断触发 ISR,在 ISR 中翻转 LED 状态,并测量从按键动作到 ISR 执行的时间。硬件连接:按键一端接 GPIO1,另一端接地;LED 接 GPIO0。软件流程如下:

  1. 初始化 GPIO0 为输出,GPIO1 为输入并启用上拉。
  2. 配置 GPIO1 为下降沿触发中断。
  3. 在 PLIC 中使能 GPIO 中断源,设置优先级为 3,阈值为 0。
  4. 编写 ISR:清除 GPIO 中断状态,翻转 GPIO0,记录时间戳。
  5. 使能全局中断,进入主循环等待。

实验现象:每次按下按键,LED 状态翻转一次。若 LED 不翻转,应检查中断是否使能、状态是否清除、PLIC 配置是否正确。若出现多次翻转,可能是按键抖动导致,需增加消抖逻辑。

五、中断延迟测量

中断延迟是指从中断事件发生到 ISR 第一条指令执行之间的时间。测量方法:在 ISR 入口翻转一个空闲 GPIO(如 GPIO2),用示波器同时捕获按键信号和 GPIO2 信号,测量两个边沿之间的时间差。典型延迟包括:GPIO 同步、PLIC 仲裁、CPU 流水线刷新、向量跳转等。在 PolarFire SoC 上,若 PLIC 优先级配置合理,延迟通常在 1~5 μs 量级。

降低延迟的措施包括:提高中断优先级、减少 ISR 入口的保存操作、避免在 ISR 中调用复杂函数、关闭不必要的调试模块。对于实时控制,建议将关键中断优先级设为最高,并确保 PLIC 阈值不阻塞该中断。

实践建议:在测量中断延迟时,建议使用逻辑分析仪而非普通示波器,因为逻辑分析仪能同时捕获多路信号并精确测量边沿间隔。若条件有限,也可用 CPU 周期计数器(如 mcycle)在 ISR 中读取时间戳,但需注意计数器频率和溢出问题。

注意:GPIO 中断状态寄存器必须在 ISR 中手动清除,否则中断会持续触发。清除方式通常是向状态寄存器写入对应位,具体操作请参考 MPFS 参考手册。此外,PLIC 的中断完成寄存器也需要在 ISR 结束时写入,以通知 PLIC 该中断已处理完毕。

通过本节的学习,读者应能独立完成 GPIO 配置、中断使能、PLIC 优先级设置以及中断延迟测量。这些技能是后续实时控制系统开发的基础,建议在开发板上反复练习,直至能够熟练排查中断不触发、重复触发、延迟过大等常见问题。