在移植实时操作系统到一款新的板子上时,上下文切换与中断处理是需要用汇编来编写的,尽管可能平时很少写汇编,但是真的写起来其实也没太大难度!可是如果哪个细节没有搞清楚,那么可能会出现特别奇怪的执行过程。这时候最好不要直接调试,最好停下来梳理下整个处理流程,从头到尾审视下自己的处理过程,看看有没有明显的问题。
如果没有发现明显的问题,那么就调试一下吧!可是调试上下文切换与中断处理比调试 c 函数要麻烦点,上下文切换还好,它只在特定的时候发生,而中断却可能在任何时候到来。
下面是我的一些调试建议。
1. 将中断处理与上下文切换分开调试
当执行出现异常时既可能是中断处理过程有问题,也可能是上下文切换过程有问题,如果不将这两个分开调试,那么我们将面对一个很复杂的调试对象。
基于这点,我们有必要将中断处理与上下文切换分开调试。
在调试上下文切换的时候可以关闭中断,这可以通过修改任务初始化时预存到栈中的 cpu 状态处理器来实现。对于 【risc-v】 架构来说,要做到这点,只需要在预存现场数据时将 mstatus 的 MPIE 位设置为 0 就行了,其它的处理器可能有所不同,需要根据架构手册来修改。
关闭了中断之后可能 systick 也就停止了,这样我们如果使用任务延时阻塞的行为来触发上下文切换,那么只能触发一次。如果想触发多次,我们可以通过合理的安排多个任务的优先级或使用永久阻塞的信号量来完成!
2. 观察关键的过程
在上下文切换中,关键的地方在于现场的保存于恢复。现场的保存与恢复中也有些关键的寄存器。对于 risc-v 架构的芯片而言,这些处理器有 mepc、ra、sp 等。在调试时要先查看这些寄存器的值是否正确,这些寄存器的值不正确一般都会立刻造成问题。
总结
上下文切换与中断的处理过程是移植实时操作系统到一款芯片的重点,完成了这两部分功能系统才能够正常的跑起来。这两部分功能与体系结构直接相关,需要通过编写汇编来完成。写之前一定要把中间的所有过程想清楚,也只有这样才能写出来一个正确的处理逻辑。出现了问题时首先应该梳理整个的执行逻辑,没发现明显的问题那么可以调试看看。调试时将中断处理与上下文切换过程分开调试,缩小问题的范围,便于很快定位到问题!