按要求,中断服务函数里,如果使用了内核“事件、信号量、消息、队列、邮箱”操作等,则需要在内核操作前后调用“rt_interrupt_enter、rt_interrupt_leave”通知内核。
看了内核函数“rt_event_send、rt_mb_send、rt_mq_send_wait”等的实现,以及内核调度函数rt_schedule的实现之后,明白,如果不进行上述的中断通知,的确会导致系统调度受到不良影响。但这种影响会严重吗?会严重到什么程度?
rt_interrupt_nest
的作用是中断嵌套层级数,也就是每一次进入中断函数进行数据处理之时,需要将该值加 1,推出中断时将该值减 1。也就是说在 rt_schedule
中,通过该值时 0 还是非 0 来确定具体的切换线程所使用的 API。
在中断中没有记录中断嵌套层级数,就会发生本来应该使用 rt_hw_context_switch_interrupt
时,结果调度器错误使用了 rt_hw_context_switch
。
发生这种错误会有什么影响,为什么楼主这里没有影响呢?
从内核如下代码实现看,只要不使用“信号”,进行其它内核操作“信号量、事件、消息、邮箱”等操作时,中断服务函数不调用“中断通知”应没有任何风险。大家看我的理解对不。
(1)调度函数rt_schedule()利用了rt_interrupt_nest值确定如何进行调度处理。而rt_interrupt_nest的值确定是当前是否处于中断状态,中断通知会设定rt_interrupt_nest的值;
当在切换目的线程不是当前线程时,使用了rt_interrupt_nest值进行了处理,rt_interrupt_nest等于0的处理流程和rt_interrupt_nest不等于0的处理流程是不同的,特别是当使用了信号时(对应使用了软中断。这里的“信号”不是信号量。),rt_interrupt_nest等于0的处理流程和rt_interrupt_nest不等于0的处理流程差异更大。
不过没有使用信号时,rt_interrupt_nest等于0的处理流程和rt_interrupt_nest不等于0的处理流程差异在于:一个调用了rt_hw_context_switch,另外一个调用了rt_hw_context_switch_interrupt,但查看内核函数具体实现时发现函数rt_hw_context_switch和rt_hw_context_switch_interrupt的定义实现是完全一样的。
(2)内核的“信号量、事件、消息、邮箱”操作等”都调用了rt_schedule()。
本来认为在不使用“信号”机制的前提下,中断里进行其它内核操作时,不进行中断通知会也会有不良影响。
但是看了内核代码后,发现rt_hw_context_switchde代码实现和rt_hw_context_switch_interrupt的实现完全一摸一样,这样的的话,rt_interrupt_nest是否为0的处理流程是完全一样,基于此,才判断不进行中断通知是没有影响的。
有个疑问:为何内核目前把rt_hw_context_switchde和rt_hw_context_switch_interrupt设计的完全一样,既然完全一样,为何设计成两个函数名?是为以后扩展吗?还是我没看清楚,漏看一些处理。麻烦大家协助交流下。
@asonyfm
明白楼上专家的意思了:在Cortex_M系列MCU中,当没使用信号情况下,中断里进行其它“事件、消息、信号量”等内核操作,不进行中断通知是没有影响的,但在其它Cortex系列MCU中,情况就不一样了。
非常感谢楼上专家的信息!