协作式多任务操作系统

协作式多任务操作系统


复制代码
//任务句柄的的定义( tiny_os_51.h )
typedef char  TN_OS_HANDLE;



//任务状态字的定义
#define __TN_TASK_FLG_DEL         0x00        //任务被删除
#define __TN_TASK_FLG_RDY        0x01        //任务就绪

//任务控制块
struct tn_os_tcb
{
    jmp_buf        jbTaskContext;        //用于存储上下文信息
    unsigned char        ucTaskStat;        //任务状态子
};
typedef struct tn_os_tcb         TN_OS_TCB;        //TN_OS_TCB等效于struct tn_os_tcb

static data TN_OS_TCB        __GtcbTasks[ TN_OS_MAS_TASKS ];        //任务控制块的结构体数组

//注意了
__Gtcb_Tasks[ tnTask ].ucTaskStat = __TN_TASK_FLG_DEL        //使任务处于删除状态





//OS初始化( tiny_os_51_core.c )
static data TN_OS_TASK_HANDLE  __GthTaskCur;        //当前任务句柄

void tnOsInit ( void )
{
    TN_OS_TASK_HANDLE  tnTask;        //操作的任务

    for ( tnTask = 0; tnTask < TN_OS_MAX_TASKS; tnTask ++ )
    {
        __GtcbTasks[ tnTask ].ucTaskStat = __TN_TASK_FLG_DEL;        //使任务处于删除状态
    }

    __GthTaskCur = 0;        //初始化任务号为0
}




//创建任务( tiny_os_51_core.c )            注意了,这里的一个任务可以在操作系统启动( 即调用tnOsStart() )前创建
//                                        也可以在其他任务执行过程中创建,但任务不可以在中断服务程序来创建
TN_OS_TASK_HANDLE    tnOSTaskGreat ( 
                    
                    void ( *pfuncTask )( void ),        //指向任务函数的函数指针
                    idata unsigned char *pucStk            //指向任务堆栈的指针
                                                                
                                    )
{
    TN_OS_TASK_HANDLE  thRt;        //返回值


    //搜索是否有空闲的任务控制块
    for ( thRt = 0; thRt < TN_OS_MAX_TASKS; thRt ++ )
    {
        if ( __GtcbTasks[ thRt ].ucTaskStat == __TN_TASK_FLG_DEL )
        {
            
            //如果搜索到有空闲的TCB,则创建任务
            setTaskJmp ( pfuncTask, pucStk, __GtcbTask[ thRt ].jbTaskContext );
            __GtcbTasks[ thRt ].ucTaskStat = __TN_TASK_FLG_RDY;        //任务就绪

            return thRt;
        }    
    }

    return -1;            //如果没有空闲的TCB,则创建任务失败,即任务句柄的返回值为-1
}




//启动OS( tiny_os_51_core.c )
void tnOsStart ( void )
{
    longjmp ( __GtcbTasks[ 0 ].jbTaskContext );            //执行0号任务
}




//任务切换   任务切换的设计的思想:当发生任务切换时,首先搜索下一个将要执行的任务是否处于
//             就绪状态,如果是的话,则将当前正在运行的任务的上下文保存到该任务的TCB中,然后
//             再从相应的TCB中恢复下一个将要运行的上下文.如果所有的任务都未处于就绪状态,则
//             等待本任务知道就绪为止
void tnOsSched ( void )
{
    TN_OS_TASK_HANDLE tnTask;            //任务句柄即操作的任务
    char              cTmp1;
    TN_OS_TASK_HANDLE thTmp2;
    volatile data char *pucTmp3 = ( void * )0;

    thTmp2 = __GthTaskCur;                //首次运行时,__GthTaskCur为0

    //搜索下一个任务
    for ( thTask = 0; thTask < TN_OS_MAX_TASKS; tnTask ++ )
    {
        thTmp2 ++;                //首次运行时thTmp2 = 1
        if ( thTmp2 > TN_OS_MAX_TASKS )
        {
            thTmp2 = 0;
        }

        if ( ( __GtcbTask[ thTmp2 ].ucTaskStat & __TN_TASK_FLG_RDY ) != 0 )
        {
            cTmp1 = setjmp ( __GtcbTasks[ __GthTaskCur ].jbTaskContext );    //保存当前任务的上下文,cTtmp1 = 0
            
            if ( cTmp1 == 0 )        //如果cTmp1 = 0,往下执行
            {
                __GthTaskCur = thTmp2;        //更新当前任务句柄
                longjmp ( __GtcbTasks[ thTmp2 ].jbTaskContext );
            }                                                

            return;        //如果cTmp1 = 1,则返回函数
        }
    }

    //如果所有的任务都未就绪,则等待本任务就绪,相当于一般操纵系统的空闲任务
    pucTmp3 = ( volatile data char * )( &( __GtcbTasks[ thTmp2 ].ucTaskStat ) );
    while ( ( *pucTmp3 & __TN_TASK_FLG_RDY ) == 0 )        //任务未就绪,直到就绪为止
    {
    
    }
               
}





//删除任务( 句柄为-1时删除自身,并且要转换为真实的句柄在合法范围内,才能进行任务调度 )
void tnOSTaskDel ( TN_OS_TASK_HANDLE tnTask )
{
    //检查参数
    if ( thTask == -1 )
    {
        thTask = __Gth_TaskCur;                //转换为真实的句柄

        if ( thTask >= TN_OS_MAX_TASKS || thTask < 0 )            //检查参数是否合法
        {
            return;                           //不合法不执行
        }
    }

    __GtcbTasks[ thTask ].ucTaskStat = __TN_TASK_FLG_DEL;            //删除任务

    if ( thTask == GthTaskCur )                       //删除自身,则执行下一个任务
    {
        thOsSched();
    }
}
复制代码

 

 

举例:

复制代码
//协作式多任务操作系统范例

static idata unsigned char         __GucTaskStks[2][32];        //分配任务堆栈

static unsigned char     __GucTask0;        //任务0测试变量
static unsigned char     __GucTask1;        //任务1测试变量

void task0 ( void )
{
    while ( 1 )
    {
        __GucTask0 ++;

        tnOsSched ();
    }
}

void task1 ( void )
{
    while ( 1 )
    {
        __GucTask1 ++;

        tnOsSched ();
    }
}

void main ( void )
{
    tnOsInit ();
    tnOsTaskGreate ( task0, __GucTaskStks[0] );
    tnOsTaskGreate ( task1, __GucTaskStks[1] );
    tnOsStart ();
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值