RTA-OS系列介绍-资源

RTA-OS系列介绍-资源,第1张

RTA-OS系列介绍-资源

本文框架
  • 1. 概述
    • 1.1 死锁与优先级置顶
    • 1.2 资源分类
  • 2. 资源的应用
    • 2.1 资源嵌套调用
    • 2.2 内部资源
    • 2.3 使用资源最小堆栈使用
      • 2.3.1 内部资源
      • 2.3.2 标准资源
    • 2.4 选择抢占控制机制
  • 3. 本章小结

1. 概述

本篇我们将继续讲述RTA-OS下的另一个部分-资源,在实际应用中对于需要在任务和ISR之间共享的硬件或数据的访问,低优先级任务或中断可能会由于其优先级较低而被高优先级抢占,共享数据部分可能被篡改,当高优先级执行完毕再回到低优先级任务继续执行时,就可能读取到的是被篡改后共享区域的值,使得系统不可靠且不安全。

为了提供对关键部分中引用的代码和数据的安全访问,需要确保系统中没有其他任务或2类ISR能够在关键部分抢占正在执行的任务。

OS提供了基于资源的互斥机制,即当Task或2类 ISR获得资源时,其他任务或ISR无法获得该资源,防止任何其他任务或ISR同时进入同一关键部分,当关键部分完成时,任务或ISR将释放资源。

1.1 死锁与优先级置顶

实际应用中,由于低优先级任务在持有共享资源时可能会被多次抢占,在极端情况下,任务可能会达到一种称为“死锁”的状态。

在AUTOSAR OS中,为避免死锁相关的问题,使用了最高优先级的概念。系统中的每个资源都分配了一个最高优先级,该优先级等于需要访问该资源的任何Task或ISR的最高优先级。当任务或ISR获得资源时,任务/ISR的运行优先级将增加到资源的最高优先级(当且仅当此优先级高于Task/ISR的当前运行优先级时),即优先级置顶。释放资源后,任务或ISR的优先级将恢复为任务或ISR发出呼叫前的优先级。如下图所示:

优先级置顶有如下两个好处:

  • 能最小化控制优先级翻转
    每次高优先级任务或ISR准备就绪时,其执行最多只能由一个已持有a资源的低优先级任务或ISR延迟一次,也就意味着不存在累积阻塞发生。

  • 保证无死锁
    必须执行任务或ISR才能锁定。这可以用逆推来证明。假设某个任务(或ISR)试图获取资源,此时另一个任务或ISR已经拥有该资源,由于该任务或ISR必须以最高优先级运行,发出请求的任务不会执行(它将不是系统中优先级最高的任务或ISR),因此也就无法锁定资源。

1.2 资源分类

在最基本的级别上,资源只需要命名和分配一个类型。AUTOSAR OS中有三种类型的资源:
1.标准资源是正常的OS信号量。配置标准资源将创建具有指定名称的资源;

2.链接资源允许用户为标准(或其他链接的)资源别名

3.内部资源是指在进入任务时自动锁定并在终止时自动释放的资源。

RTA-OS需要知道哪些任务和ISR使用哪些资源。然后,它可以计算优先级上限协议使用的优先级上限。

2. 资源的应用

可以通过调用GetResource()获取资源,在使用后可以通过使用ReleaseResource()来释放资源,在Task或ISR释放资源前不能被终止。
如下示例展示了如何在Task1中使用资源:

#include  
TASK(Task1)  {
...
GetResource(Resource1);

ReleaseResource(Resource1);
...
TerminateTask();
}

创建GetResource()时,它会将调用任务或ISR的优先级提升到资源的最高优先级。资源的最高优先级是共享资源的任何任务或ISR的最高优先级,由RTA-OS自动计算。如果任何优先级低于上限优先级的任务已准备好运行,则在运行任务的优先级恢复正常之前,将阻止该任务执行(该任务被阻止)。

2.1 资源嵌套调用

所有的资源都必须正确调用,Get与Release成对出现。资源嵌套调用的正确格式:

GetResource(Resource1);
	GetResource(Resource2);
		GetResource(Resource3);
		ReleaseResource(Resource3);
	ReleaseResource(Resource2);
ReleaseResource(Resource1);
2.2 内部资源

如果一组任务非常紧密地共享数据,那么就运行时成本而言,使用标准资源来保护对每个数据项的每次访问可能过于频繁。甚至可能无法确定需要保存资源的所有位置。

可以使用内部资源阻止对共享数据的并发访问,内部资源是为任务的生命周期分配的资源。
使用rtaoscfg配置内部资源。然而,与普通资源不同,您无法获取并释放它们。从概念上讲,RTA-OS在启动任务之前立即锁定内部资源,并在任务终止后立即释放资源。
当任务进入运行状态时,RTA-OS中内部资源的实施不会产生Runtime成本,因为rtaosgen计算任务运行的优先级,并以该优先级简单地分派任务。共享内部资源的任务集在配置时使用rtaoscfg进行静态定义。

在AUTOSAR *** 作系统中,内部资源仅可用于任务。但在RTA-OS中提供了AUTOSAR OS的扩展,允许ISR使用内部资源。当任务锁定与ISR共享的内部资源时,任务将在中断的IPL处执行,并且在任务期间,所有优先级相同或更低的中断都将被阻止。

如果任务使用内部资源,RTA-OS将在调用任务的输入函数之前自动获取内部资源。在任务终止、执行Schedule()或WaitEvent()调用后,资源将自动释放。

在任务执行期间,共享内部资源的所有其他任务将被阻止运行,直到释放内部资源。下图显示了共享相同内部资源的三个任务的执行情况。
需要注意的是,当包含内部资源的任务终止时, *** 作系统会根据就绪任务的正常(基本)优先级做出调度决策。如果某个任务正在运行,且共享同一内部资源的多个任务已处于活动状态,则在运行的任务终止时,将选择最高优先级的就绪任务来运行,然后以内部资源的最高优先级进行调度。

如果正在执行共享内部资源的任务,则优先级低于内部资源最高优先级的任何任务(包括不共享内部资源的任务)都将被阻止。优先级为1的Task1与优先级为3的Task共享内部资源。如果Task1在Task2或Task3启动之前开始运行,则这两个任务都将延迟(阻止)到Task1完成。

但是,所有不共享内部资源的高优先级任务仍然可以抢占。下图显示任务1最初以优先级3运行,因为它与优先级3的任务共享一个内部资源。当任务1正在运行时,任务2准备好运行。任务2的优先级低于任务1的活动优先级,因此无法抢占。激活Task4时,它可以抢占Task1,因为其优先级为4,即优先级高于Task1的活动优先级。任务2只能在任务1终止时运行。

从这种行为可以清楚地看出,锁定内部资源的任务将阻止任何优先级高于自身但低于内部资源最高优先级的任务在整个任务期间运行。当低优先级任务阻止高优先级任务执行时,这称为阻塞。

共享内部资源的任务彼此之间以非抢占方式运行。一旦共享内部资源的集合中的任务访问CPU,它将在不被集合中的任何其他任务抢占的情况下运行。其结果是,与完全抢占系统中的情况相比,优先级较高的任务访问CPU可能需要更长的时间。

2.3 使用资源最小堆栈使用

应用程序中资源的主要作用是在关键部分上提供相互排斥。然而,RTA-OS的单堆栈模型意味着资源有一个有用的次要角色——最小化堆栈使用。回想一下,共享资源的任务不会相互抢占。在RTA-OS使用的单堆栈模型中,这意味着它们的堆栈使用被有效地覆盖。

可以利用此功能来权衡系统中的时间和堆栈使用情况。以下各节描述了对应用程序进行简单修改如何减少堆栈使用。所有这些修改将在系统中引入额外的阻塞因素。

这些阻碍因素的影响取决于系统。回想一下,优先级上限协议确保任务或ISR在执行期间最多被阻止一次。最坏情况下的阻塞时间是任何低优先级任务或ISR可以占用相同资源的最长时间。

这意味着,如果额外的阻塞因子小于或等于任务/ISR所遭受的当前最坏情况阻塞,则不会对响应时间产生影响,并且减少的堆栈使用将是免费的。如果额外的阻塞因子比当前最坏情况阻塞更长,则响应时间将更长。如果响应时间保持在任务/ISR要求的截止日期内,系统仍将正常运行。

2.3.1 内部资源

给定一组共享内部资源的任务,RTA-OS使用的最坏情况堆栈等于使用最多堆栈的任务所需的最大堆栈空间。在传统OS中,最大堆栈空间将等于任务堆栈的总和,而不是它们的最大值。

如果需要最小化堆栈空间,则可以通过在消耗大量堆栈的任务之间共享内部资源来利用RTA-OS单堆栈体系结构的这一优势。下图的第一个堆栈显示了5个抢占式任务A、B、C、D和E的最坏情况堆栈消耗。通过在任务B和C之间以及任务D和E之间共享内部资源,可以显著节省堆栈空间。图中的其他四个堆栈显示了现在可能发生的情况——最坏的情况是B中最坏的一个被抢占,或者C中最坏的被D和E中最坏的抢占。从图中可以看出,C中的抢占被D抢占,给出了最坏的情况,并且这比不使用内部资源时的堆栈要少得多。

2.3.2 标准资源

如果任务调用一个使用大量堆栈的函数,那么可以考虑锁定函数调用周围的资源,并将资源与优先级较高的任务共享。任务不需要在代码中锁定资源或调用函数-共享只是为了强制任务的执行以更高的优先级运行。这将防止高优先级任务在使用大量堆栈时抢占任务,从而降低总堆栈需求。

禁用函数调用周围的中断也有类似的效果-有效地将函数调用的堆栈使用与临时屏蔽的ISR重叠。

2.4 选择抢占控制机制

如果在一对GetResource()和ReleaseResource()调用之间出现不需要锁的代码,则系统响应可能会降低。基于此,当您在应用程序中使用资源时,应该尽可能地将GetResource()调用放在使用资源保护的代码部分周围。

然而,这条规则有一个例外。当短时间运行的任务或ISR对同一资源进行许多GetResource()和ReleaseResource()调用时,会发生此异常。API调用的成本可能会占整个任务执行时间的很大一部分,因此可能会占响应时间。
可以发现,将整个任务或ISR主体放在GetResource()和ReleaseResource()调用之间实际上缩短了最坏情况下的响应时间,应该尽可能避免使用非抢占式任务和获取RES_SCHEDULER程序。当资源占用的时间最短,且任务数量最少时,系统响应性和可调度性得到改善。

3. 本章小结

•资源用于提供对共享数据或硬件资源访问的互斥机制;

•任务和ISR可以共享任意数量的资源;

•所有GetResource()和ReleaseResource()调用必须正确嵌套使用;

•在任务或ISR终止之前,必须先释放所有资源;

•内部资源为控制一组任务和ISR之间的抢占提供了一种无成本机制。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5668906.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存