AUTOSAR入门-DoIP模块
原创 thatway 那路谈OS与SoC嵌入式软件 2022-04-19 18:03
AUTOSAR入门-DoIP模块
聊**DoIP**
前,我们先来聊聊通信
。烽火戏诸侯
的故事大家都知道,古代在遇到危急情况比如边关有敌军
来侵袭或者王都要告急的时候,就需要点燃烽火
,相近的烽火台把守人员看到附近的狼烟后也点燃自己的烽火,这样信息就会依次传递
,最后到达目地去,正所谓“十万火急
”。
**烽火**
算是通信的最原始的版本,汽车中的通信也差不多
是这样的。本文会先对通信进行一个概况说明,不局限
于基于以太网通信的DoIP,会涉及一些
计算机网络
的知识,然后结合真实的代码,给你一个
程序员眼中
的AUTOSAR
。
- 通信的发展
上面提到使用
烽火
进行传递信息,这是一种比较原始低级的方式,烽火只有两种状态点燃
和熄灭
代表两种含义:
有敌人
和没有敌人
。比如想知道敌人的首领是谁,就需要更加复杂的信息,需要通信双方写一封信
,使用
语言文字
进行说明。解决了信的内容问题,如果要管理非常多的边关信息,那么还需要有一个网络,比如驿站网络
对信件进行分类转发,实现更加复杂的功能,实现全面通信。
总结下:烽火-》信件-》驿站
。
烽火
:
这种通信可以堪称基于**信号**
的,烽火两种状态点燃或者不点燃,就像一个开关,二进制里面就是0
和1
两种状态,有点像汽车里面的
LIN总线
(LocalInterconnect Network
)-局部互联协议
。使用一根线传递0和1就可以了。
信件
:
写信需要有格式,**时间地点人物**
,主谓宾
才能描述一个事情。这就像把0和1组织起来来说明一件事情,规定好一串01是什么意思,形成报文
。这像汽车里面使用的CAN协议(
控制器局域网总线 Controller Area Network**)**
,把0和1的二进制规定为如下报文:
提到协议自然要说到ISO组织,这个ISO规定各种报文协议,对于CAN来说,ISO-11898
规定了高速CAN,ISO11519
规定了低速CAN(公众号回复ISO获取
)。
驿站
:
比如很多部队很多边关这时候要通信,不可能都一对一,不同单位间通信需要**中转**
的机构,按层级进行通信。这有点像计算机网络里面路由器
的概念,可以进行万物互联
。上面说的LIN和CAN都是车内通信,如果想在
世界上任意一个地方
就可以跟某一个车通信这时候就需要Eth以太网
通信了,基于TCP/IP
,报文可以进行路由转发
。
以太网可以实现的报文相对于CAN复杂度上升了很多,可以说是报文套报文
,套了好多层,功能自然也强悍了很多倍。除了功能比CAN强悍,性能比如传输速度和距离也比CAN要好。
烽火(LIN)-》信件(CAN)-》驿站(ETH)
对应在AUTOSAR框架里面如下:
可以看到从**LIN-》CAN-》Eth**
通信能力是在增强
的,通信的内容增多
,速度加快,传输距离也增强了。但是为什么不用能力最强的Eth淘汰掉其他的呢?首先低级的通信方式成本低
,LIN只用一两根线,Eth需要8根线。其次是因为安全性
,能力和安全不能兼得,能力弱的往往更可靠,更安全不出错。忽略成本的前提下,当然能力强的替代能力弱的是趋势,前提是把安全提上去。
下面介绍下各种通信协议在汽车中的常见应用:
上图说明了一些常见的功能使用的什么协议,比如车窗只有升降那采用**LIN**
就可以。空调功能有点多,用CAN
就可以。
上图说明了一些**CAN总线**
的使用,低速CAN跟LIN有一些重叠,看实际设计了。
上图说明了车内**域控制器间**
使用Eth通信的例子。
这个图说明了车跟**外部通信**
的例子,大部分是基于Eth的Inetnet,比如OTA升级。
其他:
在AUTOSAR的通信图中,好像遗漏了一个**FlexRay**
。FlexRay只从功能上进行了改进,跟CAN一个层次。并不像Eth那么颠覆性的改变。
首先FlexRay还是**车内联网,**
跟CAN一个层次。其次其采用基于时间触发机制,具有高带宽、容错性能好
等特点,在实时性、可靠性和灵活性
方面比CAN有一定的优势。
当然如果使用**Eth以太网**
,进行
降维打击
,FlexRay的优点,在Eth上都可以实现。
2.DoIP AUTOSAR和ISO规范
2.0准备工作
首先官网规范去
https://www.autosar.org下载
《AUTOSAR_SWS_DiagnosticOverIP.pdf》
然后DoIP对应的ISO规范ISO13400(公众号回复ISO获取
)
2.1 DoIP是什么?
打开
《AUTOSAR_SWS_DiagnosticOverIP.pdf》
这里其实就是说**DoIP实现了ISO13400规定的协议内容**
,然后DoIP是什么就去参考ISO13400吧。这个图左侧就是基于Eth的DoIP通信到Dcm的过程,这个图很重要,看代码的时候在各个模块跳来跳去,这个图就是总纲领
。
打开《ISO 13400-2-2012.pdf》
对应软件编程来说主要就是ISO13400的**第二部分**
,规定了报文的格式
。进行诊断在Dcm里面都说了使用UDS报文
,这里为什么还需要DoIP
?
这个在之前的文章里面解释过([AUTOSAR入门-基于以太网诊断](http://mp.weixin.qq.com/s?__biz=MzUzMDMwNTg2Nw==&mid=2247483815&idx=1&sn=8603d2994641cbbb02d48ac0313d074b&chksm=fa528783cd250e9524080071c93ed2d7db49a074824f264587bd317f3fda28e746657c7161de&scene=21#wechat_redirect)
),UDS只是负责诊断的业务功能,可以基于很多网络比如Eth、CAN、LIN。但是基于Eth的时候,以太网有很多新的功能,比如路由、会话、DHCP、TCP等
需要一个模块去维护,这个模块就是DoIP
。简单来说就是网络通信附加的功能
都交给DoIP
处理,最后剥离处理UDP报文
再通过PduR模块传递给Dcm
模块处理。
DoIP整个过程简化一个图:
刚开始是基于UDP不可靠的传输,需要进行DHCP
过程,网络通信需要基于IP
就像地址。我们的AS平台暂时没实现DHCP,IP是配置死的为:172.18.0.200
com/as.application/common/config/SoAd_Cfg.c中
然后基于TCP,首先需要
激活路由
,之后才能发送诊断报文,这时候诊断报文剥离出来才能送到Dcm模块。
下面看下具体的DoIP报文的格式什么样的。在AUTOSAR入门-基于以太网诊断
中,我们在ubuntu中发DoIP报文
给qemu中,172.18.0.200的网卡
,端口号是13400
,发的tcp报文,
第一条DoIP报文是0005
表示路由激活
,
第二条DoIP报文是8001
表示诊断请求
,如下:
DoIP报文格式参考AUTOSAR入门-基于以太网诊断
中说明就可以。这里给一个图:
有不懂的地方对照ISO13400-2文档Table12
中详细说明
2.3 建立连接过程
上面client发送了路由激活命令就算建立连接了,省略了之前的几步,完整的如下:
诊断连接建立分三步:1.DHCP 2.UDP广播找设备3.TCP路由激活
,如下:
当DoIP实体和外部测试设备都连接到一个网络中时,它们会利用DHCP
协议获得一个属于自己的IP地址
。在网络中,路由器作为DHCP server,为新加入到该网络中的设备分配IP地址。在获取IP地址之后,车辆发现有两种方式:
DoIP设备启动后,首先通过UDP广播的形式把一条DoIP报文(vehicle announcement message
,Payload Type为0x0004
)发给网络上的所有的其他节点,其中就包括诊断仪,目的端口是13400
,其中这条消息携带了DoIP设备的DoIP版本、VIN、logical address等信息,这条信息会发送三次
,而之前监听在13400端口的诊断仪接收到这条信息,就知道了DoIP设备的基本信息。如果诊断仪没有收到,还有一种办法,就是诊断仪这边主动请求,通过UDP广播的形式,主动发一条DoIP request
消息(Payload Type为0x0001
),目的端口号是13400,而之前启动后就一直监听在13400的DoIP设备,接收到这条消息后,就会回复一条携带自己信息的response
0x0004
给诊断仪在TCP连接建立后,诊断仪还需要发送一条Routing activation request(Payload Type为0x0005
)的DoIP报文给DoIP设备,DoIP设备收到后会回复一条Routing activation response
(Payload Type为0x0006
)的DoIP报文,此时诊断连接建立,双方可以诊断通信。
2.2 DoIP交互的模块
参考之前那个通信图,看下
依赖模块
SoAd
:SocketAdaptor是DoIP模块的底层模块。它提供了:
Socket连接建立和通知的接口和回调
多套接字连接的数据传输
通过多个套接字连接接收数据
Socket状态变化通知
IP地址状态变更通知
PduR
:Pdu Router
Pdu路由器12是DoIP模块用来连接到通信堆栈的其余部分的模块。它提供了:
·将DoIP模块的诊断消息转发给其他模块(即内部Dcm或其他TP模块)
·将Dcm或其他TP模块的诊断消息转发给DoIP模块。
Dcm
:DiagnosticCommunication Manager
诊断通信管理器4是向DoIP模块提供VIN(车辆识别号码的模块)。此外,Dcm将执行经PduR路由的ECU局部诊断。
Det
:Default ErrorTracer
DoIPDevelopmentErrorDetect设置为true,并且使用不正确的参数调用DoIP API,则使用错误ID调用默认错误跟踪器7。
2.3DoIP报文头处理
DoIP模块处理DoIP报文的过程如下:
3. AS平台代码实现
还是结合实际的例子进行讲解,我们之前做的实验:AUTOSAR入门-基于以太网诊断
。报文传递的过程为:网卡驱动-》网络接口-》LWIP网络协议栈-》SoAd模块-》DoIP模块-》PduR模块-》Dcm模块
。
Dcm和PduR模块都讲了,本次我们聚焦到DoIP模块。上次我们说DoIP模块调用
PduR_SoAdTpRxIndication
PduR_SoAdTpProvideRxBuffer
这两个函数发消息给Dcm模块。
DoIP收到报文的入口为:
DoIp_HandleTcpRx
DoIp_HandleTcpRx
DoIp_HandleRxInternal(sockNr, FALSE);
nBytes = SoAd_RecvIpMessage(sockNr, rxBuffer,.....);
payloadType =((uint32)rxBuffer[2] << 8) | rxBuffer[3];
witch (payloadType) {
case DOIP_PLT_UDP|0x8001:
handleDiagnosticMessage(sockNr, payloadLength, rxBuffer);
}
rxBuffer 加颜色跟报文对应打印处理为:
0
2**fd
80 0100 00 00 60e 80fe ed
11 1**
payloadType 0x8001
,表示发送的诊断请求。
然后进入DoIP的协议栈进行处理
handleDiagnosticMessage
lookupResult = lookupSaTa(connectionIndex, sa, ta,&targetIndex);
if (lookupResult == LOOKUP_SA_TA_OK) {
result=PduR_SoAdTpProvideRxBuffer(SoAd_Config.DoIpTargetAddresses[targetIndex].rxPdu,diagnosticMessageLength,&pduInfo);
pduInfo->SduLength = diagnosticMessageLength;
memcpy(pduInfo->SduDataPtr, &rxBuffer[12],diagnosticMessageLength);
PduR_SoAdTpRxIndication(SoAd_Config.DoIpTargetAddresses[targetIndex].rxPdu,NTFRSLT_OK);
createAndSendDiagnosticAck(sockNr, sa, ta);
}
可以看到PduR_SoAdTpProvideRxBuffer和
PduR_SoAdTpRxIndication都调用了。
DoIP通过PduR发送报文到Dcm模块,分为三个步骤:
PduR_SoAdTpProvideRxBuffer 告诉要发送的数据长度和内存位置
memcpy 内存拷贝
,在最新的autosar规范中这个也变成一个接口直接传送内存地址,不进行拷贝了PduR_SoAdTpRxIndication 通知Dcm模块传输完成
最后DoIP模块执行
createAndSendDiagnosticAck
给客户端回复处理成功的消息,这里可以在ubuntu中安装wireshark进行
网络报文抓包
,可以看到整个网络报文交互
过程。
小技巧:
如果你不知道**DoIp_HandleTcpRx**函数在那个.c文件中,可以在AS根目录执行命令:**grep -Rn "DoIp_HandleTcpRx"**
后记:
其实这一些列介绍AUTOSAR的文章都是以AS平台的**实验**
:AUTOSAR入门-基于以太网诊断
为基础的,之前写了怎么搭建实验运行环境
:AUTOSAR入门-AS开源代码运行环境搭建
,但是对于很多编程薄弱不了解linux的人有些难度
,后续我再补充写一篇介绍怎么搭建环境的。
欢迎留言或者消息回复,**感兴趣**
的地方和有疑问
的地方,我补充文章发出来。
Talk is cheap,show methe code!
后续会继续更新,纯
干货
分享,无广告,不打赏,欢迎
转载
,欢迎
评论交流
!
往期见话题标签:
AUTOSAR入门