[uCOS/RTOS] 是时候讨论一波 OSCtxSw()和OSIntCtxSw()的区别了

[复制链接]
3466|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定时就可以跑!

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

我的程序长这样
  1. void  OSIntExit (void)
  2. {
  3. #if OS_CRITICAL_METHOD == 3                            /* Allocate storage for CPU status register     */
  4.     OS_CPU_SR  cpu_sr;
  5. #endif
  6.    
  7.    
  8.     OS_ENTER_CRITICAL();
  9.     if (OSIntNesting > 0) {                            /* Prevent OSIntNesting from wrapping           */
  10.         OSIntNesting--;
  11.     }
  12.     if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Reschedule only if all ISRs complete ...     */
  13.         OSIntExitY    = OSUnMapTbl[OSRdyGrp];          /* ... and not locked.                          */
  14.         OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
  15.         if (OSPrioHighRdy != OSPrioCur) {              /* No Ctx Sw if current task is highest rdy     */
  16.             OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy];
  17.             OSCtxSwCtr++;                              /* Keep track of the number of context switches */
  18.             OSIntCtxSw();                              /* Perform interrupt level context switch       */
  19.         }
  20.     }
  21.     OS_EXIT_CRITICAL();
  22. }




大神的程序长这样
  1. void  OSIntExit (void)
  2. {
  3. #if OS_CRITICAL_METHOD == 3u                               /* Allocate storage for CPU status register */
  4.     OS_CPU_SR  cpu_sr = 0u;
  5. #endif



  6.     if (OSRunning == OS_TRUE) {
  7.         OS_ENTER_CRITICAL();
  8.         if (OSIntNesting > 0u) {                           /* Prevent OSIntNesting from wrapping       */
  9.             OSIntNesting--;
  10.         }
  11.         if (OSIntNesting == 0u) {                          /* Reschedule only if all ISRs complete ... */
  12.             if (OSLockNesting == 0u) {                     /* ... and not locked.                      */
  13.                 //OS_SchedNew();
  14.                 OS_Sched();
  15.                 OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
  16.                 if (OSPrioHighRdy != OSPrioCur) {          /* No Ctx Sw if current task is highest rdy */
  17. #if OS_TASK_PROFILE_EN > 0u
  18.                     OSTCBHighRdy->OSTCBCtxSwCtr++;         /* Inc. # of context switches to this task  */
  19. #endif
  20.                     OSCtxSwCtr++;                          /* Keep track of the number of ctx switches */
  21.                     OSIntCtxSw();                          /* Perform interrupt level ctx switch       */
  22.                 }
  23.             }
  24.         }
  25.         OS_EXIT_CRITICAL();
  26.     }
  27. }



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

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

然后我的程序改成了这样 他就能正常巡行了
  1. void  OSIntExit (void)
  2. {
  3. #if OS_CRITICAL_METHOD == 3                            /* Allocate storage for CPU status register     */
  4.     OS_CPU_SR  cpu_sr;
  5. #endif
  6.    
  7.    
  8.     OS_ENTER_CRITICAL();
  9.    // if (OSIntNesting > 0) {                            /* Prevent OSIntNesting from wrapping           */
  10.   //      OSIntNesting--;
  11.   //  }
  12.   //  if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Reschedule only if all ISRs complete ...     */
  13.   //      OSIntExitY    = OSUnMapTbl[OSRdyGrp];          /* ... and not locked.                          */
  14.   //      OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
  15.   //      if (OSPrioHighRdy != OSPrioCur) {              /* No Ctx Sw if current task is highest rdy     */
  16.   //          OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy];
  17.   //          OSCtxSwCtr++;                              /* Keep track of the number of context switches */
  18.   //          OSIntCtxSw();                              /* Perform interrupt level context switch       */
  19.   //      }
  20. //   }
  21.     if (OSIntNesting > 0) {                            /* Prevent OSIntNesting from wrapping           */
  22.         OSIntNesting--;
  23.     }
  24.     if ((OSIntNesting == 0) && (OSLockNesting == 0)) {
  25.         OS_Sched();
  26.         OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy];
  27.         if (OSPrioHighRdy != OSPrioCur) {  
  28.             OSCtxSwCtr++;  
  29.             OSIntCtxSw();
  30.         }
  31.     }
  32.     OS_EXIT_CRITICAL();
  33. }



所以 今天的问题是
OSCtxSw()和OSIntCtxSw()有啥区别 到底啥时候用啥
dq_qiuxue 发表于 2017-3-17 16:45 | 显示全部楼层
哈哈哈,非常感谢您,我也遇到和您一样的问题,现看到你的帖子已解决,您可以贴出您的OSCtxSw()和OSIntCtxSw()的代码吗,我来和我的做一下比较,哈哈
hnuduanyang 发表于 2017-6-16 19:26 | 显示全部楼层
老铁,我也遇到了和你一样的问题,不过还没有解决,能留个QQ号吗? 讨论一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

26

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部