解释如下: 这个函数用来通知OS我们正准备进入中断服务例程,这允许OS保持中断嵌套的路径(次数),
以便于仅在最后一次嵌套的中断退出时才执行任务调度。
1.这个函数应当在关闭中断的情况下调用,为啥?涉及到全局变量的操作了吧,也就是在调用前后加下它哥俩:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。
2.可以直接增加OSIntNesting,而不必调用这个函数,因为这个变量是全局的!
3.一定要调用OSIntExit()这个函数,即使你直接增加OSIntNesting这个变量。也就是说,上面两个函数是哥俩,一定要成对使用,但是由于大哥本质上只是增加了中断嵌套次数,可以不用大哥,但一定得用小弟,为啥?下面再细说!
后央三句自己看吧,挺简单的!
再看老二函数源码:
void OSIntExit (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
if (OSRunning == TRUE) {
OS_ENTER_CRITICAL();
if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping */
OSIntNesting--;
}
if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Reschedule only if all ISRs complete ... */
OSIntExitY = OSUnMapTbl[OSRdyGrp]; /* ... and not locked. */
OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
OSCtxSwCtr++; /* Keep track of the number of ctx switches */
OSIntCtxSw(); /* Perform interrupt level ctx switch */
}
}
OS_EXIT_CRITICAL();
}
}
源码不多,也不少,不过关键的需要理解的就那一行:OSIntCtxSw(),这是啥?中断级任务调度函数啊,终于出来了,看它的注释吧:
*********************************************************************************************************
* EXIT ISR
*
* Description: This function is used to notify uC/OS-II that you have completed serviving an ISR. When
* the last nested ISR has completed, uC/OS-II will call the scheduler to determine whether
* a new, high-priority task, is ready to run.
*
* Arguments : none
*
* Returns : none
*
* Notes : 1) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call
* to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the
* end of the ISR.
* 2) Rescheduling is prevented when the scheduler is locked (see OS_SchedLock())
翻译如下:这个函数用来通知OS我们已经完成了中断服务程充,当最后一次被嵌套的中断也完成时,OS将调用scheduler来决定是否有一个新的,更高优先级的任务,已经主绪。(当然没有更高的时就恢复被中断的任务)
总结:我遇到情况的主要原因大概是,当按普通方法写中断服务例程时,没有通知操作系统,触发中断时当前执行任务被中断,然后退出中断服务例程时,系统找不到原先被中断的任务,不知道该干啥,所以就进入了默认异常处理程序,死在里面出不来了,呵呵,不知道这样理解对不对,呵呵! |