ucosII进出中断不用OSIntEnter()和OSIntEixt()也能跑,为什么?
ucosII进出中断不用OSIntEnter()和OSIntEixt()也能跑,为什么?我用的是从ucosII官方下载的LPC2103移植范例,开发环境是IAR,其中时钟节拍使用timer0产生,发现其中系统时钟节拍服务函数中没有成对的使用OSIntEnter()和OSIntEixt(),这和众多ucosII书籍所说的不一样,但是系统能正常创建任务,完全可以照常运行。我仿照timer0初始化timer1,并且timer1的中断服务函数中也没有使用OSIntEnter()和OSIntEixt()这两个函数,结果系统同样可以正常跑起来。请看程序的相关代码:
voidTmr_TickISR_Handler (void)
{
T0IR = 0xFF; /* Clear timer #0 interrupt */
OSTimeTick(); /* Call uC/OS-II's OSTimeTick() */
}
在上面的OsTimeTick()函数中也没找到OSIntEnter()和OSIntEixt()。
难道在中断服务程序中OSIntEnter()和OSIntEixt()不是必须的吗?还是模板在其他地方做了相关处理?
voidOSIntEnter (void)
{
if (OSRunning == OS_TRUE) {
if (OSIntNesting < 255u) {
OSIntNesting++; /* Increment ISR nesting level */
}
}
}
这个函数执行使变量OSIntNesting自增1,是有作用的。
比如你错误的在中断中调用了OSFlagPend函数,如果这个变量不为0,那么说明此时是在中断里面,直接返回OS_ERR_PEND_ISR,否则有可能引起程序卡在中断里出不来,因为PEND会导致挂起,一直等待!
而
voidOSIntExit (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SRcpu_sr = 0;
#endif
if (OSRunning == OS_TRUE) {
OS_ENTER_CRITICAL();
if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping */
OSIntNesting--;
}
if (OSIntNesting == 0) { /* Reschedule only if all ISRs complete ... */
if (OSLockNesting == 0) { /* ... and not locked. */
OS_SchedNew();
if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */
OSTCBHighRdy= OSTCBPrioTbl;
#if OS_TASK_PROFILE_EN > 0
OSTCBHighRdy->OSTCBCtxSwCtr++; /* Inc. # of context switches to this task*/
#endif
OSCtxSwCtr++; /* Keep track of the number of ctx switches */
OSIntCtxSw(); /* Perform interrupt level ctx switch */
}
}
}
OS_EXIT_CRITICAL();
}
这个函数会判断此OSIntNesting是否已经为0,如果为0,会发生任务调度,如果不为0,那么退出一层中断, 主要是用于在多个中断嵌套的时候防止中断还没结束,就执行任务调度!! 谢谢两位,回答都很精彩! 3L的解释很好,学习了 支持3l的... 学习了 ballack_linux 发表于 2014-3-14 20:30
voidOSIntEnter (void)
{
if (OSRunning == OS_TRUE) {
你太搞笑了,中断绝对不能用Pend之类等待的函数,等待就不叫中断了,误人子弟 lanmanck 发表于 2019-3-16 10:57
你太搞笑了,中断绝对不能用Pend之类等待的函数,等待就不叫中断了,误人子弟 ...
晕, 麻烦审题仔细一点好吗。。我说了中断可以使用pend之类的话了?而且, 许多新手写代码的时候是可能会在中断中使用会导致挂起的函数的, 见多了就见怪不怪了。
页:
[1]