实验二 任务的基本管理
1,理解任务管理的基本原理,了解任务的各个基本状态及其变迁过程;
2,掌握 uC/OS-II 中任务管理的基本方法(创建、启动、挂起、解挂任务);
3,熟练使用 uC/OS-II 任务管理的基本系统调用。
二、实验原理
为了展现任务的各种基本状态及其变迁过程,本实验设计了 Task0、Task1 两个任务:任务 Task0 不断地挂起自己,再被任务 Task1 解挂,两个任务不断地切换执行。通过本实验,读者可以清晰地了解到任务在各个时刻的状态以及状态变迁的原因。
第一部分:任务运行流程
(1)系统经历一系列的初始化过程后进boot_card()函数,在其中调用 ucBsp_init()进行板级初始化后,调用 main()函数;
(2)main()函数调用 OSInit()函数对 uC/OS-II 内核进行初始化,调用 OSTaskCreate 创建起始任务 TaskStart;
(3)main()函数调用函数 OSStart()启动 uC/OS-II 内核的运行,开始多任务的调度,执行当前优先级最高的就绪任务 TaskStart;
(4)TaskStart 完成如下工作:
a、安装时钟中断并初始化时钟,创建 2 个应用任务;
b、挂起自己(不再被其它任务唤醒),系统切换到当前优先级最高的就绪任task0
之后整个系统的运行流程如下:
a,t1 时刻,Task0 开始执行,它运行到 t2 时刻挂起自己;
b,t2 时刻,系统调度处于就绪状态的优先级最高任务 Task1 执行,它在 t3 时刻唤醒Task0,后者由于优先级较高而抢占 CPU;
c,Task0 执行到 t4 时刻又挂起自己,内核调度 Task1 执行;
d,Task1 运行至 t5 时刻再度唤醒 Task0;
e,……
第二部分:任务描述
一个任务通常是一个无限的循环 ,由于任务的执行是由操作系统内核调度的,因此任务是绝不会返回的,其返回参数必须定义成 void。在μC/OS-Ⅱ中,当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的 CPU 使用权就会被抢占,高优先级任务会立刻得到 CPU 的控制权(在系统允许调度和任务切换的前提下)。μC/OS-Ⅱ可以管理多达 64 个任务,但目前版本的μC/OS-Ⅱ有两个任务已经被系统占用了(即空闲任务和统计任务)。必须给每个任务赋以不同的优先级,任务的优先级号就是任务编号(ID),优先级可以从 0 到 OS_LOWEST_PR10-2。优先级号越低,任务的优先级越高。μC/OS-Ⅱ总是运行进入就绪态的优先级最高的任务。
第三部分:函数说明
系统启动后,经历一系列的初始化过程,进入 main()函数,这是我们编写实现应用程序的起点。首先需要在 main()函数里创建起始任务 TaskStart:
OSTaskCreate(TaskStart, (void *)0, &TaskStartStk[TASK_STK_SIZE - 1], 4);
TaskStart 任务负责安装操作系统的时钟中断服务例程、初始化操作系统时钟,并创建所有的应用任务。TaskStart 任务完成创建任务后将自己挂起,操作系统将调度当前优先级最高的应用任务Task0 运行。
OSTaskCreate()建立一个新任务。任务的建立可以在多任务环境启动之前,也可以在正在运行的任务中建立。中断处理程序中不能建立任务。一个任务必须为无限循环结构,且不能有返回点。
函数原型为:INT8U OSTaskCreate( void (*task)(void *pd),void *pdata,OS_STK *ptos,INT8U prio);
OSTaskSuspend ()无条件挂起一个任务。调用此函数的任务也可以传递参数OS_PRIO_SELF,挂起调用任务本身。当前任务挂起后,只有其他任务才能唤醒。任务挂起后,系统会重新进行任务调度,运行下一个优先级最高的就绪任务。唤醒挂起任务需要调用函数 OSTaskResume ()。任务的挂起是可以叠加到其他操作上的。例如,任务被挂起时正在进行延时操作,那么任务的唤醒就需要两个条件:延时的结束以及其他任务的唤醒操作。又如,任务被挂起时正在等待信号量,当任务从信号量的等待对列中清除后也不能立即运行,而必须等到被唤醒后。
函数原型:INT8U OSTaskSuspend ( INT8U prio);
OSTaskResume()唤醒一个用OSTaskSuspend()函数挂起的任务。OSTaskResume()也是唯一能“解挂”挂起任务的函数。
三、实验内容
程序启动具有三个不同优先级的任务:Task0,Task1,Task2,完成任务的挂起和被唤醒的系列动作。优先级分别为5,6(学号),7。Task0优先级最高。
在本次实验中,可以分为三种情况进行:
第一种情况:Task0不进行延时
输出效果为:
结果:Task0,Task1,Task2交替运行。
第三种情况:Task0进行延时300
输出效果为:
结果:Task1先运行,然后Task2运行,接着才是Task0,且Task0运行两次
因为300=150+150。从而造成了类似于优先级反转的现象,但又不是优先级反转。
第三种情况:Task0进行延时350
输出效果为:
结果:Task1先运行,然后Task2运行,接着便按照Task0,Task1,Task2的顺序循环下去。因为300>150+150。从而在系统刚运行时,造成了类似于优先级反转的现象,但又不是优先级反转。
四、实验总结
在进行试验时,应该注重一下程序中使用的函数以及函数的参数、返回值。这样便于理解程序,达到试验效果。比如: 在程序中 OSTaskSuspend()和 OSTaskResume ()应该成对使用。用 OSTaskSuspend()挂起的任务只能用 OSTaskResume ()来唤醒。另外,在本次实验中,还尝试修改Task0的延时时间,观察会出现什么效果。