本文原创转载请注明出处 http://blog.csdn.net/rickleaf [email protected]
因为RTOS的关中断处理最必要的中断响应过程基本相同,我们讨论实现关中断以后的中断延后处理方法。
μC/OS-II在关中断的时候可以通过API标记一下开中断后去唤醒一个线程处理中断的后续工作。
开中断以后,系统是否会立即处理之前关中断时决定要唤醒的线程,需要μC/OS-II的线程调度器根据
系统的调度策略来决定。
Windows CE也是类似这种方式,它直接映射一个event给中断,同时我们还需要创建一个线程去waitobject这个event,
这样中断到来的时候会直接到这个线程来处理。
那么这样做的好处是什么呢,我们来看下面的这张图。
无论系统发生什么样的中断,或者是中断延后处理有多复杂它都在系统的调度器之内,那么我们说关于中断的延后处理一直处于
可控的范围内。
μC/OS-II的中断处理过程相比eCos更简单可靠,中断的上下文结束后,保证了运行path的一致性。
参考ecos kernel的源代码,我们可以看到ecos提供了一个post_dsr的函数,我们从下面的一张图去看下它的caller
仔细阅读源码可以发现,如果ecos在isr return的时候决定了采用DSR,那么就会调用post_dsr函数。
我们再来看ecos的sched.cxx,注意下面的这段代码然后我们就可以得到eCos的DSR调用方法。
void Cyg_Scheduler::unlock_inner( cyg_ucount32 new_lock ) { #ifdef CYGDBG_KERNEL_TRACE_UNLOCK_INNER CYG_REPORT_FUNCTION(); #endif do { CYG_PRECONDITION( new_lock==0 ? get_sched_lock() == 1 : ((get_sched_lock() == new_lock) || (get_sched_lock() == new_lock+1)), "sched_lock not at expected value" ); #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS // Call any pending DSRs. Do this here to ensure that any // threads that get awakened are properly scheduled. if( new_lock == 0 && Cyg_Interrupt::DSRs_pending() ) Cyg_Interrupt::call_pending_DSRs(); #endif
有此可见eCos的DSR是在ecos进入sched.cxx以后首先运行的代码,也就是说它是脱离调度策略。
换句话说DSR比任何的thread都有更高的优先级。我们可以认为eCos的DSR里面的代码比μC/OS-II中断处理线程的代码
响应的更快。
但是,对于RTOS来说这也增加了系统稳定性的隐患。如果我的DSR里面的代码超多咋办,如果DSR里面的代码挂了怎么办呢?
到现在我们可以去看看eCos的网络中断服务程序了,Yes你看到了。DSR里面只是唤醒了一个线程。
也就是说如果更复杂的中断处理代码是必须放在thread中完成的,其实这也是thread存在的必要性。
总的说来DSR的处理机制还是能起到缩短关中断时间的作用,即使稍微复杂点的代码放到DSR中处理也不会降低响应速度。
不过编程需要技巧,DSR作为中断的处理过程之一就应具有中断处理要求的代码简练快速返回的特性。
更复杂的处理就用DSR中提供的线程同步API去和线程一起协作吧!