SOMEIP

目的

本文档旨在通过一个SOMEIP示例工程的配置,向用户展示SOMEIP的集成过程。

通过阅读本文档,用户可以了解ORIENTAIS配置工具的配置过程,以及如何应用配置工具生成的配置文件。

为了让用户更清晰的了解工具的使用,所用的配置均逐一手动完成。用户在了解了配置的基本过程后,可以快速完成配置。

缩写词和术语

表 缩写词和术语

缩写词/术语

描述

SoAd

Socket Adapter 将socket的数据和PDU进行转换

Sd

Service Discovery 服务发现模块

SOMEIP

Scalable service-Oriented MiddlewarE over IP 可扩展的面向服务的IP中间件

RTE

Runtime Enviroment 虚拟运行唤醒

SWC

Software Component 软件组件

参考文档

[1] 参考手册_Sd.pdf

[2] 参考手册_SomeIpTp.pdf

[3] 参考手册_SomeIpXf.pdf

协议栈集成

新建ORIENTAIS工程

  1. 安装ORIENTAIS Manager软件,Install SnapShot后双击Controller列名称打开软件。

    image1

    图 新建工程-1

  2. 菜单栏File🡪New🡪Project,新建工程

    image2

    图 新建工程-2

  3. 在弹出的新建窗口中选择Autosar下的 [BSW Project],选择Next

    image3

    图 新建工程-3

  4. 在弹出的窗口中输入工程名,选择Finish

    image4

    图 新建工程-4

  5. 在弹出的窗口中选择Yes。

    image5

    图 新建工程-5

  6. 在工程的[Bsw_Builder]项目上右键,选择New ECU Configuration

    image6

    图 新建工程-6

  7. 在弹出的窗口中输入一个ECU名,然后选择Next

    image7

    图 新建工程-7

  8. 在弹出的窗口中勾选需要添加的模块,点击Finish。

    image8

    图 新建工程-8

  9. 新建完成的工程如下所示,步骤7中添加的模块已经被加入到工程中。

    image9

    图 新建工程-9

配置文件生成

模块配置

模块的具体配置,取决于具体的项目需求。SOMEIP各模块配置项的详细介绍,参见《参考手册_Sd.pdf》、《参考手册_SomeIpTp.pdf》、《参考手册_SomeIpXf.pdf》。

配置代码生成

  1. 在工程上右键会弹出校验整个工程和生成整个工程所有模块配置文件的菜单。

  2. 首先选择Validate All,没有错误提示信息即校验通过。

    image10

    图 配置代码的生成-1

  3. 然后选择Generate All,生成配置文件。右下角的输出框中会输出生成的配置文件信息。

    image11

    图 配置代码的生成-2

  4. 在工程Config文件夹下即可查看生成的配置文件。

    image12

    图 配置代码的生成-3

功能集成

代码集成

协议栈代码包括两部分:项目提供的协议栈源码和ORIENTAIS Studio配置生成代码。SOMEIP集成包括SOMEIP源码(SD、SomeipXf)。

用户须将协议栈源码和章节(配置代码生成)生成的配置源代码添加到集成开发工具的对应文件夹。协议栈集成的文件结构,见章节(源代码集成)。

Note

协议栈集成之前,用户须确保已经有基础工程,以及以太网通信协议栈已集成,且本协议栈相关的其他协议栈能正常工作。

集成注意事项

对于集成过程中,协议栈特殊要求和用户经常出现的问题,归类总结形成下表。用户需逐一排查表中的约束项,以避免集成问题出现。

表 SOMEIP集成约束清单

编号

类别

约束限制

1

堆栈

用户需确保为任务堆栈和中断堆栈分配足够的堆栈空间。

2

头文件

  • 添加协议栈代码之后,用户需更新集成开发工具中的头文件路径。

  • 调用协议栈API的源文件,需要包含协议栈的头文件。

3

初始化

SOMEIP协议栈的初始化顺序为:EthIf_Init, TcpIp_Init, SoAd_Init,SomeIpXf_Init,Sd_Init。

4

周期函数

EthSM_MainFunction,EthIf_MainFunctionState,Sd_MainFunction, ComM_MainFunction_<ComMChannel_ETH>需要被周期性任务函数调用。

配置过程

集成目标

本手册会以以下参数作为示例,进行集成演示。

表 配置参数

参数

SdServerService实例参数

SdServerServiceId:0x1

SdServerServiceInstanceId:0x1

SdServerServiceMajorVersion:1

SdServerServiceMinorVersion:1

SdServerTimer时间参数

SdServerTimerInitialOfferDelayMax:0.1

SdServerTimerInitialOfferDelayMin:0.0

SdServerTimerInitialOfferRepetitionBaseDelay:0.03

SdServerTimerInitialOfferRepetitionsMax:3

SdServerTimerOfferCyclicDelay:1.0

SdServerTimerRequestResponseMaxDelay:0.5

SdServerTimerRequestResponseMinDelay:0.0

SdServerTimerTTL:300

Socket信息

Sd单播本地:172.31.30.78/ UDP/30490

Sd多播本地:239.192.255.250/ UDP/30490

AddMethod本地:172.31.30.78/ TCP/12310

AddMethod远端:172.31.30.80/ TCP/0(端口号为通配符)

序列化参数

加法运算请求参数:

typedef struct

{

    uint16 number_a;

    uint16 number_b;

} AddMethodReq;

加法运算结果参数:

typedef uint32 AddMethodResp;

模块配置

EcuC模块配置

  1. 双击EcuC模块,打开EcuC模块配置界面。

  2. 在EcucConfigSets栏目上右键新建 EcucConfigSet。

  3. 再在EcucPduCollections上右键新建EcucPduCollection。配置PduIdTypeEnum为UINT16,PduLengthTypeEnum为UINT32。

    image13

    图 EcuC 模块配置-1

  4. 在EcucPduCollection上右键,选择Pdu,生成一个Pdu的配置界面。

    image14

    图 EcuC 模块配置-2

  5. 配置4个PDU用于加法运算服务的收发,pdu长度为500, SoAd_SdInstance0_AddMethodReq、LdCom_SdInstance0_AddMethodReq、SoAd_SdInstance0_AddMethodResp、LdCom_SdInstance0_AddMethodResp;

    配置3个PDU用于用于SD模块的单/多播收发,pdu长度1400, SdInstance0_Unicast_Rx、SdInstance0_Multicast_Rx、SdInstance0_Tx。

    image15

    图 EcuC 模块配置-3

  6. ECUC模块配置完成,在模块上右键,选择校验。

    image16

    图 EcuC 模块配置-4

  7. 查看校验窗口,校验提示窗口没有错误信息,即校验通过。

    image17

    图 EcuC 模块配置-5

Tcpip模块配置

  1. 在TcpIp模块添加Sd模块使用的多播地址239.192.255.250。

    image18

    图 Tcpip模块配置-1

    image19

    图 Tcpip模块配置-2

    image20

    图Tcpip模块配置-3

  2. 按照步骤1配置SD模块单播地址172.31.30.78.

  3. 校验后提示窗口没有错误信息,即校验通过。

SoAd模块配置

  1. 配置SoAdGeneral,配置调度周期0.005S,Socket最大个数4和SocketGroup的最大个数10。

    image21

    图 SoAd模块配置-1

  2. 配置SoAdBswModules,本例中需关联SD和PDUR,所以新建两个模块并配置SoAdBswModuleRef关联对应模块。

    image22

    图 SoAd 模块配置-2

  3. 配置SoAdSocketGroup,Sd和AddMethod Server各配置一个

    image23

    图 SoAd 模块配置-3

    image24

    图 SoAd 模块配置-4

#. 配置SoAdSocketConnectionGroup;Sd采用多播/单播收发,需要配置2个Socket,分别用于单播发送/多播发送/单播接收和多播接收;AddMethod Server是TCP Server,需要配置一个Socket。

其中单播收发的Socket配置如下:

image25

图 SoAd 模块配置-5

image26

图 SoAd 模块配置-6

image27

图 SoAd 模块配置-7

多播的Socket配置如下:

image28

图 SoAd 模块配置-8

image29

图 SoAd 模块配置-9

image30

图 SoAd 模块配置-10

AddMethod Server的配置如下:

image31

图 SoAd 模块配置-11

image32

图 SoAd 模块配置-12

image33

图 SoAd 模块配置-13

  1. 配置SoAdPduRoute,即报文发送。

    image34

    图 SoAd 模块配置-14

    image35

    图 SoAd 模块配置-15

    image36

    图 SoAd 模块配置-16

    image37

    图 SoAd 模块配置-17

  2. 配置SoAdSocketRoute,即报文接收。

    image38

    图 SoAd 模块配置-18

    image39

    图 SoAd 模块配置-19

    image40

    图 SoAd 模块配置-20

    image41

    图 SoAd 模块配置-21

    image42

    图 SoAd 模块配置-22

    image43

    图 SoAd 模块配置-23

  3. 校验后提示窗口没有错误信息,即校验通过。

Sd模块配置

  1. SdGeneral页面配置

    image44

    图 Sd模块配置-1

  2. 配置SdConfig。

  3. 新建一个SdInstance, SdAddrFamily选择TCPIP_AF_INET。

    image45

    图 Sd模块配置-2

  4. 配置Sd的Pdu,一个多播接收Pdu,一个发送Pdu,一个单播接收Pdu。

    image46

    图 Sd模块配置-3

    image47

    图 Sd模块配置-4

    image48

    图 Sd模块配置-5

  5. 右键新建一个SdServerTimer,并配置。

    image49

    图 Sd模块配置-6

  6. 右键新建一个SdSeverService,并配置。

    image50

    图 Sd模块配置-7

  7. 新建一个SdProvidedMethod,并配置。

    image51

    图 Sd模块配置-8

  8. 校验后提示窗口没有错误信息,即校验通过。

Ldcom模块配置

  1. 打开LdcomGeneral,配置Ldcom使用的回调函数声明头文件。

    image52

    图 Ldcom模块配置-1

  2. 打开LdcomConfig,配置AddMethod Server报文的收发。

    image53

    图 Ldcom模块配置-2

    image54

    图 Ldcom模块配置-3

  3. 校验后提示窗口没有错误信息,即校验通过。

PduR模块配置

  1. PduRGemeral页面保持默认配置,不用修改。

  2. ②打开PduRBswModeles,新建并配置PduRBswModules_LdCom、PduRBswModules_SoAd。

    image55

    图 PduR模块配置-1

    image56

    图 PduR模块配置-2

  3. 打开PduRRoutingTables,并新建PduRRoutingTable,配置AddrMethod Server报文的收发路由。

    image57

    图 PduR模块配置-3

    image58 image59

    图 PduR模块配置-4

    image60

    图 PduR模块配置-5

    image61 image62

    图 PduR模块配置-6

  4. 校验后提示窗口没有错误信息,即校验通过。

Xfrm模块配置

  1. 新建DataTypeDescription,并配置序列化使用的参数类型和结构体。

    image63

    图 Xfrm模块配置-1

    image64

    图 Xfrm模块配置-2

    image65

    图 Xfrm模块配置-3

    image66

    图 Xfrm模块配置-4

    image67

    图 Xfrm模块配置-5

  2. 打开TransformationSet页面,新建并配置一个SOMEIP序列化使用的TransformationTechnology。

    image68

    图 Xfrm模块配置-6

  3. 新建一个SOMEIPTransformationDescription,配置序列化的字节对齐方式以及数据大小端类型。

    image69

    图 Xfrm模块配置-7

  4. 打开BufferProperty,配置序列化报文HeaderLenght长度为16bits。

    image70

    图 Xfrm模块配置-8

  5. 打开SomeIpXfPublic,新建并配置两个SOMEIPTransformationlSignaProp。

    image71

    图 Xfrm模块配置-9

    image72

    图 Xfrm模块配置-10

  6. 新建并配置两个ClientServerInterface。

    image73

    图 Xfrm模块配置-11

    image74

    图 Xfrm模块配置-12

  7. 新建并配置两个SomeIpXfConfig。

    image75

    图 Xfrm模块配置-13

    image76

    图 Xfrm模块配置-14

  8. 在TransformationSet页面,新建并配置两个Transformations,以生成对应的序列化/反序列化函数。

    image77

    图 Xfrm模块配置-15

    image78

    图 Xfrm模块配置-16

  9. 校验后提示窗口没有错误信息,即校验通过。

源码集成

项目交付给用户的工程结构如下:

image79

图 源码集成

  1. Config目录,这个目录用来存放基础软件配置工具生成的配置文件,SOMEIP有关的配置文件放在该文件夹中。

  2. 模块相关的静态源代码,存放在各个模块的文件夹下。

调度集成

  1. 将章节(模块配置及代码生成)生成的配置文件复制到Config文件夹中。

  2. 添加初始化函数和周期调用函数。

Note

本示例中, SOMEIP初始化的代码和启动通信的代码置于main.c文件,并不代表其他项目同样适用于将其置于main.c文件中。

 1#include "Timer.h"
 2#include "Led.h"
 3#include "Mcal_User.h"
 4#include "UserTimer.h"
 5#include "Dio.h"
 6#include "ComM.h"
 7#include "ComM_Internal.h"
 8#include "Can.h"
 9#include "E2EXf.h"
10#include "CanNm.h"
11#include "EthIf.h"
12#include "EthSM.h"
13#include "TcpIp.h"
14#include "SoAd.h"
15#include "LdCom.h"
16#include "TestCase.h"
17#include "Wdg.h"
18#include "WdgM.h"
19#include "Mcu.h"
20#include "ringbuf.h"
21#include "Sd.h"
22// SOMEIP协议栈相关头文件
23#include "SomeIpXf.h"
24
25int main(void)
26{
27    eth_ringbuf_init(&g_EthRingBufManager, &g_EthRxPduBuf, ARRAR_SIZE(g_EthRxPduBuf));
28    McalUser_Init();
29
30    // 初始化核心通信模块
31    PduR_Init(&PduR_PBConfigData);
32    ComM_Init(&ComM_Config);
33
34    EthIf_Init(&EthIf_ConfigData);
35    EthSM_Init();
36    TcpIp_Init(&TcpIp_Config);
37    SoAd_Init(&SoAd_Config);
38    LdCom_Init(&LdCom_InitCfgSet);
39    SomeIpXf_Init(&SomeIpXf_Config);  // 初始化SOMEIP适配层
40    Sd_Init(&Sd_Config);
41
42    // 使能ETH通信通道并请求全通信模式
43    ComM_ChComAllow(ComMUser_ETH, TRUE);
44    ComM_RequestComMode(ComMUser_Eth, COMM_FULL_COMMUNICATION);
45
46    while (1)
47    {
48        // 1ms周期任务:处理以太网状态机
49        if (UserTimer_GetFlag1ms())
50        {
51            EthSM_MainFunction();
52            UserTimer_ClrFlag1ms();
53        }
54
55        // 2ms周期任务:处理以太网接口状态
56        if (UserTimer_GetFlag2ms())
57        {
58            EthIf_MainFunctionState();
59            UserTimer_ClrFlag2ms();
60        }
61
62        // 5ms周期任务:处理TCP/IP和Socket适配
63        if (UserTimer_GetFlag5ms())
64        {
65            ethif_read_buf();
66
67            TcpIp_MainFunction();
68            SoAd_MainFunction();
69            ComM_MainFunction(ComMUser_Eth);
70
71            UserTimer_ClrFlag5ms();
72        }
73
74        // 10ms周期任务:发送测试PDU和服务发现
75        if (UserTimer_GetFlag10ms())
76        {
77            TestCase_Send_EthPdu();
78            Sd_MainFunction();  // 服务发现模块周期处理
79
80            UserTimer_ClrFlag10ms();
81        }
82    }
83}

SomeIpXf相关的代码示例需要在LdCom添加函数实现:

 1#include "SomeIpXf.h"
 2
 3/* 实现一个加法运算服务 */
 4void LdComRxInd_SdInstance0_AddMethodReq(const PduInfoType* PduInfoPtr)
 5{
 6    if ((NULL_PTR != PduInfoPtr) && (NULL_PTR != PduInfoPtr->SduDataPtr))
 7    {
 8        AddMethodReq request;  // 定义加法请求结构体
 9        Rte_Cs_TransactionHandleType TransactionHandle;
10
11        // 解析SOMEIP请求数据
12        if (E_OK == SomeIpXf_Inv_AddMethodReq(&TransactionHandle, PduInfoPtr->SduDataPtr, PduInfoPtr->SduLength, &request))
13        {
14            uint8 data[128];  // 响应数据缓冲区
15            uint32 sum = request.number_a + request.number_b;  // 执行加法运算
16            uint16 length = 0;
17
18            // 构建SOMEIP响应数据
19            if (E_OK == SomeIpXf_AddMethodResp(&TransactionHandle, data, &length, &sum))
20            {
21                PduInfoType pdu;  // 定义PDU结构体
22
23                pdu.SduLength = length;       // 设置响应数据长度
24                pdu.SduDataPtr = data;        // 指向响应数据缓冲区
25                pdu.MetaDataPtr = NULL_PTR;    // 无元数据
26
27                // 发送SOMEIP响应
28                LdCom_Transmit(SdInstance0_AddMethodResp, &pdu);
29            }
30        }
31    }
32}
33
34// 响应发送完成回调
35void LdComTxConf_SdInstance0_AddMethodResp(void)
36{
37    // 可添加发送完成后的处理逻辑
38}

验证结果

  1. 使用wireshark监控Offer Service正常多播发送,符合集成目标。

    image80

    图 验证结果-1

  2. 使用调试助手,发送多播/单播 Find Service报文,都可以接收到单播的Offer Service报文,控制器返回正确,符合预期目标。

    image81

    图 验证结果-2

#. 使用调试助手,连接AddMthod TCPserver,发送加法运算请求报文,控制器返回正确运算结果,符合预期目标。

image82

图 验证结果-3