您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
   
 
 订阅
五千字长文介绍AUTOSAR RTE功能
 
作者: 一片绿叶
   次浏览      
 2024-9-13
 
编辑推荐:
本文主要介绍了Autosar RTE的功能相关内容。希望对您的学习有所帮助。
本文来自于微信公众号谦益行,由火龙果软件Linda编辑、推荐。

一、什么是RTE

RTE的作用有点像一个快递中转站或者说是电话接线员(就是上个世界那种要先打电话到接线员那里,然后通过接线员转接电话线到目的地),其作用就是将一个SWC的信息通过RTE连接到其他SWC或者BSW上。且RTE具有管理这些信息的功能,比如接收的SWC正忙(您所拨打的用户正忙),那么RTE负责让发送信息的SWC等待,或者做其他处理;RTE还能触发SWC,就像是这时接收的SWC在睡觉,这时发送的SWC发信息来了,那么RTE就要把接收的SWC叫醒起床。

一句话概括就是RTE提供了SWC的运行环境。

二、RTE的作用

提供跨ECU/ECU内部的通信管理。

提供对runnable的管理功能(触发、唤醒等,简单说就是runnable需要映射到Task上运行嘛,而这个映射就是通过RTE具体实现的),之前我们不是提到了VFB(虚拟功能总线),RTE就是VFB的具体实现。

在Vector的工具链中,RTE是自动生成的下面这种图,我们将其再做细化,就能很清楚的看出其关联关系了。这里的RTE就是统一的管理,具体那些连接时怎么连的,我们是不需要在RTE中关心的(因为AppL中配好,RTE就自动生成嘛)。

三、RTE对Runnables的运行支撑

1)作为运行环境的主要功能点

通过RTE给runnable提供触发事件。之前说过了runnable是可以被触发的,就是需要通过RTE来实现这个触发和调用runnable,具体在下面讲解通过RTE给runnable提供所需资源。就是之前说的接口通信(Ports那节),将runnable需要的一些资源通过接口传输给它将BSW和SWC做隔绝。因此OS和runnables也被隔绝了,runnable的运行条件由RTE提供,不能由OS直接提供

2)Runnables的触发条件

RTE给runnables提供触发条件,也就是runnable在设计的时候,需要有触发条件,不然无法运行,也就没有意义了。触发条件就是一些特定的事件,AutoSAR中主要规定了以下一些触发条件(图中是DaVinci软件中的配置项,灰色是因为我没有配置,不用在意):

初始化事件:初始化自动触发

定时器事件:给一个周期定时器,时间到了就触发

接收数据事件(S/R):Receiver Port 一旦收到数据,就触发

接收数据错误事件(S/R)

数据发送完成事件(S/R):Send Port 发送完成,就触发

操作调用事件(C/S):当调用到了该函数的时候

异步服务返回事件(C/S):之前说过C/S可以在异步下运行,就是说当我调用一个Server函数,但是我是异步调用的。那么该被掉函数作为一个线程和当前的运行程序并行运行,当被调函数运行结束返回(Return)的时候,这时触发异步服务返回事件

模式切换事件

模式切换应答事件

三 RTE对Ports的支撑(上)

1)扮演SWCs和BSW的交流途径

还是老生常谈的那么几点:

作为VFB的具体实现

作为S/R接口的通信实现

作为C/S接口的通信实现

ECU内部通信/跨ECU(通过COM)

实现AR-COM的回调功能,具体实现是在SWC中完成的,RTE负责完成这个回调机制

2)其他特征

提供了实现数据一致性的机制(所谓的数据一致性,就是说简单一点:当多个SWC同时操作同一个数据时,可能会发生一些不想看到的问题,数据一致性要求不能发生这些问题)

支持简单和复杂的数据类型

对SWC类型(SWC type,和SWC不同,SWC type是指SWC的一个类型,用这个类型可以实例化一个SWC,就好像用int这个类型实例化一个count一样)的实例化

3)S/R接口的不同方式

以下调用,在配置好Davinci后,是会自动生成到runnable上方的,可以直接复制。比如我复制了一段DaVinci生成的SWC中的代码,可以看到,其中的 Rte_ 的函数都是列出来在runnable上方的


Runnable Entity Name: RAB_Core0_100us

Executed if at least one of the
following trigger conditions occurred:
* - triggered on TimingEvent every 100us

Input Interfaces:
* Explicit S/R API:
* Std_ReturnType Rte_Read_AppPI_
Can_ReceiverCore0_DEP_Can_Receiver(Idt
_Can_Receiver *data)
**
Output Interfaces:
* Explicit S/R API:
* Std_ReturnType Rte_Write_AppPI_Can_
SenderCore0_DEP_Can_Sender(Idt_Can_Sender data,
Rte_TransformerError *transformerError)
**
Service Calls:
* Service Invocation:
* Std_ReturnType Rte_Call_
ComM_UserRequest_GetCurrentComMode
(ComM_ModeType *ComMode)
* Synchronous Service Invocation. Timeout: None
* Returned Application Errors:
RTE_E_ComM_UserRequest_E_NOT_OK
* Std_ReturnType Rte_Call_ComM_UserRequest_
GetMaxComMode(ComM_ModeType *ComMode)
* Synchronous Service Invocation. Timeout: None
* Returned Application Errors:
RTE_E_ComM_UserRequest_E_NOT_OK
* Std_ReturnType Rte_Call_ComM_UserRequest
_GetRequestedComMode(ComM_ModeType *ComMode)
* Synchronous Service Invocation. Timeout: None
* Returned Application Errors:
RTE_E_ComM_UserRequest_E_NOT_OK
* Std_ReturnType Rte_Call_ComM_UserRequest
_RequestComMode(ComM_ModeType ComMode)
* Synchronous Service Invocation. Timeout: None
* Returned Application Errors: RTE_E_ComM_UserRequest
_E_MODE_LIMITATION, RTE_E_ComM_UserRequest_E_NOT_OK
**
* DO NOT CHANGE THIS COMMENT! << Start
of documentation area >> DO NOT CHANGE THIS COMMENT!
* Symbol: RAB_Core0_100us_doc
* DO NOT CHANGE THIS COMMENT! << End of documentation
area >> DO NOT CHANGE THIS COMMENT!
FUNC(void, SWCCore0Basic_Type_CODE) RAB_
Core0_100us(void) /* PRQA S 0850 */ /* MD_MSR_19.8 */
{/
* DO NOT CHANGE THIS COMMENT! << Start of
runnable implementation >> DO NOT CHANGE THIS COMMENT!
* Symbol: RAB_Core0_100us
* DO NOT CHANGE THIS COMMENT! << End of runnable
implementation >> DO NOT CHANGE THIS COMMENT!

}
 

 

直接调用(Direct)

相当于有一个全局变量,runnable可以直接读写这个变量

用的是下面的语法:(注意 <data> 和 data 的区别,带<>的是指全局data的名字,不带<>的data是局部变量的名字,这里使用指针,就是说操作的是同一个地址,没有复制使用;同时,这些函数都是在runnable中使用的,不要看是Rte,就以为是RTE中的代码,因为调用的是RTE的机制,所以这里是Rte)

Std_ReturnType Rte_Read_<port>_<data> (<DataType> *data)

Std_ReturnType Rte_Write_<port>_<data> (<DataType> data)

缓存调用(Buffered)

相当于将全局变量先复制到一个runnable的局部变量中,再操作这个局部变量,最后把这个局部变量再赋值到全局变量中。在runnable操作这个局部变量期间,全局变量是不会改变的。

使用方法如下:(都是由RTE管理的,用户只需要正确调用函数就ok)

<DataType> Rte_IRead_<r>_<port>_<data> (void)

void Rte_IWrite_<r>_<port>_<data> (<DataType> data)

队列调用(Queued)

因为数据不止一个,是一组队列的数据,就像我们常用的串口FIFO。因此,可以设置循环接收或者等待接收,等待的话是有超时管理的。

调用代码如下:

Std_ReturnType Rte_Receive_<port>_<data> (<DataType> *data)

Std_ReturnType Rte_Send_<port>_<data> (<DataType> data)

4)跨ECU的方式

假如是跨ECU的数据传输。那么,我在runnable中使用 Rte_Write_<port>_<Data>() 这样的函数后,会需要走runnable(ECU1) ->RTE (ECU1) ->BSW (ECU1) ->外部总线->BSW (ECU2)->RTE (ECU2) ->runnable (ECU2),这里也列出了用于COM传输的两个函数名:

Com_SendSignal()

Com_ReceiveSignal()

四、RTE对Ports的支撑(下)

1)C/S接口的实现

之前在第二章AppL中讲过了C/S接口,这里再更加深入的说明一下其实现的原理:首先,C/S接口就是客户/服务接口,这个接口就是客户来调用服务端的操作的一个接口。也就是我写着写着,发现我想要调用一个函数,这个函数在其他的C文件中,就让RTE帮忙调用。还是举个例子:

我,客户,我想要执行一个函数,这个函数写在服务端上的。由于我和服务端有隔阂(SWC之间不能直接通信),这时,我就悄悄告诉RTE,我想要执行那个函数,RTE就会帮我告诉服务端,让服务端执行该函数。

而这里又有两种方式:异步和同步:

同步就是说我这个人很懒,我要等服务端运行完了这个函数,RTE返回这个函数的结果后,我才开始继续我的工作;

异步就是我这个人很勤快,我通知RTE让它帮忙告诉服务端运行函数后,我就继续干我的事了,等过一段时间后,我估摸着函数运行结束了,我再请求函数结果

2)C/S接口的不同方式

同步和异步调用不是通过函数区别的,这必须是事先配置好由RTE生成的,所以在Davinci中配置runnable的port时是有这个选项的(当然要C/S接口才有)

同步调用

从上文的例子,可以看出,同步调用其实就是我们平时调用函数是一样的,就是等同于将被调函数代码嵌入当前调用的函数代码中运行即可。

我们也用代码实际说明一下

//假如我们的被调函数是:

Std_ReturnType RunnableServer(int *param)

//那我们的客户中应该写的调用函数就是:

Std_ReturnType Rte_Call_<Port>_RunnableServer(int *param)

//这个param就是我们希望被调函数操作的变量

异步调用

异步调用相当于有两个线程,一个线程运行我们的原函数中的内容,另一个执行被调函数的内容。然后可以过一段时间去读取一下被调函数的返回结果

而这时,如何知道被调函数是否执行完了呢?有三种方法:

循环检测,就是在那一直等,等到返回值为止,这样的话和同步就差不多了,意义不大

超时检测,定一个时间,时间到了就去读取,没到的时候继续运行我的程序

事件触发,当服务函数运行结束,RTE可以触发原函数,告诉它被调函数运行完了,你可以读取返回值了

读取函数也用代码实际说明一下

//执行下面的函数后就能将参数返回回来了

Std_ReturnType Rte_Result_<Port>_RunnableServer(int *param)

五、RTE对数据一致性的管理

1)什么是数据一致性

引用百度百科:数据一致性,就是当多个用户试图同时访问一个数据库,它们的事务同时使用相同的数据时,可能会发生以下四种情况:丢失更新、未确定的相关性、不一致的分析和幻想读。

说的通俗一点:就是当多个操作同时读写同一个数据的时候,很有可能出bug(实际是由于优先级的问题,可能出现我们的数据被篡改的情况,造成作者不想看到的数据结果)

2)数据一致性的实现机制

利用RTE管理

这部分类容之前说过了,就是利用RTE来管理这里的数据,防止bug出现。比如IRead,大家都操作的是数据的备份,不直接操作原数据2、SWC内部变量这个内部变量就比较神奇了,因为它可以直接在DaVinci中配置,runnable可以直接调用,就类似于一个c文件中定义的全局变量,没有被extern出去。在c文件中定义的函数时可以直接使用的。那么这时就会出问题了,同一个c文件中的函数是可能被放在不同Task上运行的,就可能出现这些函数在同一时刻运行的状况,那么在调用这个全局变量的时候,就可能出bug。那么要如何解决呢?AutoSAR做了以下两种方式:

EAs(Exclusive Areas,专用区域):就是下面两句代码,相当于一个关中断,调用变量的语句放在里面,运行时不能有更高级的Task打断被保护的语句

Rte_Enter_<name>();

//这里放置被保护的语句

Rte_Exit_<name>();

IRVs(Inter-runnable variables,跨函数变量):还是两句代码,上面的EAs是整段代码段都被保护了,而这里的两句就相当于在改变变量的时候被保护,也就是这两句话执行的时候被保护

Rte_IrvWrite_<re>_<name>()

Rte_IrvRead_<re>_<name>()

六、RTE与Interface接口

1)Interface接口总览

少说废话,先上图

上图将所有的接口以及其分布的位置都详细的标识了出来,还是用的原来的那张ECU的图添加的,方便大家做对比

七、AutoSAR接口

一句话概括:之前说的S/R和C/S接口就是AutoSAR接口

特征:接口函数名可变,例如之前说过的 Std_ReturnType Rte_Read_<port>_<data> (<DataType> *data) 这中形式的S/R函数,其中的 <port> <data> 就是,用户自己配置的名字,因此,这些接口的函数名都是可以改变的,但大体的形式是不变的。

位置:SWC<>RTE、RTE<>CDD、RTE<>ECU AB(这里提一句,ECUAB之前没有讲到,其实很多的传感器、执行器都放在这里,是ECU的抽象,也是可以看作是SWC的,IoHwAb就在这里面)。说明白一点,就是

只要能看成是SWC处理的,就是AutoSAR接口。

八、标准接口

一句话概括:就是AutoSAR规定的C语言API

特征:接口函数名是固定不变的,是AutoSAR规定好的。比如:Com_SendSignal() WaitEvent() 这类都是API函数名,可以有上层调用,但是一般是使用工具配置生成的,做上层应用的一般是不用关心其具体实现的位置:第一张图中棕色的就是标准接口,说白了就是对函数API的调用。

需要特殊说明一点的是:下图中两个红圈中的箭头,OS和COM是唯一的两个标准接口允许直接和RTE相连的。因为RTE的很多功能是需要基于这两个模块来实现的

九、标准AutoSAR接口

一句话概括:就是AutoSAR接口,不过名称是由AutoSAR官方规定不能修改

特征:就是标准接口和AutoSAR接口的特征它都有一部分。首先是和AutoSAR接口一样,提供的是C/S、S/R接口;然后又和标准接口一样,函数名是不可变的。说白了就是官方规定好的C/S、S/R接口,咱们就当成是AutoSAR接口就行了,函数名字什么不用管它位置:RTE<>Services,就这么一个地方。

 

 

   
次浏览       
 
相关文章

CMM之后对CMMI的思考
对软件研发项目管理的深入探讨
软件过程改进
软件过程改进的实现
 
相关文档

软件过程改进框架
软件过程改进的CMM-TSP-PSP模型
过程塑造(小型软件团队过程改进)
软件过程改进:经验和教训
 
相关课程

以"我"为中心的过程改进(iProcess )
iProcess过程改进实践
CMMI体系与实践
基于CMMI标准的软件质量保证

最新活动计划
C++高级编程 12-25 [线上]
白盒测试技术与工具实践 12-24[线上]
LLM大模型应用与项目构建 12-26[特惠]
需求分析最佳实践与沙盘演练 1-6[线上]
SysML建模专家 1-16[北京]
UAF架构体系与实践 1-22[北京]
 
 
最新文章
iPerson的过程观:要 过程 or 结果
基于模型的需求管理方法与工具
敏捷产品管理之 Story
敏捷开发需求管理(产品backlog)
Kanban看板管理实践精要
最新课程
基于iProcess的敏捷过程
软件开发过程中的项目管理
持续集成与敏捷开发
敏捷过程实践
敏捷测试-简单而可行
更多...   
成功案例
英特尔 SCRUM-敏捷开发实战
某著名汽车 敏捷开发过程与管理实践
北京 敏捷开发过程与项目管理
东方证券 基于看板的敏捷方法实践
亚信 工作量估算
更多...