1. 简介和功能概述
本文档说明了AUTOSAR基本软件模块Socket Adaptor(SoAd)的功能、API和配置。
数据传输的TCP/IP概念,特别是使用以太网作为物理层,已经成为计算和电信环境中的事实上的标准。应用程序的寻址、端点的逻辑寻址和物理寻址都覆盖在一套分层的协议和数字分配中。动态配置和路由是实现这些概念的核心。
AUTOSAR遵循静态通信关系(static communication relations)的概念,该概念在编译时预先确定,在运行时严格执行。传输的数据被认为与它需要往返的源和接收一样是预先确定的。
Socket Adaptor模块旨在弥合这两个概念之间的差距。通过建立一个包含AUTOSAR所需信息的预先确定的配置,并保留一些项,以便在运行时进行更新,就可以利用相互冲突的概念。此外,SoAd将基于回调(call-back based)的软件体系结构与TCP/IP世界中的基于套接字(socket based)的通信处理解耦。
SoAd模块的主要目的是在使用PDU(如:PDU Router)的AUTOSAR通信服务模块和基于socket的TCP/IP堆栈之间创建一个接口。它将I-PDU ID映射到插座连接,反之亦然。TCP/IP协议栈在TcpIp SWS中指定,如图1所示。为了便于了解,本文略示了TCP/IP堆栈的内部功能结构。
SoAd模块,以及以太网通信栈,首先在AUTOSAR R4.0.1中引入,在AUTOSAR R4.0.3和AUTOSAR R4.1.1之间有一些主要的概念并不相同。
2. 相关的文档
2.1. 输入文档
- Layered Software Architecture
AUTOSAR_EXP_LayeredSoftwareArchitecture.pdf
- General Requirements on Basic Software Modules
AUTOSAR_SRS_BSWGeneral.pdf
- Specification of Communication Stack Types
AUTOSAR_SWS_CommunicationStackTypes.pdf
- Specification of ECU Configuration
AUTOSAR_TPS_ECUConfiguration.pdf
- Specification of BSW Scheduler
AUTOSAR_SWS_BSW_Scheduler.pdf
- Specification of Default Error Tracer
AUTOSAR_SWS_DefaultErrorTracer.pdf
- Basic Software Module Description Template
AUTOSAR_TPS_BSWModuleDescriptionTemplate.pdf
- Specification of UDP Network Management
AUTOSAR_SWS_UDPNetworkManagement.pdf
- Requirements on Ethernet
AUTOSAR_SRS_Ethernet.pdf
- List of Basic Software Modules
AUTOSAR_TR_BSWModuleList
- Specification of Service Discovery
AUTOSAR_SWS_ServiceDiscovery.pdf
- Specification of PDU Router
AUTOSAR_SWS_PDURouter.pdf
- Specification of TCP/IP Stack
AUTOSAR_SWS_TCPIP.pdf
- Specification of Module XCP
AUTOSAR_SWS_XCP.pdf
- Specification of Diagnostics over IP
AUTOSAR_SWS_DoIP.pdf
- General Specification of Basic Software Modules
AUTOSAR_SWS_BSWGeneral.pdf
2.2. 相关标准及规范
- IETF RFC 4702
http://tools.ietf.org/html/rfc4702
- IETF RFC 4704
http://tools.ietf.org/html/rfc4704
3. 约束和假设
在以太网上使用TCP/IP传输数据需要大约60字节的报头信息(header information)。这意味着对于小消息,头开销可能达到一个无法接受的高百分比。
为了避免进一步的协议开销,这里描述了对每个PDU使用单个socket连接。然而,这种解决方案是非常耗费资源的,特别是在要传输许多小型PDU的情况下。这里描述的一种解决方案是添加一个包含ID和长度信息的小PDU头(PDU header)。这样可以通过一个插座连接来传输多个PDU。此外,AUTOSAR规范还包括一个资源保护方案作为一个可选项。
AUTOSAR规范不涉及UDP或TCP端口号(Port numbers)的分配。IANA分配的号码范围内没有预留空间。每个实现者负责管理使用的端口号。
SoAd标准文档也不涉及IP地址的管理。这可以是动态的,例如使用DHCP,也可以是静态的。它是实现者的责任,以防止地址冲突和实现符合IANA地址分配。
4. 对其他模块的依赖关系
4.1. AUTOSAR TCP/IP Stack
TcpIp模块实现了TCP/IP协议族中的主要协议(TCP、UDP、IPv4、ARP、ICMP、DHCP、IPv6、NDP、ICMPv6、DHCPv6),并通过以太网提供了基于socket的动态通信。SoAd模块是TcpIp模块可能的上层模块之一。
4.2. 通用的上层
SoAd模块提供了通用的上层支持,即SoAd向任何符合SoAd通用上层API/配置的上层提供服务。SoAd的每个上层可以指定它想要使用的服务类型。
在AUTOSAR体系结构中,已经定义了许多SoAd上层模块。以下列表指定了这些模块,并提供了所使用的SoAd服务的大致描述:
- PduR(PDU Router): IF-PDU和TP-PDU API
- UdpNm(UDP Network Management ): IF-PDU API
- XCP(XCP on Ethernet): IF-PDU API
- Sd(Service Discovery): IF-PDU API, Control API
- DoIP(Diagnostics over IP ): IF-PDU和TP-PDU API, Control API
5. 功能规范
SoAd通过TCP/IP网络实现基于PDU(PDU-Based)的通信。因此,AUTOSAR I-PDU被映射到由SoAd配置和维护的套接字连接(socket connections)。当多个I-PDU使用Socket连接时,可以在每个I-PDU的前面添加一个SoAd PDU头(SoAd PDU Header)。消息接受策略(A message acceptance policy)用来定义如何接受远程节点(Remote nodes)的TCP连接和UDP数据报文。套接字连接可以通过来自上层的请求自动或手动打开。同时也定义了对于套接字连接的断开和恢复的策略。SoAd的上层可以使用IF-API和TP-API的接口来进行PDU的传输和接收。SoAd的上层可以通过定义PDU路由组(PDU routing groups)有选择地使能或者禁止socket连接进出的PDU报文的路由。一个IF-PDU也可以转发给多个套接字连接。或者从一个套接字连接收到的消息可以作为不同的IF-PDU转发给同一或不同的SoAd上层(PDU Fan-out)。
注意:SoAd模块不提供任何方法来调整PDU中的位或字节顺序(Endianness)。
5.1. 套接字连接(Socket Connections)
TCP/IP通信是基于Internet套接字(Internet socket)的。Internet套接字是通信链路的端点(endpoint),由元组IP地址和端口标识。根据传输协议,套接字可被分为UDP套接字(UDP sockets)和TCP套接字(TCP sockets)。在UDP套接字中,用于通过UDP-用户数据报协议(User Datagram Protocol)进行无连接通信。而TCP套接字则用于通过TCP-传输控制协议(Transmission Control Protocol)进行面向连接的通信。TCP基于点对点(point-to-point)的通信关系。广播或多播在TCP中是不可能的。TCP要求一方建立连接,另一方接受传入的请求。两个站(stations)之间可以建立多个连接,每个连接将由不同的套接字处理,至少需要连接使用一个不同的端口号。在TCP中,所有从源发送到接收器的消息都被认为是一个按顺序的连续字节流。TCP的确认方案(acknowledgement scheme)可以保证跨消息的字节顺序的正确性。如果接收器在一定时间内没有确认接收,则消息由源重新传输。TCP保证了数据的完整性(通过校验和的方式)、字节顺序和完整性。
为了抽象TCP/IP通信,SoAd定义了套接字连接。SoAd套接字连接定义了连接的本地套接字(即本地地址标识符和本地端口)和一个远程的套接字(即远程IP地址和端口)信息,以及其他的连接参数:如传输协议;SoAd PDU头的使用;缓冲需求;连接设置;传输协议等相关参数。每个套接字连接可以由一个唯一的标识符(SoConId)来标识。每个本地套接字为了能同时支持多个通信伙伴,可以将具有相同连接参数的套接字分组成套接字连接分组(socket connection groups)。
当SoAd_OpenSoCon函数和SoAd_CloseSoCon函数分别调用时,SoAd应该存储一个打开或关闭套接字连接的请求。但根据连接设置和关闭策略,仅在SoAd_MainFunction函数中处理该请求。
5.1.1. 套接字连接打开
在SoAd_MainFunction中,SoAd应该尝试打开每个满足以下所有准则的套接字连接:
- 没有分配TcpIp Socket的套接字连接。
- SoAdSocketAutomaticSoConSetup为TRUE的隐性的请求,或者先前被SoAd_OpenSoCon函数调用的显式地请求,而该调用还没有被随后的SoAd_CloseSoCon函数调用撤销。
- 设置了远程地址(remote address is set),通过配置指定或通过调用函数SoAd_SetRemoteAddr函数。
- 分配本地IP地址(local IP address is assigned),即调用了SoAd_LocalIpAddrAssignmentChg函数,相关的LocalAddrId和TCPIP_IPADDR_STATE_ASSIGNED作为状态。
TODO: to be continue
5.2. PDU传输(PDU Transmission)
当上层模块的PDU通过UDP或TCP套接字传输时,SoAd配置指定了一条与套接字连接(Socket Connection)相连的PDU路由。一个PDU路由(SoAdPduRoute或者SoAdPduRouteDest)用来描述如何从SoAd的上层模块到TcpIp堆栈中的套接字连接(Socket connection)的路由定义。该套接字连接(Socket connection)的定义通过SoAdSocketConnection或者SoAdSocketConnectionGroup进行定义。SoAd的上层模块可以使用Interface (IF) API或Transport Protocol (TP) API分别用于传输请求和数据提供。
5.2.1. 通过IF-API传输PDU
如果使用IF-API传输上层请求的PDU,则SoAd需要完成以下操作:
- 使用SoAd_IfTransmit()提供的TxPduId来识别相关的socket连接和PDU路由
- 如果PDU长度> 0或SoAdPduHeaderEnable为TRUE,则根据连接类型调用相应的TcpIp传输函数,否则SoAd跳过进一步处理,返回E_NOT_OK。
5.2.2. 通过TP-API传输PDU
如果使用TP-API传输上层请求的PDU,则SoAd需要完成以下操作:
- 如果PDU长度为0,跳过进一步处理,返回E_NOT_OK。
- 使用SoAd_TpTransmit()提供的TxPduId来识别相关的socket连接和PDU路由。
- 将TP传输请求保存在SoAd_MainFunction()中,以便进一步处理。
在SoAd_MainFunction()中,SoAd将检查等待中的TP传输请求,并按照如下规定处理等待中的请求:
- 通过PduInfoType.SduLength = 0调用可配置回调函数<up>_[SoAd][Tp]CopyTxData(),查询上层可用数据量。
- 根据连接类型:检索数据并调用相应的TcpIp传输函数。
注意: TxPduId在SoAd配置中用来标识SoAdPduRoute,它包含一个或多个SoAdPduRouteDest容器。以及此SoAdPduRouteDest容器所使用的SoAdSocketConnection。
5.3. PDU接收(PDU Reception)
当使用UDP或TCP套接字接收PDU时, SoAd需配置一个引用套接字连接的套接字路由。套接字路由(Socket route)通过SoAdSocketRoute或者SoAdSocketRouteDest来描述了从TcpIp栈到SoAd的相关上层模块的路由。UDP或TCP套接字通过SoAdSocketConnection或者SoAdSocketConnectionGroup进行描述。SoAd的上层模块可以使用Interface (IF) API或Transport Protocol (TP) API来接收PDU。
对于接收来自UDP或TCP套接字的消息,SoAd将接收到的数据作为PDU转发给相应的上层。SoAd需要完成以下操作:
- 使用SoAd_RxIndication()提供的SocketId识别相关的套接字连接(socket connection)和套接字路由(socket routes)
- 根据消息接收策略对消息进行过滤。
- 将消息转换为PDU。
- 如果PDU长度为0且SoAdPduHeaderEnable为FALSE或SoAdRxUpperLayerType为TP,则跳过进一步处理。
- 根据SocketRouteDest配置中的SoAdRxUpperLayerType调用配置的上层模块的上层类型相关的接收函数。
5.4. TP PDU取消
可以通过调用SoAd_TpCancelReceive()和SoAd_TpCancelTransmit()发送TP取消请求。最终的请求会在SoAd_MainFunction()中被处理
5.5. 路由组(Routing Groups)
为了有选择地启用/禁用经过套接字连接的PDU路由,可以定义路由组(routing groups),同时可以由SoAd的上层模块控制。
如果SoAd_IfTransmit()被调用时,参数TxPduId指向的一个SoAdPduRouteDest属于无效RoutingGroups , SoAd需要跳过这个SoAdPduRouteDest的传输和任务传输成功。只有指向的所有SoAdPduRouteDest属于无效RoutingGroups时,SoAd才需返回错误E_NOT_OK。
如果SoAd_TpTransmit()被调用时,参数xTxPduId指向的一个SoAdPduRouteDest属于无效RoutingGroups, SoAd需要跳过这个SoAdPduRouteDest的传输和任务传输成功。只有指向的所有SoAdPduRouteDest属于无效RoutingGroups时,SoAd才需返回错误E_NOT_OK。
如果接收到的PDU指向的SoAdSocketRouteDest属于未激活的RoutingGroups, SoAd需要直接丢弃该PDU。
6. API规范
6.1. 函数定义
6.1.1. SoAd_GetVersionInfo
void SoAd_GetVersionInfo(
Std_VersionInfoType* versioninfo
)
6.1.2. SoAd_Init
void SoAd_Init(
const SoAd_ConfigType* SoAdConfigPtr
)
6.1.3. SoAd_IfTransmit
Std_ReturnType SoAd_IfTransmit(
PduIdType TxPduId,
const PduInfoType* PduInfoPtr
)
6.1.4. SoAd_IfRoutingGroupTransmit
Std_ReturnType SoAd_IfRoutingGroupTransmit(
SoAd_RoutingGroupIdType id
)
6.1.5. SoAd_IfSpecificRoutingGroupTransmit
Std_ReturnType SoAd_IfSpecificRoutingGroupTransmit(
SoAd_RoutingGroupIdType id, SoAd_SoConIdType SoConId
)
6.1.6. SoAd_TpTransmit
Std_ReturnType SoAd_TpTransmit(
PduIdType TxPduId,
const PduInfoType* PduInfoPtr
)
6.1.7. SoAd_TpCancelTransmit
Std_ReturnType SoAd_TpCancelTransmit(
PduIdType TxPduId
)
6.1.8. SoAd_TpCancelReceive
Std_ReturnType SoAd_TpCancelReceive(
PduIdType RxPduId
)
6.1.9. SoAd_GetSoConId
Std_ReturnType SoAd_GetSoConId(
PduIdType TxPduId,
SoAd_SoConIdType* SoConIdPtr
)
6.1.10. SoAd_OpenSoCon
Std_ReturnType SoAd_OpenSoCon(
SoAd_SoConIdType SoConId
)
6.1.11. SoAd_CloseSoCon
Std_ReturnType SoAd_CloseSoCon(
SoAd_SoConIdType SoConId,
boolean abort
)
6.1.12. SoAd_GetSoConMode
void SoAd_GetSoConMode(
SoAd_SoConIdType SoConId,
SoAd_SoConModeType* ModePtr)
6.1.13. SoAd_RequestIpAddrAssignment
Std_ReturnType SoAd_RequestIpAddrAssignment(
SoAd_SoConIdType SoConId,
TcpIp_IpAddrAssignmentType Type,
const TcpIp_SockAddrType* LocalIpAddrPtr,
uint8 Netmask,
const TcpIp_SockAddrType* DefaultRouterPtr
)
6.1.14. SoAd_ReleaseIpAddrAssignment
Std_ReturnType SoAd_ReleaseIpAddrAssignment(
SoAd_SoConIdType SoConId
)
6.1.15. SoAd_GetLocalAddr
Std_ReturnType SoAd_GetLocalAddr(
SoAd_SoConIdType SoConId,
TcpIp_SockAddrType* LocalAddrPtr,
uint8* NetmaskPtr,
TcpIp_SockAddrType* DefaultRouterPtr
)
6.1.16. SoAd_GetPhysAddr
Std_ReturnType SoAd_GetPhysAddr(
SoAd_SoConIdType SoConId,
uint8* PhysAddrPtr
)
6.1.17. SoAd_GetRemoteAddr
Std_ReturnType SoAd_GetRemoteAddr(
SoAd_SoConIdType SoConId,
TcpIp_SockAddrType* IpAddrPtr
)
6.1.18. SoAd_EnableRouting
Std_ReturnType SoAd_EnableRouting(
SoAd_RoutingGroupIdType id
)
6.1.19. SoAd_EnableSpecificRouting
Std_ReturnType SoAd_EnableSpecificRouting(
SoAd_RoutingGroupIdType id,
SoAd_SoConIdType SoConId
)
6.1.20. SoAd_DisableRouting
Std_ReturnType SoAd_DisableRouting(
SoAd_RoutingGroupIdType id
)
6.1.21. SoAd_DisableSpecificRouting
Std_ReturnType SoAd_DisableSpecificRouting(
SoAd_RoutingGroupIdType id,
SoAd_SoConIdType SoConId
)
6.1.22. SoAd_SetRemoteAddr
Std_ReturnType SoAd_SetRemoteAddr(
SoAd_SoConIdType SoConId,
const TcpIp_SockAddrType* RemoteAddrPtr
)
6.1.23. SoAd_SetUniqueRemoteAddr
Std_ReturnType SoAd_SetUniqueRemoteAddr(
SoAd_SoConIdType SoConId,
const TcpIp_SockAddrType* RemoteAddrPtr,
SoAd_SoConIdType* AssignedSoConIdPtr
)
6.1.24. SoAd_ReleaseRemoteAddr
void SoAd_ReleaseRemoteAddr(
SoAd_SoConIdType SoConId
)
6.1.25. SoAd_TpChangeParameter
Std_ReturnType SoAd_TpChangeParameter(
PduIdType id,
TPParameterType parameter,
uint16 value
)
6.1.26. SoAd_ReadDhcpHostNameOption
Std_ReturnType SoAd_ReadDhcpHostNameOption(
SoAd_SoConIdType SoConId,
uint8* length,
uint8* data
)
6.1.27. SoAd_WriteDhcpHostNameOption
Std_ReturnType SoAd_WriteDhcpHostNameOption(
SoAd_SoConIdType SoConId,
uint8 length,
const uint8* data
)
6.1.28. SoAd_GetAndResetMeasurementData
Std_ReturnType SoAd_GetAndResetMeasurementData(
SoAd_MeasurementIdxType MeasurementIdx,
boolean MeasurementResetNeeded,
uint32* MeasurementDataPtr
)
微信扫一扫,获取更多及时资讯
