μC/OS-II的多任务系统实时性分析与优先级分配
,这显然不够。可通过优化GUI的驱动,去掉LCD的显示缓冲区,增加4 KB的RAM,以满足系统需要。
3 可变任务栈和任务划分
3.1 可变大小任务栈
一般来说,一个嵌入式系统中不会建立60个以上的任务。从简单的角度考虑,应用μC/OS-II时,建立的所有任务均驻留不删除,使用足够大并且同样大小的堆栈。这种处理任务的方法会对内存数量提出较高要求。例如50个任务,每个任务栈均为128字节,则需要6 KB的RAM。
本着这样一个原则来改进任务划分:不需要驻留的任务运行完毕即删除,可以自身删除,也可以在别的任务里删除。这种任务处理不仅可以重用任务优先级,还可以重用任务堆栈,并且减少同时运行的任务数量。
删除任务的办法不仅可获得共享的任务栈资源,而且也是一个方便中止某些应用程序的手段,前面提及的任何测试阶段按Exit键退出所有测试的动作,就可以依靠删除任务来实现。
把任务看作有大小的,这里的"大小"指需要"重入"到任务堆栈的变量的数量。如果每一个任务都使用相同大小的任务栈,对小任务而言显然是在浪费宝贵的RAM,大小可变的任务栈才是经济合理的。
首先,在os_cfg.h头文件中增加大、小两个宏参数,如果需要更多不同的栈大小,还可以继续增加参数。
#define MaxStkSize128//大任务栈
#define MinStkSize80//小任务栈
然后定义任务栈时使用它们:
OS_STK TaskDelStk1[MinStkSize];
OS_STK TaskDelStk2[MaxStkSize];
TaskDelStk1和TaskDelStk2是两个可删除任务所使用的任务栈,一个80字节,另一个128字节。
接下来是关键,要在任务堆栈初始化函数OSTaskStkInit中进行处理:定义一个全局整型变量STK_SIZE,创建任务前给它赋值,任务创建时执行的OSTaskStkInit函数用它来初始化模拟栈的长度。
修改前,OSTaskStkInit中的?C_XBP仿真堆栈指针(即模拟栈指针)的初始化语句如下:
*stk++ = (INT16U) (ptos + MaxStkSize) >> 8;//MaxStkSize是固定的栈长度
*stk++ = (INT16U) (ptos + MaxStkSize) & 0xFF;
注意:ptos是任务栈栈底,模拟栈从任务堆栈的另一头开始。
修改后变为:
*stk++ = (INT16U) (ptos + STK_SIZE) >> 8;//指针高8位
*stk++ = (INT16U) (ptos + STK_SIZE) & 0xFF;//指针低8位
创建任务前要给STK_SIZE赋予堆栈定义匹配的栈长度值,否则,会因为堆栈不能正确初始化导致任务崩溃。不同大小的任务栈结构如图2所示,可以看出区别在于模拟栈不同。
图2 可变大小任务栈结构
利用可变大小任务栈创建一个小堆栈任务,示例如下:
STK_SIZE=MinStkSize;//提供堆栈大小值
/*创建带TimeLimit参数的,分配有任务栈TaskDelStk1,优先级为10的任务OverTime*/
OSTaskCreate(OverTime,(void*)&TimeLimit, &TaskDelStk1[0],10);
3.2 系统任务划分
用户任务分为两类: 一类任务是常驻任务,即创建后不用删除的任务;另一类是可删除任务,运行时建立,运行完删除,该任务资源又可用来创建新的任务。
4 任务优先级分配
优先级的合理分配围绕实时性要求进行,因为可用优先级较多,所以任务优先级之间可取较大间隔。这样当有更多的任务加入时,能安排在这些间隔中,不用改变已有任务的优先级。本系统中优先级关系可以按由高到低顺序依次排列: 键盘扫描任务,超时检测任务, A/D扫描转换任务,主任务,各通道测试任务,数据打印和传送任务,温度检测任务,日期时间显示任务,如图3所示。
图3 任务关系示意图
常驻任务一般是固定优先级,而可删除任务每一次创建时却能够对应不同的任务函数和优先级,且使用同一个任务栈。
一个任务函数可用于多个任务,这种"重用"的特性在获得任务并行性的同时,最大限度地节约了代码。本系统只有一个测试函数,却构成了4个并行的通道任务。这些任务都是进入测试菜单后随着各自通道键被按下后在主任务中创建的,复用的4个测试函数接受任务创建时主任务传递过来的参数,为本通道的计算、显示、数据存储等一系列工作服务。
5 资源共享的处理
ADC0、LCD、打印机和串口等资源被4个测试任务所共享。资源共享有一些经典的方法(如信号量、全局变量等),需要根据实际需求灵活运用。
本系统的处理如下:
① 对于ADC0,在A/D扫描转换任务中每0.1 s轮流扫描4个通道一次,产生4个邮箱消息发往各自通道任务,以读取对应的转换结果。0.1 s的精确定时由定时器中断获得,中断服务发出信号量启动AD任务。一次扫描完成后A/D扫描转换任务挂起,直至下一次信号量到来。
② 对于LCD,情况要复杂一些,每个测
- μC/OS-II下通用驱动框架的设计与实现(07-23)
- 基于μC/OS-II嵌入式系统的低功耗开发(07-08)
- 基于S3C44B0X+μcLinux的嵌入式以太网设计(07-08)
- 蓄电池化成控制系统中显示功能的实现(11-05)
- 嵌入式实时操作系统μC/OS-II 在P89V51RD2中的移植(04-09)
- LPC2292的伪中断与伪中断处理(03-25)