[uCOS/RTOS]

是时候讨论一波 OSCtxSw()和OSIntCtxSw()的区别了

[复制链接]
2897|2
手机看帖
扫描二维码
随时随地手机跟帖
lcr52099|  楼主 | 2016-2-20 16:08 | 显示全部楼层 |阅读模式
os, NTC, ST, TI, TE
小弟这几天移植uCOS系统的时候,
发现了一个问题,
就是系统时钟我用TIM模块记时的时候程序能正常运行,
但是我把记时的方式改成了PIT中断记时,程序就开始跑飞了。
整个人都是懵逼的,ILLEGAL_BP是什么鬼。


尼玛这不科学啊,虽然TIM模块能跑,但是我就是喜欢用PIT,问我为啥?我喜欢,任性!
于是我就走上了debug的不归路,xs128的datasheet被我看了一次又一次,
然并卵,我发现我的中断没问题啊。
终于在今天,我开始了一遍有一遍的单步调试

终于 在程序跑到了嘀嗒时钟的OSIntExit()时,问题出现了
在执行了OSIntCtxSw()的最后一句时,编译器提示我单片机自动复位了!
问题就是这个!

我赵日天第一个表示不服,为啥我在网上下载的uCOS移植好了的程序用PIT定时就可以跑!

默默的点开了网上大神写的程序,开始默默比对 终于发现了不一样的地方 

我的程序长这样
void  OSIntExit (void)
{
#if OS_CRITICAL_METHOD == 3                            /* Allocate storage for CPU status register     */
    OS_CPU_SR  cpu_sr;
#endif
   
   
    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 context switches */
            OSIntCtxSw();                              /* Perform interrupt level context switch       */
        }
    }
    OS_EXIT_CRITICAL();
}




大神的程序长这样
void  OSIntExit (void)
{
#if OS_CRITICAL_METHOD == 3u                               /* Allocate storage for CPU status register */
    OS_CPU_SR  cpu_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();
                OS_Sched();
                OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
                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();
    }
}



为啥长得不一样,最后冰雪聪明的我还是在里面找到了两个不一样的地方

那就是!大神的定时中断任务切换代码根本就没执行OSIntCtxSw()!!!!!

然后我的程序改成了这样 他就能正常巡行了
void  OSIntExit (void)
{
#if OS_CRITICAL_METHOD == 3                            /* Allocate storage for CPU status register     */
    OS_CPU_SR  cpu_sr;
#endif
   
   
    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 context switches */
  //          OSIntCtxSw();                              /* Perform interrupt level context switch       */
  //      }
//   }
    if (OSIntNesting > 0) {                            /* Prevent OSIntNesting from wrapping           */
        OSIntNesting--;
    }
    if ((OSIntNesting == 0) && (OSLockNesting == 0)) {
        OS_Sched();
        OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy];
        if (OSPrioHighRdy != OSPrioCur) {  
            OSCtxSwCtr++;  
            OSIntCtxSw();
        }
    }
    OS_EXIT_CRITICAL();
}



所以 今天的问题是
OSCtxSw()和OSIntCtxSw()有啥区别 到底啥时候用啥

相关帖子

dq_qiuxue| | 2017-3-17 16:45 | 显示全部楼层
哈哈哈,非常感谢您,我也遇到和您一样的问题,现看到你的帖子已解决,您可以贴出您的OSCtxSw()和OSIntCtxSw()的代码吗,我来和我的做一下比较,哈哈

使用特权

评论回复
hnuduanyang| | 2017-6-16 19:26 | 显示全部楼层
老铁,我也遇到了和你一样的问题,不过还没有解决,能留个QQ号吗? 讨论一下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

26

帖子

0

粉丝