hualiming025 发表于 2014-3-14 09:29

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()不是必须的吗?还是模板在其他地方做了相关处理?

ballack_linux 发表于 2014-3-14 20:30

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,那么退出一层中断, 主要是用于在多个中断嵌套的时候防止中断还没结束,就执行任务调度!!

hualiming025 发表于 2014-3-17 08:44

谢谢两位,回答都很精彩!

SevenWans 发表于 2014-3-17 19:29

3L的解释很好,学习了

Larm1 发表于 2016-3-15 17:37

支持3l的...

戴风海 发表于 2016-3-28 22:02

学习了

lanmanck 发表于 2019-3-16 10:57

ballack_linux 发表于 2014-3-14 20:30
voidOSIntEnter (void)
{
    if (OSRunning == OS_TRUE) {


你太搞笑了,中断绝对不能用Pend之类等待的函数,等待就不叫中断了,误人子弟

ballack_linux 发表于 2019-4-11 21:13

lanmanck 发表于 2019-3-16 10:57
你太搞笑了,中断绝对不能用Pend之类等待的函数,等待就不叫中断了,误人子弟 ...

晕, 麻烦审题仔细一点好吗。。我说了中断可以使用pend之类的话了?而且, 许多新手写代码的时候是可能会在中断中使用会导致挂起的函数的, 见多了就见怪不怪了。
页: [1]
查看完整版本: ucosII进出中断不用OSIntEnter()和OSIntEixt()也能跑,为什么?