小弟这几天移植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()有啥区别 到底啥时候用啥
|