利用可变大小任务栈创建一个小堆栈任务,示例如下:
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,情况要复杂一些,每个测试任务都要在LCD的各自区域显示,但是LCD不能实现2个以上位置同时进行显示处理,所以当涉及显示过程时需要禁止任务切换,否则会造成显示混乱。例如,当一个低优先级任务的显示工作还没有完成时,若发生了任务切换,则高优先级任务去进行另一个显示。当重新切换回低优先级任务后就没有办法继续未完的显示,因为显示位置已经被高优先级任务所改变。
③ 对于打印机和串口,也有类似的问题,不允许一个结果尚未打印完成又去打印另一个结果。禁止任务切换的办法不适合这里,因为打印和传送耗时比LCD显示长很多,禁止任务切换会影响到测试的实时性,它们单独建立后台任务的原因也在于此。
数据打印和传送任务循环扫描各个通道的请求服务标志,当标志有效时即为该通道服务,服务完毕清除该标志,因数据打印和传送任务的优先级较低而不会对其他测试任务造成任何影响。被服务的通道测试任务循环检测请求服务标志,检测到标志被清除后才可以继续下次测试,表示此次数据已经输出。其他高优先级测试任务不会影响打印过程,因为先检测到标志的通道独占资源,直至传送和打印完成后,打印任务才去检测下一个标志;高优先级任务的输出请求要等低优先级输出完毕才能得到响应,优先级反转在这里是正确的。
6 结论
本文从嵌入式系统的并行程序出发,结合实时性的要求,讨论了μC/OS-II操作系统环境下的任务划分和优先级确定的相关问题,提出了一些在μC/OS-II中用于减少资源耗用和同时运行的任务数量的改进措施。实践证明,这些措施可以充分发挥μC/OS-II小巧精悍的特点,提高程序代码的重用性,节约宝贵的RAM资源。
本系统与采用双通道测试、没有RTOS、采用前后台方式解决并行问题的方法比较[5],后者占用了54 KB代码,在人机界面和并行度上均不及前者。前者在加入了μC/OS-II和GUI,并能进行四通道测试的情况下,仅有59 KB代码;排除更大的汉字库容量后,实际代码大小几乎与原来相同,性能却有了很大的提高。
,μC/OS-II的多任务系统实时性分析与优先级分配