UDS协议详解系列:CanTp6

发布于 2023-2-15 15:32
浏览
1收藏

欢迎来到​《UDS协议详解系列》​的第6篇文章,本文将介绍CanTp的接收和发送过程:先简单介绍下CanTp模块,然后分别介绍下SF,FF,CF和FC的接收过程,再通过实例来理解CanTp接收,最后分别介绍SF,FF,CF和FC的发送过程。

1 CanTp模块

当诊断服务基于CAN总线实现,如果请求或响应的诊断数据超过8个字节,而一帧CAN信息只能传输8个字节的数据,这就意味着诊断数据无法通过一帧CAN信息传输完。那怎么办呢?自然地,我们想到的一种方案是分割诊断数据,通过多帧CAN信息来传输;另一种方案是让一帧CAN信息传输出更多的数据。针对前者就提出了ISO15765协议,针对后者有了CAN FD。现如今CAN FD可传输64个字节长度的数据,但诊断数据超过64个字节,仍将面临上述问题。不过通过对ISO15765协议的了解,你会发现这个协议可彻底解决诊断数据过长问题。


ISO15765协议定义了两种传输机制(单帧传输和多帧传输),四种协议数据单元类型(单帧SF,首帧FF,续帧CF和流控帧FC)和相关的网络层定时参数(N_As,N_Ar,N_Bs,N_Br,N_Cs和N_Cr),如图1所示。

UDS协议详解系列:CanTp6-汽车开发者社区

图1 两种传输机制,引自[1]


本文将介绍的CanTp模块是ISO15765协议的软件实施,CanTp模块的最主要作用是分割和组装超过8个字节长度的CAN I-PDUs。在基于AUTOSAR架构的通讯栈中,CanTp模块位于PDU Router和CAN Interface模块之间,如下图2所示。

UDS协议详解系列:CanTp6-汽车开发者社区

图2 AUTOSAR 通讯栈,引自[2]


CanTp模块提供的服务有:发送方向分割数据,接收方向组装数据和控制数据流等。在接收方向CanIf模块经CanTp_RxIndication函数通知CanTp模块;在发送方向CanTp模块调用CanIf_Transmit函数来发送数据,如下图3所示。

UDS协议详解系列:CanTp6-汽车开发者社区

图3 CanTp与其上下层的交互,引自[2]


下面我们来了解下具体的接收与发送过程。

2 接收过程

当通过一帧CAN信息接收到8个字节的诊断服务数据,根据ISO15765协议可知,这个数据将是SF或FF或CF或FC。因此不难理解:CanTp模块应先识别接收数据的类型(N_PCItype)。然后再提取数据,由于网络层数据的交换支持三种寻址格式格式:正常格式(normal),扩展格式(extended)和混合格式(mixed),因格式不同数据长度将有区别:正常格式有7个字节数据,扩展格式和混合格式有6个字节数据,如图4所示。故先根据寻址格式确定数据长度,再提取数据。最后根据不同数据类型进行相应的接收处理。

UDS协议详解系列:CanTp6-汽车开发者社区

图4 不同寻址格式的定义,引自[1]

2.1 SF(单帧)接收处理

考虑到CanTp模块没有缓冲能力,CanTp将直接作用于上层(比如PduR或DCM)的存储区域。要访问这些存储区域,CanTp模块将使用PduR_CanTpCopyRxData函数。同时为了保证数据的一致性,上层必须锁定这些存储区域直到一个通知发生。这里CanTp模块将使用PduR_CanTpStartOfReception函数来通知上层的PduR模块,这样上层的模块将为接收的数据保留和锁住buffer,如下图5所示。

UDS协议详解系列:CanTp6-汽车开发者社区

图5 接收buffer的锁定状态切换示意,引自[2]


针对接收到一帧SF的情况,从CanIf模块到CanTp模块的大致过程为:


1.下层接收到一帧诊断服务的数据,经CanIf调用CanTp_RxIndication函数通知CanTp模块;


2.CanTp模块先根据N_PCItype识别出是SF,在考虑了寻址格式的基础上,确定取数据长度;


3.CanTp模块由于自身没有缓冲能力,将调用PduR_CanTpStartOfReception函数向上层确认是否有足够的buffer大小来存储接收的数据;


4.上层分配和锁定所需的接收buffer。且返回BUFREQ_OK,然后CanTp模块调用PduR_CanTpCopyRxData函数让上层把接收的数据复制到接收buffer;


5.当复制成功完成,CanTp调用PduR_CanTpRxIndication函数通知上层。


这就是理想的SF接收成功的基本过程,如下图6所示。

UDS协议详解系列:CanTp6-汽车开发者社区

图6 SF接收过程,引自[2]


但实际的SF接收可能会有一些原因导致接收不成功,比如:


  • 由于错误或资源限制原因,上层不能使buffer有效。那么PduR_CanTpStartOfReception将返回buffer状态NOT_OK或溢出,这时CanTp模块将丢弃接收的数据,也不会调用PduR_CanTpRxIndication函数;


  • 如果PduR_CanTpStartOfReception返回buffer状态OK,但有效bufferd的size比已接收数据的小,这时CanTp模块将丢弃接收的N-PDU,也将调用PduR_CanTpRxIndication,赋给结果NOT_OK信息。


在工程上,基于接收成功过程的理解,我们必须还要充分考虑会发生哪些使接收不成功的情况,以及如何去处理这些情况。

2.2 FF(首帧)接收处理

针对接收到一帧FF的情况,从CanIf模块到CanTp模块的大致过程为:


1.下层接收到一帧诊断服务的数据,经CanIf调用CanTp_RxIndication函数通知CanTp模块;


2.CanTp模块先根据N_PCItype识别出是FF,在考虑了寻址格式的基础上,确定数据长度和提取诊断服务数据的长度FF_DL;


3.CanTp模块由于自身没有缓冲能力,将调用PduR_CanTpStartOfReception函数向上层确认是否有足够的buffer大小来存储FF_DL长度的数据;


4.当上层分配和锁定所需的接收buffer。且返回BUFREQ_OK,CanTp模块将准备流控帧参数:流控状态、BS和STmin,再发送流控帧;


5.CanTp模块调用PduR_CanTpCopyRxData函数让上层把接收的数据复制到接收buffer;


6.当复制成功完成,CanTp不再调用PduR_CanTpRxIndication函数通知上层,FF接收完成。


这就是理想的FF接收成功的基本过程,如下图7所示。但对于上述过程其实有个疑问:是不是应该先存好了接收的数据,再去准备流控帧和发送流控帧更合理呢?

UDS协议详解系列:CanTp6-汽车开发者社区

图7 FF接收过程,引自[2]

2.3 CF(续帧)接收处理

当CanTp模块接收续帧,需考虑的3种情况,如下图8所示:

UDS协议详解系列:CanTp6-汽车开发者社区

图8 接收CF的情况分析


下面就针对接收到一帧CF的情况进行分析,与上述SF和FF的过程一样,CanIf调用CanTp_RxIndication函数通知CanTp模块,识别出是CF,确定数据长度,再根据顺序号Sn确定续帧的情况。若接收的续帧为情况1,即意味着连续接收中,CanTp模块调用PduR_CanTpCopyRxData函数让上层把接收的数据复制到接收buffer,接收完成。


若接收的续帧为情况2,则意味着需要发送流控帧,其大致过程为:


1.CanTp模块调用PduR_CanTpCopyRxData函数让上层把最后一帧数据复制到接收buffer;


2.CanTp模块将准备流控帧参数:流控状态、BS和STmin,再发送流控帧。


若接收的续帧为情况3,则意味着整条信息将接收完成,这时:


1.CanTp模块调用PduR_CanTpCopyRxData函数让上层把最后一帧数据复制到接收buffer;


2.当复制成功完成,CanTp调用PduR_CanTpRxIndication函数通知上层。


这就是理想的CF接收成功的基本过程,更具体内容可参考[2]。

2.4 FC(流控帧)接收处理

流控帧是被用来根据接收方的能力调整发送者的设置,所以CanTp模块接收FC时将对相关的发送参数BS和STmin进行更新,其大致过程是:


1.CanTp模块,识别出是FC,确定数据长度,提取流控状态;


2.针对流控状态进行处理:当流控状态为连续发送,则提取BS和STmin,更新STmin,设置CanTp模块状态为发送流控帧;当流控状态为溢出,则放弃发送。


以上就是CanTp模块接收的大致过程分析,为了便于理解,上述忽略了相关定时参数的处理。实际上定时参数的处理非常重要,监控传输是否在规定时间完成,保证通讯传输的时间要求。

UDS协议详解系列:CanTp6-汽车开发者社区

UDS协议详解系列:CanTp6-汽车开发者社区

图9 网络层传输的定时参数,引自[1]

3 接收实例

引用[2]的实例再回顾下多帧传输的接收过程,假设接收的诊断服务数据长度有49个字节,上层报告接收的buffer有25个字节可用,那么具体的接收过程将按如下进行:


UDS协议详解系列:CanTp6-汽车开发者社区

图10 接收实例,引自[2]


注意:接收的buffer只有25个字节空间可用,不足以一次性全部接收这49个字节的诊断服务数据,所以CanTp模块分几个块来接收,当接收完一个块后,buffer空间不够接收下一个块,那么,接收方将会发送一帧流控状态为等待的流控帧给发送方,当最后buffer大小够了的话,接收方将会发送一帧流控状态为继续发送的流控帧给发送方,让其继续发送。


对应图10所示的绿色序号描述如下:


1.CanIf调用CanTp_RxIndication函数通知CanTp新接收到了一帧数据(首帧),然后CanTp调用PduR_CanTpStartOfReception函数通知上层PduR(实际会到DCM的Dcm_StartOfReception函数);


2.PduR将返回可用的buffer大小由25个字节,然后CanTp发送一帧流控状态为继续发送的流控帧给发送方;


3.CanTp提供每帧接收帧的数据给PduR,并监控剩余的buffer大小。当接收了两帧续帧后,剩余buffer大小不够存下一个块的数据(接下来的两帧续帧);


4.CanTp请求PduR的剩余buffer大小,并发送一帧流控状态为等待的流控帧给发送方,直到有充足buffer大小来接收下一个块才停止;


5.当buffer大小够了后,CanTp发送一帧流控状态为继续发送的流控帧给发送方,继续接收下一个块;


6.在存好了一个块的最后一帧续帧后,又出现buffer大小不够时,重复4,5;


7.当buffer空间能接收最后一个块,CanTp继续接收;


8.当数据接收完,CanTp调用PduR_CanTpRxIndication函数通知PduR接收完毕。


ok!以上就CanTp接收的内容,写本文过程有很多实际应用的疑问,比如说什么情况下会出现什么样的网络层超时,又该如何处理?欢迎交流指导。

4 CanTp发送

开始介绍CanTp发送前,先回顾下之前文章:《​​UDS协议: 基于AUTOSAR架构的UDS服务软件实现​​》一文中的发送过程。CanTp发送数据时,通过调用CanIf_Transmit函数实现向下传输,最终将数据写入到对应的寄存器。CanTp发送被触发主要有2种情况,一种是CanTp接收时需要响应流控帧,即直接发送流控帧;另一种是上层DCM模块已处理好诊断服务请求,需要回复响应,即DCM模块通过调用CanTp_Transmit模块去触发CanTp发送响应。

UDS协议详解系列:CanTp6-汽车开发者社区

图11 注:CanTp接收时可直接进行第4步发送流控帧


下面就结合CanTp发送触发的情况来分别看下SF,FF, FC和CF的发送过程。

4.1 SF发送处理

假设CanTp接收到是SF,正常寻址格式,请求的服务为10 03,如下:

UDS协议详解系列:CanTp6-汽车开发者社区

这里假设5个字节0x00为填充数据,对请求处理无作用,只将10 03存入上层接收的buffer,那么上层DCM模块将进行请求处理,得到了正响应 50 03 00 32 01 F4, 且将该数据存入发送的buffer,然后调用PduR_CanTpTransmit请求CanTp发送,如下图12所示。

UDS协议详解系列:CanTp6-汽车开发者社区

图12 CanTp发送SF的过程


上图CanTp发送SF的过程描述如下:


1.PduR调用CanTp_Transmit函数传输发送的SduId和数据给CanTp,同时在该函数中将执行一些操作:验证输入数据的有效性,确定与发送相关配置参数,处理发送请求,发起内部的发送任务;


2.当CanTp_Transmit函数返回值OK时,CanTp通知上层发送请求已接收,上层将锁住发送的buffer;


3.CanTp调用PduR_CanTpCopyTxData函数请求上层复制分割的数据;


4.当上层分配和锁定发送的buffer返回BUFREQ_E_OK后,CanTp调用CanIf_Transmit发送;


5.当成功写入响应的寄存器后,CanIf调用CanTp_TxConfirmation向CanTp确认发送成功,然后CanTp调用PduR_CanTpTxConfirmation向上层确认。


以上就是CanTp发送SF的大致过程。

1.2 FF发送处理

假设DCM模块进行请求处理后正响应有50个字节数据,显然这时需多帧传输才能把响应数据发送给接收方,发送方先会发送FF给接收方,告诉接收方整个信息的数据长度。发送FF的大致过程与基本SF一样,只是第1步中,会根据整个信息的数据长度大于单帧的数据长度来确定与FF发送相关配置参数,处理FF发送请求。

1.3 CF发送处理

当CanTp接收到FC时,将会更新STmin,然后发送CF,注意已通过首帧发送几个字节的数据,这时CanTp会按照续帧的顺序号逐帧地发送剩余的数据,上层每次将复制6或7个字节数据给每帧续帧,数据发送成功,与SF,FF一样,向上确认发送成功,如下图13所示。

UDS协议详解系列:CanTp6-汽车开发者社区

图13 CanTp发送FF, CF过程

1.4 FC发送处理

当CanTp接收到FF时,接收方将发送FC,以表明可继续发送续帧;当接收方出现buffer溢出或者需要等待的情况时,也需要通过设置对应的流控状态来通知发送方。与SF,FF的发送一样,FC的基本步骤一致,这里不再展开。


ok!以上就CanTp发送的内容,后续再进一步补充。


文章转载自公众号:汽车电子与软件

分类
收藏 1
回复
举报
回复
相关推荐