写在前面:
由于时间的不足与学习的碎片化,写博客变得有些奢侈。
但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。
既然如此
不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录,记录笔者认为最通俗、最有帮助的资料,并尽量总结几句话指明本质,以便于日后搜索起来更加容易。
标题的结构如下:“类型”:“知识点”——“简短的解释”
部分内容由于保密协议无法上传。
点击此处进入学习日记的总目录
2024.03.29:UCOSIII第二十六节:任务的设计要点
四十、UCOSIII:任务的设计要点
作为一个嵌入式开发人员,要对自己设计的嵌入式系统要了如指掌,任务的优先级信息,任务与中断的处理,任务的运行时间、逻辑、状态等都要知道, 才能设计出好的系统。所以,在设计的时候需要根据需求制定框架。
在设计之初就应该考虑下面几点因素:任务运行的上下文环境、任务的执行时间合理设计。
1、任务运行的上下文环境
μC/OS中程序运行的上下文包括:
- 中断服务函数。
- 普通任务。
- 空闲任务。
1. 中断服务函数
中断服务函数是一种需要特别注意的上下文环境,它运行在非任务的执行环境下(一般为芯片的一种特殊运行模式(也被称作特权模式))。
在这个上下文环境中不能使用挂起当前任务的操作,不允许调用任何会阻塞运行的API函数接口。
另外需要注意的是,中断服务程序最好保持精简短小, 快进快出,一般在中断服务函数中只做标记事件的发生,然后通知任务,让对应任务去执行相关处理。
因为中断服务函数的优先级高于任何优先级的任务, 如果中断处理时间过长,将会导致整个系统的任务无法正常运行。
所以在设计的时候必须考虑中断的频率、中断的处理时间等重要因素, 以便配合对应中断处理任务的工作。
μC/OS支持中断延迟发布,使得原本在中断中发布的信息变成任务级发布。
这样会使得中断服务函数的处理更加快速,屏蔽中断的时间更短, 这样子能快速响应其他的中断,真正称得上实时操作系统。
2. 任务
任务看似没有什么限制程序执行的因素,似乎所有的操作都可以执行。
但是做为一个优先级明确的实时系统,如果一个任务中的程序出现了死循环操作 (此处的死循环是指没有阻塞机制的任务循环体),那么比这个任务优先级低的任务都将无法执行。当然也包括了空闲任务,因为死循环的时候, 任务不会主动让出CPU。
低优先级的任务是不可能得到CPU的使用权的,而高优先级的任务就可以抢占CPU。
这个情况在实时操作系统中是必须注意的一点, 所以在任务中不允许出现死循环。
如果一个任务只有就绪态而无阻塞态,势必会影响到其他低优先级任务的执行,所以在进行任务设计时, 就应该保证任务在不活跃的时候,任务可以进入阻塞态以交出CPU使用权,这就需要我们自己明确知道什么情况下让任务进入阻塞态, 保证低优先级任务可以正常运行。
在实际设计中,一般会将紧急的处理事件的任务优先级设置得高一些。
3. 空闲任务:
空闲任务(idle任务)是μC/OS系统中没有其他工作进行时自动进入的系统任务。
因为处理器总是需要代码来执行——所以至少要有一个任务处于运行态。
μC/OS为了保证这一点,当调用OSInit()函数进行系统初始化时,系统会自动创建一个空闲任务,空闲任务是一个非常短小的循环。
用户可以通过空闲任务钩子方式,在空闲任务上钩入自己的功能函数。
通常这个空闲任务钩子能够完成一些额外的特殊功能,例如系统运行状态的指示,系统省电模式等。
空闲任务是唯一一个不允许出现阻塞情况的任务,因为μC/OS需要保证系统永远都有一个可运行的任务。
对于空闲任务钩子上挂接的空闲钩子函数,它应该满足以下的条件:
- 永远不会挂起空闲任务;
- 不应该陷入死循环,需要留出部分时间用于统计系统的运行状态等。
4. 任务的执行时间
任务的执行时间一般是指两个方面。
一是任务从开始到结束的时间。
二是任务的周期。
在系统设计的时候这两个时间候我们都需要考虑。
例如,对于事件A对应的服务任务Ta,系统要求的实时响应指标是10ms,而Ta的最大运行时间是1ms, 那么10ms就是任务Ta的周期了,1ms则是任务的运行时间,简单来说任务Ta在10ms内完成对事件A的响应即可。
此时,系统中还存在着以50ms为周期的另一任务Tb,它每次运行的最大时间长度是100us。
在这种情况下,即使把任务Tb的优先级设置比Ta更高,对系统的实时性指标也没什么影响,因为即使在Ta的运行过程中,Tb抢占了Ta的资源,等到Tb执行完毕,消耗的时间也只不过是100us,还是在事件A规定的响应时间内(10ms),Ta能够安全完成对事件A的响应。
但是假如系统中还存在任务Tc,其运行时间为20ms,假如将Tc的优先级设置比Ta更高,那么在Ta运行的时候,突然间被Tc打断,等到Tc执行完毕,那Ta已经错过对事件A(10ms)的响应了,这是不允许的。
所以在我们设计的时候,必须考虑任务的时间,一般来说处理时间更短的任务优先级应设置更高一些。