⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sched.c

📁 minitos是一个实时的嵌入式操作系统
💻 C
字号:
/*
    miniTOS V0.1.3  1998-2004 (c) 林良水 (Lin LS)
    miniTOS是一个开放源码的软件,授权LGPL,但开发人员不保证本软件的可靠性,
以及对您的损失负任何责任。
    www.minitos.com

    本文实现miniTOS进程调度及优先级管理。

    create by Lin LS ,1998.10
*/
//#define VC

#include <stdio.h>

#include "minitosdef.h"
#include "extdefine.h"

#ifdef VC
#include "proctbl.h"
void lock_int(void){};
void unlock_int(void){};
void switch_task(void){};
void SendOneChar(int i,char a){i=i;a=a;};
#endif

struct ProcTbl * ptrTaskRdy[N_TASK_PRIO]; //0--highest,N_TASK_PRIO-1 is lowest for task
                // 0..7
struct ProcTbl * ptrServerRdy; //[N_SERVER_PRIO];//server priority is lower than task
                //Server priority is from N_TASK_PRIO to ...
                // now only one is 8
struct ProcTbl * ptrProcRdy; //[N_PROC_PRIO];  //user process priority is lower than server
                // 9
                // idle process priority is 10
struct ProcTbl * ptrIdle;

unsigned char TaskPrioCnt=0;    //task priority count use. 
            // bit.0 =1 mean ptrTaskRdy[0] have Task Rdy
            // bit.7 =1 mean ptrTaskRdy[7] have Task Rdy

/****************************************************************
** function: count to get a highest priority task or server or proc,ortherwise
        is idle.
**
*****************************************************************/
struct ProcTbl * SelectHightestPrioTask(void)
{
    int i;
    for(i=0;i<N_TASK_PRIO;i++)
    {
        if(ptrTaskRdy[i]!=NULL)
            return ptrTaskRdy[i];
    }
    if(ptrServerRdy!=NULL)
        return ptrServerRdy;
    if(ptrProcRdy!=NULL)
        return ptrProcRdy;
    return ptrIdle;
}
/****************************************************************
**function: 
**
*****************************************************************/
void SelectNewTask(void)
{
    ptrCurrProc=SelectHightestPrioTask();
}
/*
why in this is error??
void InitTaskRdy(void)
{
    ptrTaskRdy[0]=&Proc[0]; //idle1
    //ptrServerRdy=&Proc[1];    //idle2
    //ptrProcRdy= &Proc[2];     //idle3
    //ptrCurrProc= &(Proc[1]);
}
*/
/*************************************************
**Function:开机启动把进程表初始化
**
*************************************************/
void InitTaskRdyPtrToNULL(void)
{
    int i;
    for(i=0;i<N_TASK_PRIO;i++)
    {
        ptrTaskRdy[i]=NULL;
    }
    ptrServerRdy=NULL;
    ptrProcRdy=NULL;
}

//进程调度函数,调用本子程序实现进程调度。
void sched(void)
{
    lock_int();
    switch_task();
    unlock_int();
}
/***************************************************************************
**Function: 把rp所指的进程加到就绪表中使进程可运行。
**input:
**output:
***************************************************************************/

void ready(PROC *rp)
{
/*
    int prio;
    prio=rp->priority;
    if(prio<SERVER_PRIO)
    {   //TASK
        ptrTaskRdy[prio]=rp;    //ptrTaskRdy[priority]指向rp
        return;
    }
    if(prio==SERVER_PRIO)
    {   
        ptrServerRdy=rp;    //ptrServerRdy指向rp
        return;
    }
    if(prio==PROC_PRIO)
    {   
        ptrProcRdy=rp;  //ptrProcRdy指向rp
        return;
    }
*/
    int prio;
    PROC *ptrTmpOld;

    prio=rp->priority;
    //SendOneChar(1,prio+'0');
    if(prio<SERVER_PRIO)
    {   //TASK,加到Ready链表的末尾
        if( (ptrTmpOld=FindLastPos(ptrTaskRdy[prio]))==NULL)
        {   
            ptrTaskRdy[prio]=rp;
        }else
        {
            //现在ptrTmpOld指向链表最后一个位置
            ptrTmpOld->ptrNextProc=rp;
        }
        rp->ptrNextProc=NULL;
                //rp加入ptrTaskRdy[priority]链表的最后一个位置
        return;
    }
    if(prio==SERVER_PRIO)
    {   

        if( (ptrTmpOld=FindLastPos(ptrServerRdy))==NULL)
        {   
            ptrServerRdy=rp;
        }else
        {
            //现在ptrTmpOld指向链表最后一个位置
            ptrTmpOld->ptrNextProc=rp;
        }
        rp->ptrNextProc=NULL;
                //rp加入ptrServerRdy链表的最后一个位置

        return;
    }
    if(prio==PROC_PRIO)
    {   

        if( (ptrTmpOld=FindLastPos(ptrProcRdy))==NULL)
        {   
            ptrProcRdy=rp;
        }else
        {
            //现在ptrTmpOld指向链表最后一个位置
            ptrTmpOld->ptrNextProc=rp;
        }
        rp->ptrNextProc=NULL;
                //rp加入ptrProcRdy链表的最后一个位置

        return;
    }
}

/***************************************************************************
**Function:把rp所指的进程从就绪表中去掉,使不可运行。
**input:
**output:
***************************************************************************/
void unready(PROC *rp)
{
/*
    int prio;
    prio=rp->priority;
    if(prio<SERVER_PRIO)
    {   
        ptrTaskRdy[prio]=NULL;
        return;
    }
    if(prio==SERVER_PRIO)
    {   
        ptrServerRdy=NULL;
        return;
    }
    if(prio==PROC_PRIO)
    {   
        ptrProcRdy=NULL;
        return;
    }
*/
    int prio,i;
    PROC * ptrTmpOld;
    prio=rp->priority;
    if(prio<SERVER_PRIO)
    {   
        //ptrTaskRdy[prio]=NULL;
        ptrTmpOld=FindProcPos(ptrTaskRdy[prio],rp,&i);
        if(i<0)return ;
        if(i==0)
        {   //删除第一个
            ptrTaskRdy[prio]=rp->ptrNextProc;
        }else
        {  //删除rp所指向的项
            ptrTmpOld->ptrNextProc=rp->ptrNextProc;
        }
        return;
    }


    if(prio==SERVER_PRIO)
    {   
        //ptrServerRdy=NULL;
        ptrTmpOld=FindProcPos(ptrServerRdy,rp,&i);
        if(i<0)return ;
        if(i==0)
        {   //删除第一个
            ptrServerRdy=rp->ptrNextProc;
        }else
        {  //删除rp所指向的项
            ptrTmpOld->ptrNextProc=rp->ptrNextProc;
        }

        return;
    }
    if(prio==PROC_PRIO)
    {   
        //ptrProcRdy=NULL;
        ptrTmpOld=FindProcPos(ptrProcRdy,rp,&i);
//      SendOneChar(1,i+'0');
        if(i<0)return ;
        if(i==0)
        {   //删除第一个
            ptrProcRdy=ptrProcRdy->ptrNextProc;
            //SendOneChar(1,'f');
        }else
        {  //删除rp所指向的项
            ptrTmpOld->ptrNextProc=rp->ptrNextProc;
            //SendOneChar(1,'k');
        }

        return;
    }
    
}

//调用本子程序时,是处于定时时间片,rp一定处于该优先级rdy表的第一个位置
void ChangeProcPos(PROC *rp)
{
    int prio;
    PROC *ptrTmpOld;
    prio=rp->priority;

    if(prio<SERVER_PRIO)
    {   
        ptrTmpOld=FindLastPos(ptrTaskRdy[prio]);
        if(ptrTmpOld==NULL)
        {   //i==0空表  
            return ;  //在SwitchTaskTimeOver调用不可能出现
        }else
        if(ptrTmpOld==ptrTaskRdy[prio])
        { //最后一项等于第一项,只有一项,就是自己,不用改变
            return;
        }else
        {
            ptrTaskRdy[prio]=rp->ptrNextProc; //删除处于开头的rp
            //现在ptrTmpOld指向链表最后一个位置
            ptrTmpOld->ptrNextProc=rp; //rp加入ptrTaskRdy[priority]链表的最后一个位置
            rp->ptrNextProc=NULL;
        }               
        return;
    }
    if(prio==SERVER_PRIO)
    {   
        ptrTmpOld=FindLastPos(ptrServerRdy);
        if(ptrTmpOld==NULL)
        {   //i==0空表  
            return ;  //在SwitchTaskTimeOver调用不可能为出现
        }else
        if(ptrTmpOld==ptrServerRdy)
        { //只有一项,就是自己,不用改变
            return;
        }else
        {
            ptrServerRdy=rp->ptrNextProc; //删除处于开头的rp
            //现在ptrTmpOld指向链表最后一个位置
            ptrTmpOld->ptrNextProc=rp; //rp加入ptrServerRdy链表的最后一个位置
            rp->ptrNextProc=NULL;
        }               
        return;

    }
    if(prio==PROC_PRIO)
    {   
        ptrTmpOld=FindLastPos(ptrProcRdy);
        if(ptrTmpOld==NULL)
        {   //i==0空表  
            return ;  //在SwitchTaskTimeOver调用不可能为出现
        }else
        if(ptrTmpOld==ptrProcRdy)
        { //只有一项,就是自己,不用改变
            return;
        }else
        {
            ptrProcRdy=rp->ptrNextProc; //删除处于开头的rp
            //现在ptrTmpOld指向链表最后一个位置
            ptrTmpOld->ptrNextProc=rp; //rp加入ptrProcRdy链表的最后一个位置
            rp->ptrNextProc=NULL;
        }               
        return;

    }
        
}
/*******************************************************************
**Function:if process priority is same,time slice down come,let other same priority
    process run.
      本子程序必须在time中断中调用。放在OnTime子程序之后,使从sleep进程ready后
    先运行。
    本子程序必须在定时中断中调用。如果在中断中加入,可实现同一优先级的时间轮询调度。
**
*********************************************************************/
void SwitchTaskTimeOver(void)
{
    if(ptrCurrProc->RunTicksCount)
        ptrCurrProc->RunTicksCount--;
    if(ptrCurrProc->RunTicksCount==0)
    {
        ptrCurrProc->RunTicksCount=ptrCurrProc->RunTicksInit;
        ChangeProcPos(ptrCurrProc);
    }
}

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/*******************************************************************
**Function:
**Input: head--
**Output:ptrLastPos
**return: 链表中共有几项,0--空表,>0项数
********************************************************************/
PROC *  FindLastPos(PROC *head)
{
    PROC *ptrTmp,*ptrTmpOld;
    if(head==NULL)
        return NULL;    //空表
    ptrTmp=head;
    ptrTmpOld=head;
    while(ptrTmp!=NULL)
    {
        ptrTmpOld=ptrTmp;
        ptrTmp=ptrTmp->ptrNextProc;
    }
    //现在ptrTmpOld指向链表最后一个位置
    return ptrTmpOld;
}

/*******************************************************************
**Function:
**Input: head--
     rp--要找的指针
**Output:ptrPos-指向rp的前一个项的指针
    如图:   ptrPos->A->B
            rp->B
**return: 链表中第几项,-1--空表,0,第一项,1--第二项...
********************************************************************/
PROC * FindProcPos(PROC *head,PROC *rp,int *cnt)
{
    PROC *ptrTmp,*ptrTmpOld;
    *cnt=-1;
    if(head==NULL)
        return NULL;    //空表,ERR
    *cnt=0;
    ptrTmp=head;
    ptrTmpOld=head;
    while(ptrTmp!=rp)
    {
        (*cnt)+=1;
        ptrTmpOld=ptrTmp;
        ptrTmp=ptrTmp->ptrNextProc;
    }
    
    return ptrTmpOld;
}

/*******************************************************************
**Function:
**Input: head--
        pProc--要加的进程指针
**Output:
    none
**return: 
********************************************************************/
PROC *  AddLinkToProcLastPos(PROC *head,PROC *pProc)
{
    PROC *ptrTmp;
    ptrTmp=FindLastPos(head);
    if(ptrTmp==NULL)
        return NULL;
        
        //加入到尾部
    ptrTmp->ptrNextProc=pProc;
    pProc->ptrNextProc=NULL;
    return pProc;
}
/*******************************************************************
**Function:
**Input: head--
        pProc--要删的进程指针
**Output:
    none
**return: <0 空表
          =0 在第一项
          >0 成功
********************************************************************/
int RemoveProcFromProcLink(PROC *head,PROC *pProc)
{
    int i;
    PROC * ptrTmpProc;
    ptrTmpProc=FindProcPos(head,pProc,&i);
    if(i<0) return i; //空表
    if(i==0)
    {   //删除第一个
        head=pProc->ptrNextProc;
    }else
    {  //删除rp所指向的项
        ptrTmpProc->ptrNextProc=pProc->ptrNextProc;
    }
    return i;
}

#ifdef VC
void InitTaskRdy(void)
{
    PROC *ptrTmpOld;
    int i;
    InitTaskRdyPtrToNULL();
//  ptrTaskRdy[0]=&Proc[0]; //idle1
//  ptrServerRdy=&Proc[0];  //idle2
    Proc[0].priority=PROC_PRIO;//SERVER_PRIO;

//  ptrProcRdy= &Proc[1];       //idle3
    Proc[1].priority=PROC_PRIO;
    ready(&Proc[0]);
    ready(&Proc[1]);
//  ptrIdle= &Proc[2];  //Idle3 will run forever
    Proc[2].priority=PROC_PRIO;
    ready(&Proc[2]);
    unready(&Proc[0]);
    ready(&Proc[0]);
    unready(&Proc[0]);
    ready(&Proc[0]);
    unready(&Proc[0]);

    ptrTmpOld=FindLastPos(ptrProcRdy);
        SendOneChar(1,'0');
    for(;;);

}

void main(void)
{
    InitTaskRdy();
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -