协作式多任务操作系统
//任务句柄的的定义( 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 (); }