μC/OS-II
操作系统内核一项主要的工作就是对任务进行管理和调度。与之相关的内容主要包括以下几点:
任务的基本概念,用户任务和系统任务;
任务代码、任务控制块和任务堆栈;
任务优先权及表示任务优先权的参数——优先级别;
任务就绪表结构及其操作;
任务切换及调度;
任务的创建、删除、挂起、恢复和查询;
μC/OS-II的初始化和启动。
任务的基本概念
从代码角度看,μC/OS-II的任务就是一个个函数,从任务的存储结构来看,μC/OS-II的任务又下图所示的三部分组成:任务程序代码(函数)、任务堆栈和任务控制块。
* μC/OS-II中所有的任务都属于线程。
μC/OS-II用任务控制块链表对任务进行管理,如图所示:
μC/OS-II的任务分两种:系统任务和用户任务。用户任务是为了解决应用问题而编写的而系统任务是为应用程序提供某种服务或为系统本身服务的。目前在μC/OS-II中,最多可以含有64个任务(汉系统任务和用户任务)。
μC/OS-II是为单核CPU设计的,某一时刻只能有一个任务占用CPU处在运行状态,其他任务只能处在其他状态,μC/OS-II系统中的任务状态如下图所示
各任务状态之间的切换如下图所示
一个典型的用户任务代码结构:1
2
3
4
5
6
7
8
9
10
11
12void MyTask(void *pdata){
while(1){
//可以被中断的用户代码
...
OS_ENTER_CRITICAL(); // 进入临界段(关中断)
//不可被中断的用户代码
...
OS_EXIT_CRITICAL(); //退出临界段(开中断)
//可以被中断的用户代码
...
}
}
用户应用程序的一般结构可参见下述代码段:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27void MyTask1(void *pdata){
while(1){
...
}
}
void MyTask2(void *pdata){
while(1){
...
}
}
void MyTask3(void *pdata){
while(1){
...
}
}
void main(){
...
OSInit(); //初始化μC/OS-II
...
OSTaskCreate(MyTask1, ...); //创建用户任务1
OSTaskCreate(MyTask2, ...); //创建用户任务2
OSTaskCreate(MyTask3, ...); //创建用户任务3
...
OSStart(); //启动μC/OS-II
...
}
考虑到没有用户任务执行的时候CPU不能停下来,所以μC/OS-II中必须有系统任务。μC/OS-II预定义了两个系统任务:空闲任务和统计任务。其中空闲任务是每个应用程序必须使用的,而统计任务则可以根据情况选择是否需要。
空闲任务就是为了防止CPU某时刻没有用户任务可执行而处于空闲状态,μC/OS-II提供了一个名为OSTaskIdle()的系统任务,代码如下:1
2
3
4
5
6
7
8
9
10
11
12void OSTaskIdle(void *pdata){
OS_CPU_SR cpu_sr;
pdata=pdata; //防止某些编译器报错
while(1){
OS_ENTER_CRITICAL(); //关中断
OSdleCtr++;
OS_EXIT_CRITICAL(); //开中断
}
}