CanTp功能详述(一)


CanTp模块提供了分段、流控传输和报文重组的服务。它的主要目的是发送和接收可能适合或不适合单个CAN帧的消息。不适合单个CAN帧的报文被分割成多个部分,这样每个部分都可以在单个CAN帧中传输。CanTp功能可分为四大类:1、提供给上层的服务 2、提供给下层的服务 3、内部行为 4、错误分类

提供给上层的服务

CanTp的上层为PduR层

CanTp模块的服务接口主要分为以下两大类:

  • 初始化和关闭
  • 通信服务
初始化与关闭

CanTp模块有两个内部状态,CANTP_OFF和CANTP_ON。
CanTp模块上电后处于CANTP_OFF状态。
在CANTP_OFF状态, CanTp应当允许postbuild配置的更新。
当CanTp被CanTp_Init()成功初始化后,CanTp模块将变为内部状态CANTP_ON。
只有当CanTp处于CANTP_ON状态时,CanTp模块才会执行分段和重组任务。
函数CanTp_Init初始化模块的所有全局变量,并将所有传输协议连接设置为CANTP_ON的子状态,在此状态下,既不进行分段发送,也不进行分段接收(Rx线程处于CANTP_RX_WAIT状态,Tx线程处于CANTP_TX_WAIT状态)。
如果CanTp模块启用开发错误检测,当PduR或CanIf试图在CanTp_Init函数被调用之前使用除CanTp_GetVersionInfo的任何函数,CanTp模块将引发一个错误(CanTp.CANTP_E_UNINIT)。
如果CanTp模块在处于全局状态CANTP_ON时调用CanTp_Init函数,则CanTp_Init函数将模块返回到Idle状态(state = CANTP_ON,但发送和接收均未进行)。
当CanTp模块处于全局状态CANTP_ON时,如果调用CanTp_Init, CanTp模块将丢失所有当前连接。
CanTp_Shutdown函数应该正确停止CanTp模块。
在这里插入图片描述

传输请求

传输操作CanTp_Transmit()将允许上层请求使用CAN传输协议(CanTp)特性(分段、扩展寻址格式等)进行数据传输。函数CanTp_Transmit()是异步函数。在传输请求被接受后,无论N-SDU传输是否成功被完全处理,CanTp模块都将通知其上层。

传输取消

传输取消特性允许上层取消正在进行的传输。
使用案例:由于接收到另一个具有更高优先级的诊断协议而取消诊断传输。
此功能应通过静态配置(参数CanTpTc)来激活或取消激活。
传输取消通过调用CanTp_CancelTransmit()来触发。
如果传输正在进行中,在调用CanTp_CancelTransmit()服务之后,该连接上的传输将被中止,将在接收端产生一个超时错误。
值得注意的是,在调用CanTp_CancelTransmit()进行传输取消后,并且返回值为E_NOT_OK,那么PduR_CanTpTxConfirmation()应该被调用。

提供给下层的服务

CanTp的下层为CanIf层

根据AUTOSAR通信栈规范,CanTp为CanIf提供了以下两个回调函数:CanTp_TxConfirmation()和CanTp_RxIndication()。

传输确认

对于传输确认,CanTp模块应该提供函数CanTp_TxConfirmation()。
CanTp请求的CAN帧传输是否成功,由CanIf模块调用传输确认函数来通知CanTp。L-PDU标识符与CanIf模块此次调用相关联,以便识别相应的传输。
当超过最大时间(等于N_As)仍未收到发送确认时,CanTp模块将终止相应的会话。N-PDU将对其他并发会话保持不可用状态,直到收到传输确认的结果.
当CanTp_TxConfirmation()被调用,结果为E_NOT_OK时,CanTp将中止相应的会话。

接收指示

对于接收指示,CanTp模块应该提供CanTp_RxIndication()。
CanIf模块调用接收指示函数通知CanTp模块一个新的CAN N-PDU帧(即传输协议帧)已经收到。
接收指示可以根据CanIf配置在中断服务程序ISR的上下文中执行。

内部行为

CanTp的内部操作提供了基本机制,以实现该模块的主要目的,即在单个CAN帧或多个CAN帧中传输报文。
CanTp的整个行为将由事件触发,因此CanTp可以直接处理来自PduR的N-SDU以及CanIf的L-SDU的传输。

N-SDU接收

当接收到SF或FF N-PDU时,CanTp模块将使用PduR_CanTpStartOfReception函数通知上层(PduR)。PduR将保留并锁定一个缓冲区用于接收N-SDU。
CanTp通过PduR_CanTpStartOfReception()的参数TpSduInfoPtr将FF/SF的内容提供给PduR。
接收到的数据链路层数据长度(RX_DL)由CAN帧/PDU的第一个接收到的有效载荷长度(CAN_DL)获得,如下所示:

  • 对于小于等于8字节的CAN_DL值,RX_DL值为8。
  • 对于大于8字节的CAN_DL值,RX_DL值等于CAN_DL值。
    各N_PDU对应的N_PCI字节信息如下:
    在这里插入图片描述
    当为带有MetaData(表示通用连接)的SF或FF N-PDU调用CanTp_RxIndication时,CanTp模块将存储PDU的MetaData中包含的寻址信息,并使用该信息发起与上层的连接、传输FC N-PDUs和识别CF N-PDUs。MetaData中的寻址信息取决于寻址格式:
  • 常规寻址、扩展寻址、混合寻址(11位):无
  • 常规固定寻址、混合寻址(29位): N_SA, N_TA
    当为通用连接(带MetaData的N-SDU)调用PduR_CanTpStartOfReception()时,CanTp模块将通过N-SDU的MetaData转发提取的地址信息。MetaData中的寻址信息取决于寻址格式:
  • 常规寻址: 无
  • 扩展寻址: N_TA
  • 混合寻址(11位): N_AE
  • 常规固定寻址: N_TA, N_SA
  • 混合寻址(29位): N_TA, N_SA, N_AE
    当在通用连接(带MetaData的N-SDU)上为FC调用CanIf_Transmit()时,CanTp模块应通过N-PDU的MetaData提供存储的寻址信息。MetaData中的寻址信息取决于寻址格式:
  • 常规寻址、扩展寻址、混合寻址(11位):无
  • 常规固定寻址、混合寻址(29位): N_SA(保存N_TA), N_TA(保存N_SA)

当在通用连接(带MetaData的N-PDU)上为CF调用CanTp_RxIndication时,CanTp模块将根据FF存储的值检查N-PDU的MetaData中包含的寻址信息。
在接收到FF或块的最后一个CF时,CanTp模块应该在调用PduR_CanTpStartOfReception或PduR_CanTpCopyRxData之前启动一个超时N_Br。
可用的Rx缓冲区大小在PduR_CanTpStartOfReception()服务的输出指针参数中报告给CanTp。可用的Rx缓冲区可以小于预期的N-SDU数据长度。
注:如果上层因为一个错误不能使缓冲区可用,(例如,在网关的情况下,它可能表明到目标网络的传输会话已经中断)或资源限制(例如N-SDU长度超过上层的最大缓冲区大小),PduR_CanTpStartOfReception()函数返回 BUFREQ_E_NOT_OK 或 BUFREQ_E_OVFL。
在接收到首帧或单帧后,如果函数PduR_CanTpStartOfReception()返回 BUFREQ_E_NOT_OK给CanTp模块,CanTp模块将终止接收该N-SDU。在这种情况下,不会发送任何流控帧,也不会调用PduR_CanTpRxIndication()。
在接收到首帧后,如果函数PduR_CanTpStartOfReception()返回BUFREQ_E_OVFL 给CanTp模块,CanTp模块将发送一个FC N-PDU,状态为溢出(FC(OVFLW)),并终止接收N-SDU。
在接收到单帧后,如果函数PduR_CanTpStartOfReception()返回BUFREQ_E_OVFL给CanTp模块,则CanTp模块将中止接收N-SDU。
在接收到首帧或单帧后,如果函数PduR_CanTpStartOfReception()返回BUFREQ_OK,可用缓冲区大小小于已经接收到的数据,CanTp模块将中止接收N-SDU,并调用PduR_CanTpRxIndication(),结果为E_NOT_OK。
在接收到首帧后,如果函数PduR_CanTpStartOfReception()返回BUFREQ_OK,可用缓冲区大小小于下一个块所需的缓冲区大小,CanTp模块将启动定时器N_Br。
如果在接收到一个块的最后一个连续帧后,函数PduR_CanTpCopyRxData()返回BUFREQ_OK,但是剩余的缓冲区不足以接收下一个块,CanTp模块将启动定时器N_Br。
当定时器N_Br处于活动状态时,CanTp模块将在每次处理MainFunction期间调用数据长度为0(零)的PduR_CanTpCopyRxData()服务,并将NULL_PTR作为数据缓冲区。
注:ISO 15765-2规范定义了以下性能要求:(N_Br + N_Ar) < 0.9 * N_Bs。
如果N_Br定时器过期,而可用缓冲区的大小仍然不够大,CanTp模块将发送一个新的FC(WAIT)来暂停N_SDU的接收并重新加载N_Br定时器。
CanTp模块发送的连续FC(WAIT) N-PDU的个数不超过WFTmax。如果达到这个数字,CanTp模块将中止接收该N-SDU(接收方没有发送任何FC N-PDU,因此发送方的N_Bs定时器到期,然后终止传输),并出现E_NOT_OK的接收指示。
如果发生N_Ar超时(CAN driver没有对发送的任何FC帧进行确认),CanTp模块应中止接收,并通过调用指示函数PduR_CanTpRxIndication()通知上层此失败,结果为E_NOT_OK。
当Rx缓冲区足够大,可以容纳下一个块(直接在一个块的第一帧或最后一个连续帧之后,或者根据[SWS_CanTp_00222]重复调用PduR_CanTpCopyRxData()之后),CanTp模块将发送一个具有ClearToSend状态(FC(CTS))的Flow Control N-PDU,然后期望接收连续帧N-PDU。
当Rx缓冲区足够大,可以容纳下一个块(直接在一个块的首帧或最后一个连续帧之后,或者重复调用PduR_CanTpCopyRxData()之后),CanTp模块将发送一个具有ClearToSend状态(FC(CTS))的FC N-PDU,然后期望接收连续帧N-PDUs。
在接收到每个连续帧后,CanTp模块调用PduR_CanTpCopyRxData()函数,其带着一个PduInfo指针,包含数据缓冲区和数据长度:

  • 在CAN 2.0帧的最后CF的情况下,有6或7字节或更少
  • DLC-1或DLC-2字节用于CAN FD帧

输出指针参数在复制数据后为CanTp提供可用的Rx缓冲区大小。
CanTp模块应在每次CF接收指示(块中的最后一个除外)和每次CF传输确认(由发送端发起的FC传输)时启动N_Cr定时器。
在发生N_Cr超时的情况下,CanTp模块将中止接收,并通过调用指示函数PduR_CanTpRxIndication()将此失败通知上层,结果为E_NOT_OK。
如果PduR_CanTpCopyRxData()在接收到块中的连续帧后返回BUFREQ_E_NOT_OK,则CanTp应中止接收N-SDU,并通过调用PduR_CanTpRxIndication()通知PduR模块,结果为E_NOT_OK。
CanTp应检查在分段接收期间收到的每个SN的正确性。如果接收到错误的SN, CanTp模块将中止接收,并通过调用指示函数PduR_CanTpRxIndication()将失败通知上层,结果为E_NOT_OK。
当传输接收会话完成时((无论成功与否)),CanTp模块将调用上层通知服务PduR_CanTpRxIndication()。
对于FF N-PDU接收,FC N-PDU的内容取决于PduR_CanTpStartOfReception()服务的结果。
当接收到FF NPDU时,FC N-PDU必须在获得PduR_CanTpStartOfReception()服务的结果后才会发送。
FC N-PDU只会在每个连续帧的块(由一个BS组成)之后发送。
在分段接收期间发送的每个FC上,CanTp应该使用相同的BS和STmin参数值。这些参数的不同值可以用于不同的N-SDUs接收。
当CanIf_Transmit()在发送FC后返回E_NOT_OK,CanTp将终止当前的接收连接。

N-SDU传输

上层(PduR)通过调用CanTp_Transmit()请求传输N-SDU。CanTp_Transmit()的参数描述了CAN NSduId和要发送的完整Tx N-SDU长度。
对于不使用MetaData的特定连接,CanTp_Transmit函数只使用完整的SduLength信息,而不使用可用的N-SDU数据缓冲区来准备单帧或首帧的PCI。
当对带有MetaData的N-SDU调用CanTp_Transmit时,CanTp模块将存储N-SDU中MetaData包含的寻址信息,并使用该信息进行SF、FF和CF N-PDUs的传输和FC N-PDUs的识别。MetaData中的寻址信息取决于寻址格式:

  • 常规寻址: 无
  • 扩展寻址: N_TA
  • 混合寻址(11位): N_AE
  • 常规固定寻址: N_SA, N_TA
  • 混合寻址(29位): N_SA, N_TA, N_AE

当对通用连接(带MetaData的N-PDU)的SF、FF或CF调用CanIf_Transmit()时,CanTp模块通过N-PDU的MetaData提供存储的寻址信息。MetaData中的寻址信息取决于寻址格式:

  • 常规寻址,扩展寻址, 混合寻址(11位): none
  • 常规固定寻址,混合寻址(29位): N_SA, N_TA

当在通用连接(带MetaData的N-PDU)上对FC调用CanTp_RxIndication()时,CanTp模块将根据存储的值检查MetaData中包含的寻址信息。
在收到上层的传输请求后,CanTp模块将在调用PduR_CanTpCopyTxData之前启动N_Cs定时器。如果在定时器到期之前没有可用的数据,CanTp模块将终止通信。
CanTp模块应该为发送的每个SF, FF和CF调用PduR_CanTpCopyTxData服务。上层复制PduInfoType结构中的传输数据。
PduR_CanTpCopyTxData()包含一个用于恢复机制的参数- “ retry ”。因为ISO 15765-2不支持这种机制,CAN传输层不实现任何类型的恢复。因此,参数总是被设置为NULL指针。
如果上层由于错误(例如在网关的情况下,来自源网络的传输会话被终止)而不能使Tx数据可用,则PduR_CanTpCopyTxData()函数返回BUFREQ_E_NOT_OK。
如果PduR_CanTpCopyTxData()返回BUFREQ_E_NOT_OK, CanTp模块应中止传输请求,并通过调用回调函数PduR_CanTpTxConfirmation()将失败通知上层,结果为E_NOT_OK。
注意:如果上层暂时没有可用的Tx缓冲区,PduR_CanTpCopyTxData()函数返回BUFREQ_E_BUSY。
如果PduR_CanTpCopyTxData()函数返回BUFREQ_E_BUSY,则CanTp模块稍后将重试复制数据。
注意:如果在N_Cs定时器到期之前没有数据可用(ISO 15765-2规范定义了以下性能要求:(N_Cs + N_As) < 0.9* N_Cr), CanTp模块将中止此传输会话。
如果在N_Cs超时时间内数据不可用,CanTp模块将通过调用回调函数PduR_CanTpTxConfirmation通知上层失败,结果为E_NOT_OK。
当有Tx数据可用时,CanTp模块将恢复N-SDU的传输。
如果发生N_As超时(没有CAN driver的确认),CanTp模块将通过调用回调函数PduR_CanTpTxConfirmation()通知上层,结果为E_NOT_OK。
如果接收到FS设置为OVFLW的FC帧,CanTp模块将中止发送请求,并通过调用回调函数PduR_CanTpTxConfirmation()通知上层,结果为E_NOT_OK。
如果接收到带有无效FS的FC帧,CanTp模块将中止该消息的传输,并通过调用回调函数PduR_CanTpTxConfirmation()通知上层,结果为E_NOT_OK。
CanTp模块将在FF传输确认、块传输的最后一个CF以及每次FS=WT的FC指示(即直到接收到下一个FC的时间)时开始N_Bs时间的超时观察。
如果发生N_Bs超时,CanTp模块将中止该消息的传输,并通过调用回调函数PduR_CanTpTxConfirmation()通知上层,结果为E_NOT_OK。
当传输会话成功完成后,CanTp模块将调用上层的通知服务PduR_CanTpTxConfirmation(),结果为E_OK。
当CanIf_Transmit()在传输CF的SF、FF时返回E_NOT_OK,CanTp将终止当前的传输连接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值