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 中断触发 ISR,在 ISR 中翻转 LED 状态,并测量从按键动作到 ISR 执行的时间。硬件连接:按键一端接 GPIO1,另一端接地;LED 接 GPIO0。软件流程如下:
- 初始化 GPIO0 为输出,GPIO1 为输入并启用上拉。
- 配置 GPIO1 为下降沿触发中断。
- 在 PLIC 中使能 GPIO 中断源,设置优先级为 3,阈值为 0。
- 编写 ISR:清除 GPIO 中断状态,翻转 GPIO0,记录时间戳。
- 使能全局中断,进入主循环等待。
实验现象:每次按下按键,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 优先级设置以及中断延迟测量。这些技能是后续实时控制系统开发的基础,建议在开发板上反复练习,直至能够熟练排查中断不触发、重复触发、延迟过大等常见问题。