您当前的位置:首页 > 生活 > 内容

Events(事件)概述、配置及使用方法

Events(事件)概述、配置及使用方法

1.概观

在《RTA-OS系列介绍-Task》部分,我们介绍了任务分为基本任务和扩展任务。两者的主要区别是扩展任务有更多的等待状态,那么等待状态是在等待什么呢?事实上,这就是我们今天要介绍的事件。当系统中的任务或ISR设置一个事件时,等待的任务将变为就绪状态。当它成为优先级最高的就绪任务时,RTA-OS将选择运行该任务。

在AUTOSAR操作系统中,事件用于向任务发送信号信息,主要是为扩展任务提供多个同步点。本文将讨论什么是事件,如何配置它们,以及如何在运行时使用它们。事件的使用场景大致如下图所示。

2.事件配置

一个应用中可以正常配置的事件的最大数量取决于硬件,需要配置的事件包括:名称、至少一个任务用法和事件掩码。

设置事件时,还必须指定一项任务。因此,例如,如果为名为Task1的任务设置了名为Event0的事件,它对Task2的Event0没有影响。

2.1定义等待任务

在使用中,当我们声明一个任务需要等待一个事件时,系统会默认该任务为扩展任务,等待事件的扩展任务通常会自动启动(等待时间达到后),任务永远不会终止。当任务开始执行时,RTA-OS将清除它拥有的所有事件。

3.如何使用事件

3.1等待事件

任务的等待事件需要调用等待事件(EventMask) API,具体的等待事件掩码需要与事先声明的内容关联。

WaitEvent()将事件作为其唯一的参数。执行呼叫时,有两种可能性:

1)事件尚未发生。在这种情况下,任务将进入等待状态,RTA-OS将以就绪状态运行优先级最高的任务。

2)事件已经发生。在这种情况下,任务将保持在运行状态,并将在WaitEvent()调用后的语句中继续执行。

3.1.1等待单一事件

要等待单个事件,只需将事件掩码名称传递给API调用。以下示例显示了任务如何使用等待事件。

#包含任务(扩展任务){.WaitEvent(事件1);.}

在AUTOSAR操作系统中,为处于挂起状态的任务设置事件是非法的。事实上,这意味着等待事件的任务结构通常是等待事件的有限循环。

等待多个事件

因为AUTOSAR OS事件只是一个位屏蔽,所以用户可以按位设置一组位屏蔽,同时等待多个事件。

当任务等待多个事件时,它将在任何等待事件发生时恢复。当从等待多个事件中恢复时,您需要确定发生了哪些事件。

# include task(extended task){ eventmasktypewhathappen;while(true){ waite vent(event 1 | event 2 | event 3);GetEvent(Task1,WhatHappenedif(what happenedevent 1){.} else if(what happenedevent 2){.} else if(what happenedevent 3){.} }}

在AUTOSAR-OS中,提供了GetEvent()的API,通过它我们可以知道哪个事件已经完成。

3.1.3扩展任务的死锁

虽然AUTOSAR操作系统在关键部分的资源互斥中提供了免于死锁的自由,但在构建可能发生死锁事件的系统时,它将不受保护。如果我们有相互设置并等待事件集的扩展任务,两个(或更多)任务可能正在等待仅由其他等待任务设置的事件。当然,即使有死锁扩展任务,系统中的基本任务也不能死锁。

以下示例显示了扩展任务的死锁:

# include TASK(TASK 1){ while(1){ waite vent(Ev1);SetEvent(Task2,Ev2);} } TASK(TASK 2){ while(1){ waite vent(Ev2);SetEvent(Task1,Ev1);}}

OS配置不获取ISR设置了哪些任务或事件,只获取哪些任务可以等待事件。所以RTA-OS不可能静态判断扩展任务是否会死锁。采用以下设计方法可以避免类似问题:

仅使用基本任务;

分析代码以显示在所有SetEvent()或WaitEvent()对的传递闭包上没有循环等待事件。

3.2设置事件

通过SetEvent() API设置事件。

SetEvent()调用有两个参数,一个任务和一个事件掩码。对于指定的任务,SetEvent()调用set事件掩码中指定的事件。此调用不会为共享事件的任何其他任务设置事件。

调用SetEvent()时,可以通过位或多个事件掩码同时为任务设置多个事件。

无法为处于挂起状态的任务设置事件。因此,在设置事件之前,必须确保任务没有挂起。您可以通过使用GetTaskState()API调用来实现这一点,但是请注意,在为优先级高于调用者的任务调用此函数时,可能会出现竞争情况。在调用API和评估结果之间,调用者可能会被抢占,并且所请求任务的状态可能在中间发生了变化。

当设置了扩展任务正在等待的任何事件时,扩展任务将从等待状态转移到就绪状态。

下列任务显示了任务如何设置事件:

#包含任务(任务1) {任务状态类型任务状态;SetEvent(Task2,event 1);SetEvent(Task3,event 1 | event 2 | event 3);GetTaskState(Task2,TaskState);if (TaskState!=SUSPENDED) { SetEvent(Task2,event 1);} .termin ate task();}

多个任务可以同时等待同一个事件。但是,从上面的例子中可以看出,事件没有广播机制。换句话说,不能通过调用API来告诉所有等待的任务事件已经发生。

此外,您还可以通过警报和调度表设置事件。

3.2.1通过报警设置事件

报警可用于定期激活未终止的扩展任务。每次警报到期时都会设置此事件。然后,等待事件的任务就可以运行了。

3.2.2通过带有到期点的调度表设置事件。

进度表上的到期点可用于编程(a)非终止状态下扩展任务的周期性激活。每次处理过期点时,都会设置该事件。然后,等待事件的任务就可以运行了。

3.3清除事件

事件可以由任务或ISR设置,但只能由其所有者清除。

# include TASK(extended TASK){ event mask type what happen;while(waite vent(event 1 | event 2 | event 3)==E _ OK){ get event(task 1,WhatHappenedif(what happened event 1){ clear event(event 1);.} else if(what happened(event 2 | event 3){ clear event(event 2 | event 3);.} }}

当一个任务正在等待一个事件,并且该事件发生了,并且在后面的序列中再次为同一个事件调用WaitEvent()时,它将立即返回,因为该事件仍然处于Set状态。因此,在再次调用等待事件之前,有必要清除之前已经发生的事件。

清除事件时调用ClearEvent API,清除状态必须与事件掩码关联。

当任务被挂起时,它所拥有的事件将被自动清除。

3.4使用基本任务模拟扩展任务

基本任务只能在任务执行的开始或结束时进行同步。

如果需要其他同步节点,可以通过事件机制实现。然而,扩展任务比基本任务占用更多的资源,并且在资源受限的系统中,只能通过使用基本任务来实现同步。

例如,如果任务构建为状态机(例如,使用C switch语句),则可以设置状态变量,发出对TerminateTask()的调用,并等待重新激活。下面的示例代码显示了如何做到这一点。

#include uint8状态之间的范围内保持不变的“State”变量;TASK(TASK 1){ switch(State){ case 0:State=1;打破;情况1: State=2;打破;情况2: State=0;打破;} termin ate task();}

4.本文摘要

事件是用于同步的实体,可以用来扩展任务的等待内容;

同一事件可以被不同的任务引用;

事件没有广播机制,即不可能通知所有等待事件的任务;

可以为任务、ISR和调度表设置事件。

如果及时性在系统中很重要,那么所有扩展任务(任何等待事件的任务)的优先级必须低于基本任务。

审计唐子红

标签:事件任务等待


声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,谢谢。

上一篇: 联想平板电脑a1(乐pad A1的简介)

下一篇: 腊八节的意义,腊八节的意义20字(腊八节的由来风俗、传说故事)



推荐阅读

网站内容来自网络,如有侵权请联系我们,立即删除! | 软文发布 | 粤ICP备2021106084号