|
汽车零部件采购、销售通信录 填写你的培训需求,我们帮你找 招募汽车专业培训老师
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入门-基于以太网诊断),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_HandleTcpRxDoIp_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 加颜色跟报文对应打印处理为:
02 fd 80 01 00 00 00 6 0e 80fe ed11 1
payloadType 0x8001,表示发送的诊断请求。
然后进入DoIP的协议栈进行处理
handleDiagnosticMessagelookupResult = 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入门 |
|