μcos-II的任务调度

看到了一位网友的博客,感觉说的比较好,就Copy过来了

主要是之前知道任务调度是调用OS_Sched,但是没有看到这个函数的具体实现,或者说看过这个实现

没有意识到是利用软中断来对当前任务做现场保存的。

这里对接上了,昨天晚上还嘀咕着是不是这么做的,看来果然是啊。

 

//任务调度
//uCOS-II总是运行进入就绪态任务中优先级最高的那一个。确定哪个任务优先级最高,下面该哪个任务运行了的工作是
//由调度器(Scheduler)完成的。任务级的调度是由函数OSSched()完成的。中断级的调度是由另一个函数OSIntExt()完
//成的Scheduling。
//注意:1) 这是一个uCOS-II内部函数,你不能在应用程序中使用它
//     2) 给调度器上锁用于禁止任务调度(查看OSSchedLock()函数)
//说明:1)任务切换很简单,由以下两步完成,将被挂起任务的微处理器寄存器推入堆栈,然后将较高优先
//       级的任务的寄存器值从栈中恢复到寄存器中。在uCOS-II中,就绪任务的堆栈结构总是看起来
//       跟刚刚发生过中断一样,所有微处理器的寄存器都保存在栈中。换句话说,uCOS-II运行就绪态
//       的任务所要做的一切,只是恢复所有的CPU寄存器并运行中断返回指令。为了做任务切换,运行
//         OS_TASK_SW(),人为模仿了一次中断。多数微处理器有软中断指令或者陷阱指令TRAP来实现上
//         述操作。中断服务子程序或陷阱处理(Trap hardler),也称作事故处理(exception handler),
//         必须提供中断向量给汇编语言函数OSCtxSw()。OSCtxSw()除了需要OS_TCBHighRdy指向即将被
//         挂起的任务,还需要让当前任务控制块OSTCBCur指向即将被挂起的任务,移植uCOS-II,有关于
//         OSCtxSw()的更详尽的解释。
//     2)OS_Sched()的所有代码都属临界段代码。在寻找进入就绪态的优先级最高的任务过程中,为防止中
//         断服务子程序把一个或几个任务的就绪位置位,中断是被关掉的。为缩短切换时间,OSSched()全部
//         代码都可以用汇编语言写。为增加可读性,可移植性和将汇编语言代码最少化,OSSched()是用C写的。

//任务调度函数
void  OS_Sched (void)
{
#if OS_CRITICAL_METHOD == 3                            //中断函数被设定为模式3
    OS_CPU_SR  cpu_sr;
#endif    
    INT8U      y;                                       //定义一个8位整数y


    OS_ENTER_CRITICAL();                               //关闭中断
    //如果中断嵌套次数>0,且上锁(调度器)嵌套次数>0,函数退出,不做任何调度
    if ((OSIntNesting == 0) && (OSLockNesting == 0)) { 
        //如果函数不是在中断服务子程序中调用的,且调度允许的,则任务调度函数将找出进入就绪态的
        //最高优先级任务,进入就绪态的任务在就绪表中OSRdyTbl[]中相应位置位。
        y             = OSUnMapTbl[OSRdyGrp];          /* Get pointer to HPT ready to run              */
        OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
        //找到最高优先级任务后,函数检查这个优先级最高的任务是否是当前正在运行的任务,以避免不
        //必要的任务调度,多花时间
        if (OSPrioHighRdy != OSPrioCur) {              /* No Ctx Sw if current task is highest rdy     */
            //为实现任务切换,OSTCBHighRdy必须指向优先级最高的那个任务控制块OS_TCB,这是通过将
            //以OSPrioHighRdy为下标的OSTCBPrioTbl[]数组中的那个元素赋给OSTCBHighRdy来实现的
            OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
            OSCtxSwCtr++;                              //统计计数器OSCtxSwCtr加1,以跟踪任务切换次数
            OS_TASK_SW();                              //最后宏调用OS_TASK_SW()来完成实际上的任务切换
        }
    }
    OS_EXIT_CRITICAL();                                   //打开中断
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值