uC/OS-II中的任务
1 任务的基本概念
uC/OS-II操作系统内核的主要任务就是对任务进行管理和调度。
在设计一个较为复杂的应用程序时,通常把一个大型任务分解成多个小任务,这样可以将问题分而治之,简化问题的复杂程度,也使程序的维护变得简单。
用户任务和系统任务:
1. 用户任务:由应用程序设计者编写,用以解决应用问题
2. 系统任务:由操作系统提供,服务于用户任务
uC/OS-IIjiang每个任务作为一个节点,把它们连接成一个任务链表
1.1 任务的状态
- 任务的5中状态
- 睡眠态:
- 任务以代码的形式驻留在程序空间(ROM或RAM),还没有交给操作系统管理(任务没有被配备任务控制块或被剥夺了任务控制块时的状态)
- 就绪态:
- 系统为任务配备了任务控制块且在任务就绪表中进行了就绪等级,则任务具备了运行的充分条件
- 运行态
- 处于就绪态的任务经过调度判断获取了CPU使用权,则任务会运行,从而进入运行态
- 等待态
- 正在运行的任务,需要等待一段时间或需要等待一个时间发生再运行时,该任务就会把CPU的使用全让给其他任务而进入等待态
- 中断服务态
- 一个正在运行的任务被中断打断去执行中断服务程序,这时的任务的状态叫做中断服务态
- 睡眠态:
1.2 用户任务代码的一般结构
1.2.1 用户任务代码的一般结构
任务的执行代码通常时一个无限循环结构
void MyTask(void *pdata)
{
for(;;)
{
//可以被中断的用户代码
OS_ENTER_CRITICAL();//进入临界段(关中断)
//不可被中断的用户代码;
OS_EXIT_CRITICAL(); //退出临界段(开中断)
//可以被中断的用户代码;
}
}
1.2.2 用户应用程序的一般结构
用户任务是一个线程,它不是被主函数或其他函数调用的。主函数只负责创建和启动它们,而由操作系统负责来调度运行它们。
void MyTask1(void *pdata)
{
for(;;)
{
......
}
}
void MyTask2(void *pdata)
{
for(;;)
{
......
}
}
void main()
{
......
OSInit(); //初始化uC/OS-II
......
OSTaskCreate(MyTask1, ...); //创建用户任务1
OSTaskCreate(MyTask2, ...); //创建用户任务2
......
OSStart(); //启动任务
}
使用函数OSStart()启动了各任务之后,任务就交由操作系统来管理和调度了。
1.3 系统任务
uC/OS-II预定义了两个为应用程序服务的系统任务:空闲任务和统计任务。其中空闲任务时每个任务必须使用的,而统计任务则可以选择。
- 空闲任务
void OSTaskIdle(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata; //防止某些编译器报错
for(;;)
{
OS_ENTER_CRITICAL(); //关中断
OSdleCtr++; //计数
OS_EXIT_CRITICAL(); //开中断
}
}
uC/OS规定,一个用户应用程序必须使用这个空闲任务,而且这个任务不能用软件来删除。
- 统计任务
统计任务OSTaskStat(),每秒计算一次CPU在单位时间内使用的时间,并把计算结果以百分比的形式存放在变量OSCPUUsage中,以便应用程序通过访问它来了解CPU的使用率。
1.4 任务的优先权及优先级别
- uC/OS-II把任务的优先权分为64个级别,每个级别用一个数字表示。0表示最高优先级,数字越大优先级越低。
- 在OS+_CFG中可以通过定义LOWEST_PRIO的值,来说明应用程序中任务优先级别的数目。空闲任务总是最低优先级LOWEST_PRIO,统计任务总是LOWEST_PRIO-1,所以用户可用的优先级就是0~LOWEST_PRIO-2。
- 每个任务都具备唯一个优先级别,所以通常用任务的优先级别来作为任务的标识。
- 在使用系统函数OSTaskCreate()来创建任务时,用该函数的第4个参数prio来指定优先级
2 任务堆栈
为了满足任务切换和响应中断时保存CPU寄存器中的内容及存储任务私有数据的需要,每个任务都应该配有自己的堆栈。
2.1 任务堆栈的创建
typedef unsigned int OS_TSK;
#define TASK_STK_SIZE 512
OS_TSK TaskStk[TASK_STK_SIZE];
调用函数OSTaskCreate()来创建任务时,把数组指针传递给函数OSTaskCreate()中的堆栈栈顶参数ptos,就可以把该数组与任务关联起来而成为该任务的任务堆栈。
- 创建任务函数OSTaskCreate()的原型如下:
INT8U OSTaskCreate(
void (*task)(void *pd), //指向任务的指针
void *pdata, //传递给任务的参数
OS_STK *ptos, //任务堆栈栈顶指针
INT8U prio //指定任务优先级别
);
创建一个任务,堆栈长度为128字节,优先级为20,任务参数pdata的实参为myTaskAgu,实现如下: