我们队用安路FPGA搭了RISC-V软核,移植了RT-Thread操作系统,比赛还有一周就要提交作品了。现在遇到一个诡异的问题:软件中断和硬件定时器中断同时触发时,系统任务就卡死,串口无输出,看门狗也不复位。怀疑是中断优先级配置或者上下文切换出了问题,但用ILA抓不到CPU内部寄存器状态。请问有什么系统性的排查思路?是优先检查中断向量表还是先看调度器锁?有没有可能和FPGA的时序收敛有关?求有经验的学长指点,急!
2026年FPGA大赛只剩一周,用安路FPGA做RISC-V软核跑RT-Thread,软件中断和硬件定时器冲突导致任务卡死,怎么排查?
3 个回答

先别急着改中断向量表,把PLIC里软件中断和定时器中断的优先级打印出来看一眼。RT-Thread默认抢占式调度下,如果软件中断优先级比定时器高,任务切换时定时器中断一直被压着,卡死很常见。另外在rt_hw_context_switch函数里加个GPIO翻转,逻辑分析仪看电平变化就能定位是卡在切换前还是切换后。时序问题先放一边,优先级和锁排查完再说。

个人感觉你这个问题大概率出在CLINT的软件中断触发方式上。安路软核移植RT-Thread时,很多人直接照搬QEMU的驱动,但QEMU里软件中断是写msip寄存器触发,而安路的IP核可能要求先清pending再置位,或者反之。你可以在触发软件中断的函数前后加串口打印,看看到底是触发后没进中断,还是进了中断但没正确清标志导致反复进入。另外,RT-Thread的调度器锁在中断里是默认关闭的,如果硬件定时器中断里调用了rt_interrupt_enter/leave,但软件中断路径里漏了,系统状态就乱了。建议先用一个最简单的测试:只开定时器中断跑两个线程,再只开软件中断跑两个线程,都正常的话再叠加,这样能快速缩小范围。时序收敛的问题一般不会导致这种逻辑性卡死,除非你跑在200MHz以上且时序报告有红色路径,可以临时降频到50MHz验证一下,如果降频后问题消失,那再回头查时序。

说个我们当年做类似项目的经验吧。你们现在用ILA抓不到CPU内部状态,其实可以换一个思路:在RT-Thread里加一个软件看门狗任务,专门负责翻转某个GPIO,主循环里如果超过100ms没翻转就说明系统已经死了。然后用逻辑分析仪同时抓这个GPIO和中断触发引脚,就能看出是死在哪一步——是中断没进、进了没返回、还是任务切换时死锁。这个比ILA好用多了,因为逻辑分析仪采样深度大,能看长时间的行为模式。回到你的问题本身,我建议优先检查中断向量表,因为安路FPGA的软核一般用Vivado或自家IDE生成的BSP,向量表偏移可能没对齐,特别是如果你用了自定义链接脚本。你可以试试在startup.S里打印mtvec的值,确认它指向正确地址。另外,你说的看门狗不复位,这很关键——如果看门狗是挂在硬件定时器中断里的,那说明中断确实没死,只是任务调度死了,那就更偏向于调度器锁或上下文切换的bug。最后提一句,比赛只剩一周,如果实在查不出来,可以临时把软件中断改成轮询方式,或者把两个中断合并成同一个优先级,牺牲一点实时性换稳定,先保证作品能跑起来。你们现在用的是什么版本的RT-Thread?如果是4.0以下的老版本,建议直接换到4.1,那个版本的上下文切换对RISC-V的支持更完整。
发表回答
登录后可在本页底部提交回答