(1)设计一个只有一个任务MyTask的应用程序。
(2)在(1)的任务MyTask中再创建一个任务YourTask。
要求当任务YourTask运行20次后,挂起任务MyTask;当任务YourTask运行40次后,恢复任务MyTask。
要求任务MyTask和任务YourTask运行一段时间后,使任务MyTask能删除任务YourTask。
流程图:
程序:
#include "includes.h"
#define TASK_STK_SIZE 512
OS_STK MyTaskStk[TASK_STK_SIZE];
OS_STK YourTaskStk[TASK_STK_SIZE];
INT16S key;
INT8U x=0,y=0,z=0;
void MyTask(void*data);
void YourTask(void*data);
char *ss;
char s[4]={'|','\\','-','/'};
void main()
{
OSInit();
PC_DOSSaveReturn();
PC_VectSet(uCOS,OSCtxSw);
OSTaskCreate(MyTask,0,&MyTaskStk[TASK_STK_SIZE-1],0);
OSStart();
}
void MyTask(void*pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata=pdata;
OS_ENTER_CRITICAL();
PC_VectSet(0x08,OSTickISR);
PC_SetTickRate(OS_TICKS_PER_SEC);
OS_EXIT_CRITICAL();
OSTaskCreate(YourTask,0,&YourTaskStk[TASK_STK_SIZE-1],1);
OSStatInit();
for(;;)
{
ss="MyTask:";
PC_DispStr(1,3,ss,DISP_FGND_BLACK+DISP_FGND_WHITE);
z=(z+1)%4;
PC_DispChar(12,3,s[z],DISP_BGND_BLACK+DISP_FGND_WHITE);
if(y==60)
{
while(OSTaskDelReq(1)!=OS_TASK_NOT_EXIST)
{
ss="MyTask:I ask YourTask to delete itself!";
PC_DispStr(10,11,ss,DISP_FGND_BLACK+DISP_FGND_WHITE);
OSTimeDly(1);
}
}
if(PC_GetKey(&key)==TRUE)
{
if(key==0x1B)
{
PC_DOSReturn;
}
}
OSTimeDlyHMSM(0,0,0,200);
}
}
void YourTask(void*pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
for(;;)
{
ss="YourTask:";
PC_DispStr(1,5,ss,DISP_FGND_BLACK+DISP_FGND_WHITE);
x=(x+1)%4;
PC_DispChar(12,5,s[x],DISP_BGND_BLACK+DISP_FGND_WHITE);
y++;
if(y==20)
{
ss="YourTask: Suspend MyTask!";
PC_DispStr(10,7,ss,DISP_FGND_BLACK+DISP_FGND_WHITE);
OSTaskSuspend(0);
}
if(y==40)
{
ss="YourTask: Resume MyTask!";
PC_DispStr(10,9,ss,DISP_FGND_BLACK+DISP_FGND_WHITE);
OSTaskResume(0);
}
if(OSTaskDelReq(OS_PRIO_SELF)==OS_TASK_DEL_REQ)
{
ss="YouTask:I need to delete myself!";
PC_DispStr(10,13,ss,DISP_FGND_WHITE+DISP_BGND_BLACK);
OSTimeDlyHMSM(0,0,5,0);
ss="YouTask:I have deleted myself!";
PC_DispStr(10,15,ss,DISP_FGND_WHITE+DISP_BGND_BLACK);
OSTaskDel(OS_PRIO_SELF);
}
if(PC_GetKey(&key)==TRUE)
{
if(key==0x1B)
{
PC_DOSReturn;
}
}
OSTimeDlyHMSM(0,0,0,200);
}
}
结果:
所用到的µC/OS-II相关函数:
OSTaskCreate()
建立一个新任务。任务的建立可以在多任务环境启动之前,也可以在正在运行的任务中建立。中断处理程序中不能建立任务。一个任务可以为无限循环的结构。
函数原型:INT8U OSTaskCreate(void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio);参数说明:task是指向任务代码首地址的指针。
Pdata指向一个数据结构,该结构用来在建立任务时向任务传递参数。
返回值:
OSTaskCreate()的返回值为下述之一:
- OS_NO_ERR:函数调用成功。
- OS_PRIO_EXIST:具有该优先级的任务已经存在。
- OS_PRIO_INVALID:参数指定的优先级大于OS_LOWEST_PRIO。
- OS_NO_MORE_TCB:系统中没有OS_TCB可以分配给任务了。
OSTaskSuspend()
无条件挂起一个任务。调用此函数的任务也可以传递参数OS_PRIO_SELF,挂起调用任务本身。当前任务挂起后,只有其他任务才能唤醒被挂起的任务。任务挂起后,系统会重新进行任务调度,运行下一个优先级最高的就绪任务。唤醒挂起任务需要调用函数OSTaskResume()。
任务的挂起是可以叠加到其他操作上的。例如,任务被挂起时正在进行延时操作,那么任务的唤醒就需要两个条件:延时的结束以及其他任务的唤醒操作。又如,任务被挂起时正在等待信号量,当任务从信号量的等待对列中清除后也不能立即运行,而必须等到被唤醒后。
函数原型:INT8U OSTaskSuspend ( INT8U prio);
参数说明:prio为指定要获取挂起的任务优先级,也可以指定参数OS_PRIO_SELF,挂起任务本身。此时,下一个优先级最高的就绪任务将运行。
返回值:
OSTaskSuspend()的返回值为下述之一:
- OS_NO_ERR:函数调用成功。
- OS_TASK_ SUSPEND_IDLE:试图挂起μC/OS-II中的空闲任务(Idle task)。此为非法操作。
- OS_PRIO_INVALID:参数指定的优先级大于OS_LOWEST_PRIO或没有设定OS_PRIO_SELF的值。
- OS_TASK_ SUSPEND _PRIO:要挂起的任务不存在。
OSTaskResume()
唤醒一个用OSTaskSuspend()函数挂起的任务。OSTaskResume()也是唯一能“解挂”挂起任务的函数。
函数原型:INT8U OSTaskResume ( INT8U prio);
参数说明:prio指定要唤醒任务的优先级。
返回值:
OSTaskResume ()的返回值为下述之一:
- OS_NO_ERR:函数调用成功。
- OS_TASK_RESUME_PRIO:要唤醒的任务不存在。
- OS_TASK_NOT_SUSPENDED:要唤醒的任务不在挂起状态。
- OS_PRIO_INVALID:参数指定的优先级大于或等于OS_LOWEST_PRIO。
OSTaskDelReq()
请求删除任务。
函数原型:NT8U OSTaskDelReq ( INT8U prio);
参数说明:prio指定要删除任务的优先级。
返回值:
OSTaskDelReq()的返回值为下述之一:
- OS_NO_ERR:删除任务请求已经注册。
- OS_TASK_NOT_EXIST:任务已经被删除。
- OS_TASK_DEL_IDLE:不能删除空闲任务。
- OS_PRIO_INVALID:无效优先级。
- OS_TASK_DEL_REQ:请求删除任务。
OSTaskDel()
删除一个任务。
函数原型:NT8U OSTaskDel( INT8U prio);
参数说明:prio指定要删除任务的优先级。
返回值:
OSTaskDel()的返回值为下述之一:
- OS_NO_ERR:删除任务成功。
- OS_TASK_DEL_IDLE:不能删除空闲任务。
- OS_PRIO_INVALID:无效优先级。
- OS_TASK_DEL_ERR:请求删除任务不存在。
- OS_TASK_DEL_ISR:在ISR中不允许删除任务。