woshiwowo 发表于 2010-12-22 16:05:59

UCOS大牛们,帮我分析一下这个问题!

我在STM32上移UCOS2.86,进程之间任务的切换好像有点问题,在本论坛中看到有人上传的UCOS2.90,这下任务切换同步比较好,
经UCOS2.90和UCOS2.86内核代码比较,发现,在OSIntExit和OS_Sched中有一句 OSTCBHighRdy= OSTCBPrioTbl;位置有些不一样,提前了一下,在这两个函数中都把2.86下的
OS_SchedNew();
if (OSPrioHighRdy != OSPrioCur)
{       /* No Ctx Sw if current task is highest rdy */
   OSTCBHighRdy= OSTCBPrioTbl;
   OSIntCtxSw();                        /* Perform interrupt level ctx switch       */
}
换成2.90的
OS_SchedNew();
OSTCBHighRdy = OSTCBPrioTbl;
if (OSPrioHighRdy != OSPrioCur)
{          /* No Ctx Sw if current task is highest rdy */

    OSCtxSwCtr++;                        /* Keep track of the number of ctx switches */
    OSIntCtxSw();                        /* Perform interrupt level ctx switch       */
}
请问这样做是为什么??为什么改了后任务切换比较好,原理是什么??谢谢.

woshiwowo 发表于 2010-12-22 16:06:20

具体原程序对比如下:
在UCOS2.86中

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();
    }
}
voidOS_Sched (void)
{
#if OS_CRITICAL_METHOD == 3                            /* Allocate storage for CPU status register   */
    OS_CPU_SRcpu_sr = 0;
#endif



    OS_ENTER_CRITICAL();
    if (OSIntNesting == 0) {                           /* Schedule only if all ISRs done and ...       */
      if (OSLockNesting == 0) {                      /* ... scheduler is 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++;                        /* Increment context switch counter             */
                OS_TASK_SW();                        /* Perform a context switch                     */
            }
      }
    }
    OS_EXIT_CRITICAL();
}
在UCOS2.90

voidOSIntExit (void)
{
#if OS_CRITICAL_METHOD == 3u                               /* Allocate storage for CPU status register */
    OS_CPU_SRcpu_sr = 0u;
#endif
    if (OSRunning == OS_TRUE) {
      OS_ENTER_CRITICAL();
      if (OSIntNesting > 0u) {                           /* Prevent OSIntNesting from wrapping       */
            OSIntNesting--;
      }
      if (OSIntNesting == 0u) {                        /* Reschedule only if all ISRs complete ... */
            if (OSLockNesting == 0u) {                     /* ... and not locked.                      */
                OS_SchedNew();
                OSTCBHighRdy = OSTCBPrioTbl;
                if (OSPrioHighRdy != OSPrioCur) {          /* No Ctx Sw if current task is highest rdy */
#if OS_TASK_PROFILE_EN > 0u
                  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();
    }
}

voidOS_Sched (void)
{
#if OS_CRITICAL_METHOD == 3u                           /* Allocate storage for CPU status register   */
    OS_CPU_SRcpu_sr = 0u;
#endif



    OS_ENTER_CRITICAL();
    if (OSIntNesting == 0u) {                        /* Schedule only if all ISRs done and ...       */
      if (OSLockNesting == 0u) {                     /* ... scheduler is not locked                  */
            OS_SchedNew();
            OSTCBHighRdy = OSTCBPrioTbl;
            if (OSPrioHighRdy != OSPrioCur) {          /* No Ctx Sw if current task is highest rdy   */
#if OS_TASK_PROFILE_EN > 0u
                OSTCBHighRdy->OSTCBCtxSwCtr++;         /* Inc. # of context switches to this task      */
#endif
                OSCtxSwCtr++;                        /* Increment context switch counter             */
                OS_TASK_SW();                        /* Perform a context switch                     */
            }
      }
    }
    OS_EXIT_CRITICAL();
}

wuyiduan 发表于 2011-1-5 10:16:48

一个是不管中断结束后就绪的是不是被中断的都要更新控制块指针
一个是只有被中断的和已近就绪的最高级任务不是同一个的时候更新
页: [1]
查看完整版本: UCOS大牛们,帮我分析一下这个问题!