UCOS 等 RTOS的任务划分原则(转载整理)

参考一:
划分任务的话有几个原则:
1、根据外设类型:SPI一个,串口一个;
2、按照任务的优先级分:比如AD采集最优先,单独做一个任务,提高优先级;其他通讯任务缓一缓没关系,合成一个任务,优先级低一些。
3、按工作流程分:比如分阶段的,按阶段分。我现在做的项目偏向这种划分

参考二
任务划分有3个原则,分别介绍如下。
  2.1 原则1
  原则1是将同一个外设的访问放在一个任务中。
  对每个独立的硬件(例如串行通信端口)进行操作的驱动程序段放在一个任务中。也就是说,要想对某个设备资源进行操作,只有依靠执行相应的任务来实现。这样无论何时切换任务,都不会对任何独立的“外设”造成影响。
  这样做能够避免嵌入式操作系统的特殊问题——资源冲突和重入问题,而且利于系统维护与升级。各个任务之间要实现通信,可以调用os_send_signal函数及全局变量来实现。
  所谓“资源冲突”,就是任务A在访问某个资源时,恰好发生了任务切换——由任务A切换到任务B,任务B也访问这个资源且改变了它的状态,这样当再次执行任务A时,就可能发生冲突或带来不确定性。而所谓“重入”,是指假设任务A在运行某个函数,发生任务切换后,任务B也运行这个函数,这样就会破坏任务A执行这个函数时的现场,从而可能导致任务A执行函数时结果不正确。这种问题尤其容易出现在串行接口器件的操作中,例如串口,串行的AD、DA器件等。
  2.2 原则2
  原则2是要通过任务分割提高系统的实时性。
  在嵌入式多任务实时系统中,任务是指一个程序分段。这个程序分段被操作系统当作一个基本单元来调度。典型地,每个任务都是一个无限的循环。
  RTOS本质上就是嵌入的实时内核,它负责管理各个任务,或者说是为每个任务分配CPU时间,并且负责任务之间的通信。实时内核可分为可剥夺型和不可剥夺型两类。因此,按照所使用内核的不同,嵌入式实时系统也可分为两类:使用不可剥夺型内核的嵌入式实时系统和使用可剥夺型内核的嵌入式实时系统。
  2.2.1 长任务的定义
  在RTOS中,长任务就是指整个任务的执行时间较长,超出了RTOS中其他某一个或某几个任务的实时要求容限,而对整个RTOS的实时性构成威胁的那些任务。需要注意的是,长任务与复杂任务不能混淆,复杂任务的执行时间不一定长,简单任务也可能会构成长任务。
  2.2.2 长任务对RTOS的影响
  当使用可剥夺型实时内核时,长任务由于执行的时间较长,因而更容易被高优先级的任务打断;一旦高优先级的任务进入了就绪状态,当前任务的CPU使用权就被剥夺了,或者说任务被挂起了,那个高优先级的任务立刻得到了CPU的控制权。这样会出现两个问题:一是长任务可能在一次执行的过程中被频繁打断,长时间得不到一次完整的执行;二是长任务被打断时,可能要保存大量的现场信息,其目的是为了保证在高优先级任务执行完返回后,长任务能得以继续执行。然而,这样做要占用一定的系统资源,同时保存现场本身也是要占用CPU时间的,因此,实时性也会下降。
  当使用不可剥夺型实时内核时,长任务对RTOS的影响更为明显,因为在这种内核中,任务的响应时间取决于最长的任务执行时间。也就是说,由于长任务的存在,任务的响应时间要变长。其结果是CPU长时间停留在长任务中,其他任务得不到实时的响应,甚至根本得不到执行,系统的实时性势必要下降。
  总之,无论是使用可剥夺型内核,还是使用不可剥夺型内核,长任务都会对RTOS构成严重的威胁。
  2.2.3 长任务问题的解决方法
  解决长任务问题最有效的途径是进行任务分割。所谓“任务分割”是指将影响系统实时性的长任务分割成若干个小任务。这样单个任务的执行时间变短,系统的任务响应时间变短,实时性得以提高。
2.3 原则3
    原则3是要将软件工程中的“解耦原则”用于任务划分。
    可以采用软件工程中的解耦原则对应用程序进行任务的划分。任务之间的耦合是影响软件复杂程度的一个重要因素,应该采取下述设计原则:尽量使用数据耦合,少用控制耦合和特征耦合,限制公共环境耦合的范围,完全不用内容耦合。具体方法可参见软件工程方面的书籍,

参考三
任务优先级分配方案
对于初学者,有时候会纠结任务优先级设置为多少合适,因为任务优先级设置多少是没有标准的。对
于这个问题,我们这里为大家推荐一个标准,任务优先级设置推荐方式如下图 13.1 所示:

  UCOS 等 RTOS的任务划分原则(转载整理)
 IRQ 任务:IRQ 任务是指通过中断服务程序进行触发的任务,此类任务应该设置为所有任务里面优先级最高的。

 高优先级后台任务:比如按键检测,触摸检测,USB 消息处理,串口消息处理等,都可以归为这一类任务。

 低优先级的时间片调度任务:比如 emWin 的界面显示,LED 数码管的显示等不需要实时执行的都可以归为这一类任务。 实际应用中用户不必拘泥于将这些任务都设置为优先级 1 的同优先级任务,可以设置多个优先级,只需注意这类任务不需要高实时性。
 空闲任务:空闲任务是系统任务。
 特别注意:IRQ 任务和高优先级任务必须设置为阻塞式(调用消息等待或者延迟等函数即可),只有
这样,高优先级任务才会释放 CPU 的使用权,,从而低优先级任务才有机会得到执行。
这里的优先级分配方案是我们推荐的一种方式,实际项目也可以不采用这种方法。 调试出适合项目需求的才是最好的。 

参考四:
1、以CPU为中心,将和IO口相关的功能划分成若干个独立的任务
2、发现“关键”功能(关键任务)将关键功能分离出来,交给一个独立的任务或者
ISR来执行,剩余的部分交给另外一个任务去实现,两者之间通过通讯机制来实现。
3、发现“紧迫”功能,将紧迫功能分离出来,交给一个独立的任务或者ISR来执行
,剩余的部分交给另外一个任务去实现,两者之间通过通讯机制来实现沟通。
4、对于既“关键”又“紧迫”的任务,按紧迫任务去执行。
5、将消耗机时的数据处理部分分离出来,通过一个较低优先级的任务实现其功能。。
6、将关系联系紧密的任务合并在一起,有助于节省系统沟通之间的开销
7、将由相同事件触发的若干功能组合成一个任务,从而免除事件分发机制带来的
额外系统开销
8、将运行周期相同的功能组合在一起成为一个任务,从而免除事件分发机制带来的
额外的系统开销。
9、将若干按固定顺序执行的功能组合成为一个任务,从而免除同步接力通讯的麻烦。

几点重要的解释:
关键任务:
关键性是指某种特殊功能在应用系统中的重要性,如果这种功能不能正常实现,将造成
严重的影响,甚至引发灾难性的后果。包含“关键”功能的任务称为“关键任务”
关键任务必须得到运行机会,即使遗漏执行一次也不行

紧迫任务:
“紧迫性”是指某种功能必须在规定的时间内得到运行权(及时运行),并且要在
规定的时间内完成。也就是说有严格的实时性

数据处理任务:
用户应用程序中消耗系统时间最多的就是数据处理单元,  数据处理单元通常不止
一个,他们为不同的功能服务,应该将这些单元划分出来,交给不同的任务,并将
这些任务赋予较低的优先级,以便使用其他任务剩余的机时。

运行周期相同的任务:
将周期相同的功能组合在一起封装成一个任务,就可以避免一个时间事件触发几个
任务,省去“事件分发”的操作与他们之间通信。