原创 基于51单片机的实时操作系统的研究(七)

2010-6-15 11:11 2192 7 7 分类: MCU/ 嵌入式

基于51单片机的实时操作系统的研究(七)


51操作系统 2009-04-17 14:43:37 阅读138 评论1 字号:



2.2.2  任务调度和堆栈变换方法


   Small RTOS 51从低优先级任务切换到最高优先级任务时被调用的。OSSched总是在任务级代码中被调用的。另一个函数OSIntExit()被用来在ISR使得更高优先级任务处于就绪状态时,执行任务切换功能。任务切换只是简单的将处理器寄存器保存到将被挂起的任务的堆栈中,并且将更高优先级的任务从堆栈中恢复出来。


    Small RTOS 51中,处于就绪状态的任务的堆栈结构看起来就像刚发生过中断并将所有的寄存器保存到堆栈中的情形一样。换句话说,Small RTOS 51要运行处于就绪状态的任务必须要做的事就是将所有处理器寄存器从任务堆栈中恢复出来,并且执行中断的返回。为了切换任务可以通过执行OSSched来产生中断。处理器会提供软中断或是陷阱(TRAP)指令来完成这个功能。ISR或是陷阱处理函数(也叫做异常处理函数)的向量地址必须指向汇编语言函数OSCtxSw()


   (1) OSSched(void)函数一开始就关中断,在寻找进入就绪的高优先级的任务过程中,为防止中断服务程序把一个或几个任务的就绪位置位,中断是被关掉的。如果OS允许管理中断,(EN-OS-INT-ENTER0)则OSSCHED()先判断本身是否由中断调用。如果中断嵌套层数OSINTNESTING 大于0。则OSSCHED()由中断调用,将不进行任务调度,函数直接返回,如果不是中断调用OSSCHED()则OSSCHED()找出进入就绪状态的最高优先级的任务,实质是从任务ID0的任务起检查起就绪表的相应位是否为1。查到的ID存于变量OSNEXTTASKID中作为OS-TASK-SW()的参数。并调用之进行实际的切换。最后,函数将开中断。


非中断的任务切换函数OSSched程序代码:


 


/*********************************


** 全局变量: OSIntNesting,OSNextTaskID


** 调用模块: OS_TASK_SW


********************************


        void  OSSched(void)


{    uint8 temp;


    OS_ENTER_CRITICAL();       关中断


#if EN_OS_INT_ENTER > 0


    if (OSIntNesting == 0)              /* 是否是中断中调用 */


    {


#endif


#if OS_MAX_TASKS < 9   /* 查找处于就绪状态的任务中优先级最高的任务 */


        temp = OSTaskRuning;


        for (OSNextTaskID = 0; OSNextTaskID < OS_MAX_TASKS; OSNextTaskID++)


        {


            if ((temp & 0x01) != 0)


            {


                break;


            }


            temp = temp >> 1;


        }


        OS_TASK_SW();                   /* 进行任务调度 */


#else


                /* 查找处于就绪状态的任务中优先级最高的任务 */


        temp = OSTaskRuning % 256;


        for (OSNextTaskID = 0; OSNextTaskID < 8; OSNextTaskID++)


        {


            if ((temp & 0x01) != 0)


            {


                goto TaskSw;


            }


            temp = temp >> 1;


        }


        temp = OSTaskRuning / 256 ;


        for (; OSNextTaskID < OS_MAX_TASKS; OSNextTaskID++)


        {


            if ((temp & 0x01) != 0)


            {


                break;


            }


            temp = temp >> 1;


        }


TaskSw:



        OS_TASK_SW();         /* 进行任务调度 */


#endif


#if EN_OS_INT_ENTER > 0


    }


#endif


OS_EXIT_CRITICAL();}


 


http://xky19870905.blog.163.com/blog/static/51855417200931724337298/

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
7
关闭 站长推荐上一条 /3 下一条