Fork me on GitHub

CANoe Communication:VCODM

Introduction

  本文中的文字错误、技术描述错误等相关纠正或技术指导可在您阅读后评论区提出,感谢!

  随着CAN等传统总线后续被10BaseT1以太网补充替代的可能性加大,以太网与SOA愈发重视,各OEM的测试重心渐渐也从协议栈转向了服务与功能。而在基于SOA的功能测试中,Someip作为核心至关重要,但是常规的功能测试(不包括协议栈)针对Someip SD并不十分关注,用SomeipDLL实现也很麻烦。CANoe12.0版本提出了CO:Communication Object,CO将Someip的服务与方法抽象为具体的单独的接口来供测试工程师使用,极大降低了测试难度。本文章针对CO重要讲解基础的三部分:CO概念,VCDOM了解制作,CO手动测试,CO自动化测试。

Communication Concept

Basics of the Communication Concept

  Communication核心是基于service-oriented communication,将CANoe抽象为一个实体来负责通信层与应用层的交互。这种抽象是在应用层与通信层严格分离,CANoe自身在两层中间单独抽象一层,称为中间件Middleware。

  在Middleware中,需要用户自行配置参数,例如通信层的IP地址、端口、MAC地址、VLANID以及广播、组播的相关参数;应用层的ServiceID,MethodID等。基于这些参数抽象一个 communication objects (CO) 或 distributed objects (DO),本文中我们先不讨论DO的具体使用。

  根据Vector的描述,CO与DO理念不仅仅适用于面向服务,也支持面向CAN\Flexray等传统协议的PDU传输,这有待于我们进一步探索。

Service-Oriented Communication

  CANoe的service-oriented communication 更多使用是基于TCPIP协议的中间件抽象,例如本文重点讨论的Someip。为了大家更好的明白CANoe是如何抽象的,在下图的SOC架构中,我们需要配置应用层Someip、通信层TCPIP、物理层MAC地址等参数。配置完毕后CANoe将会为我们抽象一个接口面板出以供测试工程师使用。小张浅薄理解,CANoe的Middleware实际就是配置一个TCPIP/UDP+Someip的协议栈出来,然后抽象出应用层接口到面板。

  Middleware支持这种接口的动态修改,例如我们后续提到的consumedEventRef::Clear(),这种技术极大的提高了Middleware中间件的灵活性。

Binding

  Middleware的绑定不仅仅局限于创建一个Socket进行Port与IP的绑定,而是指CO或者DO的一种宏观上的绑定概念,直白来说就是实现抽象对象与实体ECU的通信绑定,这些绑定同样基于Someip订阅与TCP进行。目前CANoe支持四种绑定:Abstract Binding、Someip Binding、MQTT Binging、SIL Adapter Binding。

  Abstract Binding是Test Node与Test Node之间进行,这需要测试工程师同事配置两个节点进行测试,一般用于验证数据库的一致性。

  Someip Binding是Real ECU与Test Node之间,这仅仅需要测试工程师配置Teste Node即可。

 

  MQTT Binding是Docker与Client之间。

  SIL Adapter Binding是指使用SIL Adapter 的SUT (System Under Test),这种可以运行于云端,个人没接触过。  

Communication Objects

  除了本文暂不讨论的Distributed Object(DO)外,Communication Object(CO)是Communication Concept的核心,CO需要配置三部分:

  • Endpoint端点对应Paticipanting communication partners传播伙伴。
  • Communication Type通信类型决定是Signal-Based还是Service-Based。Someip采用后者。
  • Communication Pattern类型决定是端到端通信还是广播通信。

  作为了解,最后根据本文的重点举一个例子来说明SomeipBinding的实现,参考下图一个摄像头功能,客户端ParkAssit与HeadUnit需要向摄像头订阅采集前左、前右等四个方向的数据,在CANoe实现时只需要定义Interface,接口中我们定义具体的方法,Someip的实现需要MethodID、ServiceID、EventID、EventGroupID。

  VCDL中定义与C#的Interface定义类似,当然在实际应用中极少让测试工程师去定义,而是基于开发输入的的Arxml直接进行。VCDL的使用及CANoe接口小张需要请教朋友后联合撰写,继续介绍VCDOM。

VCODM制作

  重中之重,在讲解CO测试操作之前有必要告知测试工程师VCODM配置方法。CO对象支持三种数据库格式,其中Arxml为开发工程师通过Vector工具链导出,另外一种VCODM是根据协议栈与服务信息测试开发工程师自行制作而来,也支持从Arxml直接转换后修改。还有一种叫VCDL,一般作为定制化协议的数据库开发应用,网络上的资料也多有基础介绍,本文不再转述。

  对于测试工程师,三种数据库的使用难度:VCDL(全开发)>VCODM(半开发)>Arxml(开发输入)。小张看来是最好用的VCODM,不仅仅支持与开发保持协同,也支持进行部分参数的修改,相比VCDL的开发更加简单,相比Arxml难以修改更加简单。最普遍的场景为:开发工程师输入Arxml,测试工程师利用CANoe Autosar Converter转为VCODM进行测试,并可随时快速修改配置参数。对于如何修改,下文继续介绍VCODM的搭建开发。

  打开VCODM编辑器,右框条目包含了Type Definitions类型定义、Application应用层、Protocol协议栈层、Binding绑定、Safety & Security安全加密、Bus Systems总线六大模块。建议测试工程师自下而上进行数据库的搭建。
  

Bus Systems

  

 Bus Systems面向以太网总线,CO仅支持以太网的建立,根据需要的信息建立各ECU的参数。切记ECU的IP地址配置为Server与Client的类型,这关系后续Service服务的建立正确性。

Safety & Security

  

  安全加密模块为Autosar的信息安全机制,包括Secoc行程计数器、新鲜度值的设置;E2E的Porfile文件选择(已经内置CRC的基础算法),CRC的一些参数配置等;TLS加密协议中Server/Client配置,Someip中一般不用配置此模块。

Binding

  

  服务配置框的服务接口需要采用拖拽的方式添加到Binding中。在VCODM中Binding仅指Service与ECU之间的绑定,IP与Port的绑定在Bus Systems已经进行,这也是建议自下而上创建数据库的原因之一。

Protocol Layer

  

  在协议层中仅关注Someip的部分,Global Setting负责协议栈参数的基础配置,包括Client、Server、Seralize序列化三大部分,其中TLL、随机码规则等具体值需要根据开发工程师提供的具体参数决定。Service将在Application Layer建立后自动生成,TP不关注。

Application Layer

 

  至此,VCODM配置完毕,因为本篇时间所限,具体的参数配置不做讲解,这些参数与Someip协议栈完全一致,希望读者在此之前学习了Someip的基础知识。

Check

  

  在数据库的有效性检查通过后,就可以添加到CANoe的Communication Setup模块使用。
  

CO Maunal Test

  上述章节已经了解CO的概念、VCODM数据库的制作。选择好想要Simulate的ECU后,接下来我们进行数据库面板的添加与仿真。
  

  声明一点,此服务的SD订阅MiddleWare会自动进行,工程师需要确保:ECU处于正常唤醒、以太网物理链接正确,Hardware Configuration中将Swithch或Link配置正确。

  

  以上,我们完成了基于CO对象的Someip服务仿真发送。除了本文讲解的的VCODM之外,VCDL灵活性更大,支持DDS、HTTP、TOX等协议,开发支持C#等脚本语言。VCDL对测试开发工程师的能力也具有更高的要求,小张目前听说应用过的OEM也寥寥无几。

CO Automatic Test

  自动化测试仅是将手动测试中的一些操作对应到具体的CANoe接口。众所周知,只要在CANoe中可以手动点击的东西,都会存在对应的接口。在本章节中,我们仅介绍需要用的CO接口:

Counsumer Interface

consumedEventRef * <var>; // form 1
consumedEventRef <Event> <var>; // form 2
consumedEventRef <Datatype> <var>; // form 3
consumedFieldRef * <var>; // form 1
consumedFieldRef <Field> <var>; // form 2
consumedFieldRef <Datatype> <var>; // form 3
consumedMethodRef * <var>; // form 1
consumedMethodRef <Method> <var>; // form 2
consumedMethodRef <Prototype> <var>; // form 3
consumedServiceRef * <var>; // form 1
consumedServiceRef <Service> <var>; // form 2
consumedServiceRef <Interface> <var>; // form 3

Provider Interface

providedEventRef * <var>; // form 1
providedEventRef <Event> <var>; // form 2
providedEventRef <Datatype> <var>; // form 3
providedFieldRef * <var>; // form 1
providedFieldRef <Field> <var>; // form 2
providedFieldRef <Datatype> <var>; // form 3
providedMethodRef * <var>; // form 1
providedMethodRef <Method> <var>; // form 2
providedMethodRef <Prototype> <var>; // form 3
providedServiceRef * <var>; // form 1
providedServiceRef <Service> <var>; // form 2
providedServiceRef <Interface> <var>; // form 3

 SD Interface

  前文提到,Middleware会自行订阅。但是在少数情况下,Middleware的订阅并不是完全可靠,这种可靠性我们可以通过以下两类接口获取:

  事件接口:当指定的链接建立时触发。

on SD_connection_established <ServiceProvider>; // form 1
on SD_connection_established <ServiceConsumer>; // form 2
on SD_connection_established <ProvidedService>; // form 3
on SD_connection_established <ConsumedService>; // form 4

  服务属性:最常用的,相较于事件性更加方便。

public enum class ConnectionStateConsumer//存在于Consumer,可以在使用时访问该属性

Unavailable = 0 //No provider address for the service is known so far.
Connectable = 1	//A provider address is known for the service, but no connection has been established.
Available   = 2	//The connection is established and thus communication with the provider is (theoretically) possible.
public enum class ConnectionStateProvider//存在于Provider中的属性

Unavailable	= 0	//The provider is not in state Available or the consumer address is not yet known.
Connectable	= 1	//The provider is in state Available and the consumer address is known, but consumer and provider are not yet connected.
Connected	= 2	//A connection between consumer and provider has been established.

   当测试工程师采用上述方法发现服务链接并未完全建立时,可以采用下面的接口进行断开使Middleware再次建联。

void SD_ConnectAsync(providedServiceRef * providedService); // form 1
void SD_ConnectAsync(consumedServiceRef * consumedService); // form 2
void SD_Disconnect(providedServiceRef * providedService); // form 1
vvoid SD_Disconnect(consumedServiceRef * consumedService); // form 2

  需要注意,测试工程师在使用Provider/Consumer接口定义服务或者方法时并异步调用时,可能需要给接口提供DataType参数,具体提供什么DataTypes参数可以在Model Editor中查看VCODM。小张在研究本模块时已同Vector确认,目前最高的CANoe17版本并不支持在Capl中直接访问DataType成员,即使已经正确加载数据库文件。

Service Setting

  Middleware的重要特点便是可以重新设置服务属性,只要VCODM中配置Binding关系。需要注意,修改服务属性仅仅代表在Middleware中修改,VCODM中的配置属性不会发生变更。例如:

int main(void)
{
    consumedServiceRef PSI_DOOR_CS  Servicehandle;
    consumedMethodRef  PSI_DOOR_CS[ECU1,ECU2].setpara  Methodhandle; 

    //Check connect sate.
    if(Servicehandle.connectstate != available)
    {
        SD_Disconnect(Servicehandle);
        SD_ConnectAsync(Servicehandle);
    }
    
    Methodhandle.callAsync(0x01,0x02);

    //reset meethod handle.
    Methodhandle.SetMethod(DoorOpen);

    //continue...
    
    return 0;
}

//仅用于示例展示,具体的服务接口名称及其参数类型需要完全对应VCODM定义

  以上,便完成了服务的修改。小张推荐一个服务句柄仅用于一个服务,一个方法句柄仅用于一个方法,不可以重新Binding。故不推荐测试工程师在CAPL中修改已经定义好的服务句柄,这将导致VCODM与代码一致性降低,难以阅读维护。

参考

  Capl手册:CAPLFunctions/CommunicationObjects

posted @ 2023-08-13 22:25  张一默  阅读(98)  评论(0编辑  收藏  举报