【ETAS CP AUTOSAR工具链】基本概念与开发流程

基于CP AUTOSAR进行控制器软件开发已渐渐成为业界的主流。CP领域中除了VECTOR,ETAS,EB,Mentor等外资公司,还有诸如普华,东软,恒润,华为等国产基础软件公司。

ETAS是在2015年推出的AUTOSAR量产版本。在各大主机厂、零部件供应商、以及部分互联网和自动驾驶公司都有使用,在新能源三电,底盘,网关,ADAS领域均有量产项目,其基础软件代码质量经过大量项目量产,是一款相对成熟的CP产品。

一套完整的ETAS CP产品首先可以分为两个部分,一个是RTA-CAR,另一部分是OS Port。OS Port对应的是一个编译器和芯片核心,例如产品选用的是基于英飞凌芯片(Tricore核心),使用的是HighTec编译器,那么就需要安装RTA-OS TriCoreHighTec Vx.x.x。RTA-CAR则是一套AUTOSAR工具链(包括ISOLAR-AB,RTA-RTE,RTA_BSW,RTA-OS等),本文概括介绍基于这套工具链的开发流程,并主要介绍了系统级的设计与配置。

目录

概述

开发框架与流程

系统及设计与配置

创建部件与系统

定义数据类型(Data Types)与接口(Interface)

系统约束描述文件(DBC)导入

设计软件组件 

连接系统/内部信号 

ECU抽取


概述

ETAS RTA-CAR(Classic AUTOSAR)包括用于ECU软件开发的基础软件模块和工具,主要内容如下:

  • ISOLAR:工具包含ISOLAR-A和ISOLAR-B两个部分,用于配置Classic AUTOSAR产品。
    • ISOLAR-A:用于AUTOSAR架构配置与应用集成工具。
    • ISOLAR-B:用于配置满足AUTOSAR标准的基础软件,以及用于生成和集成ECU软件的工具。
  • RTA-RTE:ETAS RTA-RTE (runtime environment) 为符合AUTOSAR的ECU软件提供运行时环境。它支持相关AUTOSAR, OSEK/VDX, ISO 26262, 和MISRA C标准的最新版本。
  • RTA-BSW:RTA-BSW提供全套AUTOSAR基础软件模块,与RTA-OS和RTA-RTE相结合,即可构建用于ECU应用开发的整套AUTOSAR平台软件。它提供了完整的基础软件协议栈,例如CAN、LIN、J1939、诊断、XCP、以太网SOMEIP等。
  • RTA-OS:RTA-OS 以汽车工业建立多年的RTA-OSEK 实时操作系统的经验为基础。RTA-OS 支持单片和多片微控制器的使用,在最小运行时系统开销的条件下结合一整套AUTOSAR 功能。由于其ASIL-D 的ISO 26262 认证的优点,RTA-OS 也可以被用于进行严格安全要求下的功能开发。


开发框架与流程

下面的脑图包含了使用ETAS CP工具链进行开发的一个基本框架,其中把整个ECU的软件开发设计分为了软件组件开发、系统级设计与配置、ECU设计、以及RTE集成与配置。其中应用软件组件开发主要着眼于控制逻辑以及算法的开发,系统级设计与配置主要着眼于组件(包含应用以及基础软件组件)之间的关系设计,ECU设计主要着眼于基础软件组件,OS,以及底层驱动的设计与实现,RTE的集成与开发则着眼于根据系统级设计完成组件间通信以及任务调度。

下图是一个自顶而下的开发流程,其中第一步采用的工具是Matlab/Simulink与Embedded Coder,第二步到第四步采用的是ISOLAR(内部集成了RTA-BSW,RTA-RTE),第五步采用的是RTA-OS,第六步采用的是EB,第七步则为HighTec或者是Tasking等。


系统及设计与配置

创建部件与系统

部件(Composition)是软件组件的集合,它包含一组相关甚至整车的所有ECU的软件组件,下图是部件的建立方法。

系统(System) 建立的方法如下。

系统建立完成之后,需要为其添加一个Compositon,通过下图新建一个Root SW Comppsition Prototype。 

建立完成之后建立对刚才部件的引用。


定义数据类型(Data Types)与接口(Interface)

AUTOSAR定义了三种数据类型,即应用数据类型(ADT),实现数据数据类型(IDT)以及基本数据类型(Base Type)。下面主要说明一下建立应用数据类型(ADT)中的数组类型。

配置类型属性。

AUTOSAR常见定义了两种接口(Interface),一种是发送者-接收者接口(Sender-Receiver Interface,S/R),一种是客户端与服务器接口(Client-Server Interface,C/S)。S/R接口是一组数据类型的集合,连接的两个组件通过类似全局变量的方式传递数据,C/S接口则是一组函数原型集合,定义了IN(输入参数),OUT(输出参数,传入的是地址)等函数的参数以及返回值。

下图为一个包含了一组数据集合的S/R接口。增加接口点Add SR Interface即可。

下图包含了一组函数原型集合的C/S接口,并打开了一个函数的参数,包含BufSize等。增加C/S接口则点击Add CS Interface即可。


系统约束描述文件(DBC)导入

DBC文件主要包含以下几个部分的内容。

  • Networks(网络)
  • ECUs(电控单元)
  • Network nodes(网络节点)
  • Messages(报文)
  • Signals(信号)

每个DBC描述的是一个网络上的通信信息,所以首先要定义一个Networks(网络),这个是在新建database时自动创建出来的。之后就是定义Network nodes(网络节点),右键单击Network nodes新建即可,同时将在ECUs(电控单元)菜单中自动创建出相关ECU信息。

定义了网络节点后,就需要根据项目需求完成Signals(信号)和Messages(报文)的设计。右键点击Signals新建,按照项目的信号矩阵,完成信号的设计。下图是一个信号的配置界面。

定义了所有的信号之后,即可进行报文设计。右键单击Message新建即可,主要需要定义的属性如下,并将之前定义好的信号包含进来。        

在完成了所有的信号以及报文设计之后,就需要将他们在各个节点的收发关系定义出来。若报文是发送,则将该报文添加到相应CAN节点的Tx Messages即可;若报文时接收的,则需要拖动该报文的信号,将他们逐一添加到Mapped Rx Signals列表中,下图是两个Tx报文和一个Rx报文。

之后,就可以将系统配置所需要的输入文件导入到ISOLAR中。 点击下图红框。

然后进入如下界面,选择要导入的dbc文件,和导入的CAN网络与对应的CAN控制器。

然后选择DBC中要导入的ECU。

最后选择对应的报文。

最后在对应的ECU中可以看到导入的信号信息。

DBC导入之后会根据DBC中定义的Offset和Factor完成原始值(总线上的值)到物理值(​信号的物理值是物理量(如速度、转速、温度等)的值)的计算方法,具体的公式为:[Physical value] = ( [Raw value] * [Factor] ) + [Offset]


设计软件组件 

首先,新建一个应用组件如下图。

然后,建立软件组件内部行为,只有建立了之后才能Runnables(可运行项)等功能函数实体。

为软件添加端口(Port),端口按照方向分为PPort和RPort。

针对S/R接口,PPort“写入”接口包含的数据,RPort“读取”接口包含的数据,注意只有在Port引用了接口之后,才会建立数据的定义,不同PPort引用同一个接口会建立不同名称的数据定义,一个PPort可以对应多个RPort。

针对C/S接口,PPort“实现”接口包含的函数原型,RPort“调用”接口包含的函数,不同PPort引用同一个接口会对应不同的函数实现,一个PPort可以对应多个RPort。

下图建立了三个Port口,一个是C/S类型的RPort,一个是S/R类型的PPort,一个S/R类型的RPort。

然后我们建立一个Runnables,建立完之后,增加针对S/R类型PPort口的数据访问如下,我们选择DataSendPoints显式(Explicit,应用于实时性较高的数据传输,可以通过排布任务调度在一个调度周期内将数据传输到另一个组件)。然后增加针对S/R类型RPort口的数据访问,选择DataReceivePointByArguments显示访问。

然后增加针对C/S类型Port的访问,访问类型为Synchronous。因为接口包含了5个函数原型,所以选择对应的Port口之后,会显示Port口引用接口下的所有函数原型。

 最后,我们添加运行实体的RTE事件,我们选择周期性事件,并将周期设置成0.01s。

至此,组件相关的设计已经完成,但是要想正确的生成RTE,我们还需要以下几个步骤将组件跟之前建立的部件,系统,ECU等建立关系。

首先,我们将软件组件加入部件,双击之前建立的部件,然后点击加号,选择Component Prototype。

然后选择之前创建的应用组件Test,点击OK即可。

然后右键之间建立的系统,打开方式选择SWC To ECU,然后拖拽到ECU之下。

这里还需要把之前定义的Runnables加入到Os_Task,这部分我们到RTT配置部分再介绍。

最后生成组件内函数对应的.C文件,用户可以再接入/出的信号基础上添加逻辑。

选择为每个函数单独建立一个.c文件。 

下面是生成的.C文件,我们可以在注释写了Protect包含的地方写入代码,这样每次生成不会更改此部分代码。

/* *****************************************************************************
 * BEGIN: Banner
 *-----------------------------------------------------------------------------
 *                                 ETAS GmbH
 *                      D-70469 Stuttgart, Borsigstr. 14
 *-----------------------------------------------------------------------------
 *    Administrative Information (automatically filled in by ISOLAR)         
 *-----------------------------------------------------------------------------
 * Name: 
 * Description:
 * Version: 1.0
 *-----------------------------------------------------------------------------
 * END: Banner
 ******************************************************************************

 * Project : CSDNTest
 * Component: /ARPackage_0/Test
 * Runnable : RunnableEntity_0
 *****************************************************************************
 * Tool Version: ISOLAR-AB 4.0.2
 * Author: geekl
 * Date : ������ ���� 21 18:14:36 2024
 ****************************************************************************/

#include "Rte_Test.h"

/*PROTECTED REGION ID(FileHeaderUserDefinedIncludes :RunnableEntity_0_func) ENABLED START */
/* Start of user defined includes  - Do not remove this comment */
/* End of user defined includes - Do not remove this comment */
/*PROTECTED REGION END */

/*PROTECTED REGION ID(FileHeaderUserDefinedConstants :RunnableEntity_0_func) ENABLED START */
/* Start of user defined constant definitions - Do not remove this comment */
/* End of user defined constant definitions - Do not remove this comment */
/*PROTECTED REGION END */

/*PROTECTED REGION ID(FileHeaderUserDefinedVariables :RunnableEntity_0_func) ENABLED START */
/* Start of user variable defintions - Do not remove this comment  */
/* End of user variable defintions - Do not remove this comment  */
/*PROTECTED REGION END */
#define Test_START_SEC_CODE                   
#include "Test_MemMap.h"

FUNC (void, Test_CODE) RunnableEntity_0_func/* return value & FctID */
(
		void
)
{

	uint32 read1;
	Std_ReturnType retRead1;
	EcuM_ShutdownTargetType shutdownTarget1;
	EcuM_ShutdownModeType shutdownMode2;
	Std_ReturnType syncCall2;
	EcuM_ShutdownTargetType shutdownTarget3;
	EcuM_ShutdownModeType shutdownMode4;
	Std_ReturnType syncCall3;
	EcuM_ShutdownTargetType shutdownTarget5;
	EcuM_ShutdownModeType shutdownMode6;
	Std_ReturnType syncCall4;
	EcuM_ShutdownCauseType shutdownCause7;
	Std_ReturnType syncCall5;
	EcuM_ShutdownCauseType shutdownCause8;
	Std_ReturnType syncCall6;
	uint16 write7;
	Std_ReturnType retWrite7;

	/* Local Data Declaration */

	/*PROTECTED REGION ID(UserVariables :RunnableEntity_0_func) ENABLED START */
	/* Start of user variable defintions - Do not remove this comment  */
	/* End of user variable defintions - Do not remove this comment  */
	/*PROTECTED REGION END */
	Std_ReturnType retValue = RTE_E_OK;
	/*  -------------------------------------- Data Read -----------------------------------------  */
	retRead1 = Rte_Read_RPortPrototype_1_VDP_uint32(&read1);

	/*  -------------------------------------- Server Call Point  --------------------------------  */

	syncCall2 = Rte_Call_RPortPrototype_0_GetLastShutdownTarget(&shutdownTarget1,&shutdownMode2);

	syncCall3 = Rte_Call_RPortPrototype_0_SelectShutdownTarget(shutdownTarget3,shutdownMode4);

	syncCall4 = Rte_Call_RPortPrototype_0_GetShutdownTarget(&shutdownTarget5,&shutdownMode6);

	syncCall5 = Rte_Call_RPortPrototype_0_SelectShutdownCause(shutdownCause7);

	syncCall6 = Rte_Call_RPortPrototype_0_GetShutdownCause(&shutdownCause8);

	/*  -------------------------------------- CDATA ---------------------------------------------  */

	/*  -------------------------------------- Data Write ----------------------------------------  */
	retWrite7 = Rte_Write_PPortPrototype_0_VDP_uint16(write7);

	/*  -------------------------------------- Trigger Interface ---------------------------------  */

	/*  -------------------------------------- Mode Management -----------------------------------  */

	/*  -------------------------------------- Port Handling -------------------------------------  */

	/*  -------------------------------------- Exclusive Area ------------------------------------  */

	/*  -------------------------------------- Multiple Instantiation ----------------------------  */

	/*PROTECTED REGION ID(User Logic :RunnableEntity_0_func) ENABLED START */
	/* Start of user code - Do not remove this comment */
	/* End of user code - Do not remove this comment */
	/*PROTECTED REGION END */

}

#define Test_STOP_SEC_CODE                       
#include "Test_MemMap.h"

连接系统/内部信号 

通过之前建立的系统,打开系统数据映射编辑界面。

然后选择通过DBC导入的系统信号与之前建立的RPort与接收的系统信号进行连接。

 内部的信号连接首先还是通过之前建立的系统打开部件编辑界面。

然后选择下面的内部信号连接摁扭。

选择需要进行的连接,勾选对应连接然后点击Finish完成连接 

  下图为最后完成的连接。


ECU抽取

在生成RTE之前,需要做ECU抽取来把BSW和ASW的改动跟RTE相关的部分抽取出来。选择对应的ECU,右键选择建立ECU抽取。

选择如下选项点击Finish完成ECU抽取。 


 十六宿舍 原创作品,转载必须标注原文链接。

©2023 Yang Li. All rights reserved.

欢迎关注 『十六宿舍』,大家喜欢的话,给个👍,更多关于嵌入式相关技术的内容持续更新中。

相关推荐

  1. 软件开发标准流程软件工程基本理论

    2024-04-21 19:58:02       28 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-21 19:58:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-21 19:58:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-21 19:58:02       87 阅读
  4. Python语言-面向对象

    2024-04-21 19:58:02       96 阅读

热门阅读

  1. Python设计模式

    2024-04-21 19:58:02       33 阅读
  2. Qwen量化脚本run_gptq.py解析

    2024-04-21 19:58:02       37 阅读
  3. 【回溯】Leetcode 131. 分割回文串【中等】

    2024-04-21 19:58:02       41 阅读
  4. 【记录一个问题】ubuntu如何显示图形界面

    2024-04-21 19:58:02       34 阅读
  5. python项目练习——29.贪吃蛇

    2024-04-21 19:58:02       37 阅读
  6. oracle快速定位数据库瓶颈

    2024-04-21 19:58:02       29 阅读