void OSIntExit (void) { OS_CPU_SR cpu_sr = 0u; 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[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(); } }
//中断函数已经完成 EXIT ISR //描述: 通知uC/OS-II,一个中断服务已经执行完成,这有助于uC/OS-II掌握中断嵌套的情况。通常 //OSIntExit()和OSIntEnter()联合使用。当最后一层嵌套的中断执行完毕时,如果有更高优先级任务 //准备就绪,则uC/OS-II会调用任务调度函数。在这种情况下,中断返回到更高优先级的任务,而不 //是被中断了的任务。调用者,只能在中断程序中。 //参数: 无 //返回: 无 //注意: 1) 在任务级不能调用该函数,并且即使没有调用OSIntEnter()函数,而是使用直接递增OSIntNesting的方法, // 也必须调用OSIntExit()。 // 2) 给调度器上锁用于禁止任务调度 (查看 OSSchedLock()函数) void OSIntExit (void) { #if OS_CRITICAL_METHOD == 3 //中断函数被设定为模式3 OS_CPU_SR cpu_sr; #endif if (OSRunning == TRUE) { //关闭中断 OS_ENTER_CRITICAL(); if (OSIntNesting > 0) { //如果中断嵌套大于0 OSIntNesting--; //中断嵌套计数变量减1 } //1)中断嵌套层数计数器和锁定嵌套计数器(OSLockNesting)二者都必须是零 //2)OSRdyTbl[]所需的检索值Y是保存在全程变量OSIntExitY中 //3)检查具有最高优先级别的就绪任务的优先级是否是正在运行的任务的优先级 //4)将任务控制块优先级表保存到指向最高级优先级就绪任务控制块的指针 //5)上下文切换的次数(统计任务计数器) //6)做中断任务切换 if ((OSIntNesting == 0) && (OSLockNesting == 0)) { //1 OSIntExitY = OSUnMapTbl[OSRdyGrp]; //2 OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]); if (OSPrioHighRdy != OSPrioCur) { //3 OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];//4 OSCtxSwCtr++; //5 OSIntCtxSw(); //6 } } OS_EXIT_CRITICAL(); //打开中断 } }
void OSIntExit (void) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif if (OSRunning == TRUE) { 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 ctx switches */ OSIntCtxSw(); /* Perform interrupt level ctx switch */ } } OS_EXIT_CRITICAL(); } }