CAN网络通信采用分层设计架构(参考OSI基本模型),其分层如下:
编号 |
层架构 |
层架构 |
ISO |
1 |
Application Layer |
应用层 |
ISO-14229-3 |
2 |
Session Layer |
会话层 |
ISO-14229-2 |
3 |
Network layer |
网络层 |
ISO-15765-2 |
4 |
Data Link layer |
数据链路层 |
ISO-11898-1 |
5 |
Physical layer |
物理层 |
生产厂商定义 |
CAN软件架构(Vector协议栈)如下:
注:如上图,只有诊断报文才会通过CANTp模块处理。
15765-2网络层服务介绍CAN TP模块的理论基础,用于诊断报文在网络层的传输,当接受数据大于8个字节时,网络层会把接收到的多帧数据组包成单个数据传输给应用层;当发送数据大于8个字节时,网络层会把数据分割成多个报文传输到总线上。
一个CAN报文一次能传输8个字节的数据,而部分诊断服务响应报文的数据长度超过8个字节,标准CAN帧一次只能发送8个字节数据,这时候发送节点网络层会把数据分割成若干帧报文发送出去,接收节点接收到若干帧报文后,把数据重新组装在一起。
网络层服务协议指定不同ECU网络层之间的数据传输协议,网络层协议允许传输/接收数据长度最高达4095个字节的数据,并反馈传输/接收的结果给相对应的层。
报文数据长度不超过7个字节(正常寻址下)时,报文通过单帧发送/接收;当报文数据长度大于7个字节时,网络层会对数据进行组包(接收报文)及解包(发送报文),并通过首帧,流控帧,续帧配合完成数据的发送。
单帧用于传输数据长度低于7(正常寻址下)的数据传输。
如请求诊断会话服务的请求默认会话子服务:
注: ID为0x713的报文为请求服务报文,由Clent发出,Server接收;
ID为0x613的报文为响应服务报文,由Server发出,Clent接受;
如何看诊断报文内容(通过协议控制信息(N_PCI)来区分)?
下表给出了诊断报文单帧的结构,Byte1 的前四比特的值为0(代表单帧),后四个比特的值用于表明传输数据的字节数;
上面第一帧报文: 02 10 01
byte1中的0表明当前是单帧,2 代表当前帧数据长度为2;10 01 代表当前传输的数据(2个字节);
上面第二帧报文:06 50 10 00 32 01 F4
byte1中的0表明当前是单帧,6代表当前数据长度为6; 50 10 00 32 01 F4代表当前传输的数据(6个字节);
如传输一个数据长度为54个字节的数据,其发送流程如下:
其流程是:
注:首帧,续帧,流控帧结构见 2.2.1.2 N_PCI;
前面介绍了单帧与多帧传输(首帧,续帧,流控帧协同进行多帧传输);网络层服务定义好了数据在网络层里的数据结构,该机构称为N_PDU,网络层通过 N_PDU(网络层协议数据单元)用于实现不同节点间的网络层实体的通讯。
N_PDU有SF N_PDU, FF N_PDU, CF N_PDU, FC N_PDU四种类型。
网络协议数据单元由地址信息,协议控制信息,数据域构成。其格式如下:
Address Information |
Protocol Control Information |
Data Field |
N_AI |
N_PCI |
N_Data |
怎么理解N_PDU呢,你可以把他理解成如下的一个结构体;网络层与数据链路层之间的数据交换,通过传输这样的结构体变量来进行。
/*定义地址信息,依据来自2.2.1.1 N_AI*/
typedef struct
{
uint8 N_SA;
uint8 N_TA;
uint8 N_TA_Type;
}N_AI_type;
/*定义N_PDU结构*/
typedef struct
{
N_AI_type N_AI;
uint8* data;/*data是个8字节数组,由N_PCI跟N_data组成*/
}N_PDU_Typde
N_PDU_type N_PDU;/*N_PDU作为数据交换的参数,从而实现数据在网络层与数据链路层之间的交换*/
地址信息由源地址(N_SA),目标地址(N_TA),目标地址类型(N_TA Yype),地址扩展信息(N_AE)组成。
当Message Type为Diagnostic时,N_AI由N_SA, N_TA, N_TAtye组成。
当Message Type为Remote Diagnostic时,由N_SA,N_TA,N_TA type,N_AE四个组成。
注:
Message Type一般都为Diagnostic;
N_SA |
N_TA |
N_TA type |
N_AE |
1 byte |
1 byte |
Physical/functional |
1 byte |
N_TAtype参数是N_TA的扩展,用于选择通信模式
物理寻址 | 1对1通信,适用于所有格式N_PDU。 |
功能寻址 | 1对N通信,仅适用于单帧通信。 |
在车载CAN网络中,一个网络中存在若干个节点,当外围诊断设备需要读取目前车内所有节点(1对N)的故障状态时,通过发送功能寻址的请求诊断报文,该报文会被网络中所有节点接收;如我们只需要读取某个特定节点(1对1)的故障状态,通过发送物理寻址的请求诊断报文。
节点名称 | 物理寻址请求报文ID | 功能寻址请求报文ID | 响应报文ID |
空调AC | 0X763 | 0x7FF | 0x723 |
大屏 | 0x764 | 0x7FF | 0x724 |
仪表盘 | 0x765 | 0x7FF | 0x735 |
可以看出,不同节点的物理寻址ID是唯一且固定的,而不同节点的功能寻址ID是同一的;而所有的响应报文都是物理寻址。
注:本文中,请求报文为客户端(外温诊断设备)发出的报文,响应报文由服务器(车载ECU)发出的报文。
N_PCI规定FF,SF,CF,FS的结构,其定义见下图:
看下图中红色标记处:
如下的单帧报文解析,byte1 为0x03,0代表单帧,3代表数据长度为3;byte2~byte4 代表传输的数据,后4位为填充数据。
单帧错误处理:如果接收到的SF_DL为0或大于7,网络层要忽略本次接收;
注意:如果一帧报文的数据不足8字节,生于部分要用特定数据(自定义)进行填充。
看下图红色标记处:
如下的首帧报文中;byte1 数据为10;byte2 为2C; 1表示当前为首帧,0x02C表示数据长度;后面6字节为数据;
FF_DL占12个比特其范围为1~4095,表明网络层能处理最大的数据长度为4095各字节;
如上的首帧报文解析,1 代表首帧报文,02C代表数据总长度为44字节,62 F1 AE 05 88 91为首帧传输的数据,这里传输了6字节数据,剩下的38字节数据将通过续帧传输。
单帧错误处理:
如果FF_DL小于8(正常寻址)或小于7(扩展或混合寻址),网络层要忽略本次接收。
如果FF_DL大于目前数据缓存区的容量,认为当前出现错误,并反馈发送节点停止后续报文传输(设置流控帧的FS = OverFlow)。
如下图中红色标识处:
续帧的第一个字节为0x21;2代表续帧,1代表当前的帧序列号。
多帧传输时,服务器首帧发送完毕且接收到客户端反馈的流控帧后,服务器便会发出第一个续帧,然后按特定时间要求发送第2个,第3个续帧.....第BS个续帧,直到SN达到BS的数值或者数据发送完成。如果发送了BS个续帧数据仍未发送完,此时客户端会发送流控帧,服务器接收后组织下一快的续帧发送。
BS为一个数值,其范围为【1,15】,表示续帧连续发送的最大次数。
多帧传输的最后一帧时续帧,其的SN可能时0到BS中的任意整数值。
流控帧由FS,BS,Stmin三个参数组成。
FS |
流控制状态 |
ContiuneToSend(0x00):表明接收端做好接收BS个续帧的准备 Wait(0x01):让接收端等待接收新的流控帧 OverFlow(0x02):表明当前接收能力不足,让发送端停止后续发送 |
BS |
快大小 |
表明接收端要求一次接收续帧的能力大小 |
Stmin |
最小时间间隔 |
接收端同志发送端自己的接收能力,让发送端调整发送报文的时间。 范围(0~127)代表(0~127)ms 范围(0xF1~0xF9)代表(100~900)us |
byte1中:3代表当前为流控帧,0代表ContiuneToSend(0x00):表明接收端做好接收BS个续帧的准备;
byte2中:F代表当前要求续帧的快大小为15,即需连续发送15帧续帧。
byte3中:5代表续帧之间传输的时间间隔为5ms。
流控帧的作用:
因不同节点的传输及数据处理能力不一样,流控帧接受节点就是告诉发送节点自身的接受能力与状态,防止出现发送节点发送过快,接受节点处理不过来的情况。
最大等待流控帧等待传输(N_WFTmax)(需确认):
当FC 的 FS 为Wait时,表示接受节点希望发送节点暂停发送,等待FS 为CTS时,再继续发送。等待过程中,会定期发送流控帧,
如果后续流控帧的FD一直为Wait咋处理呢:
FC.WT报文发送的最大次数为N_WFTmax,当接受到N_WFTmax次等待流控帧后,忽略本次传输。
CAN总线软件框架基于分层设计,至下而上依次是:驱动层,数据链路层,网络层,会话层,应用层。
如Client请求10 01(默认会话请求),从底层驱动接受到数据到把数据传输到应用层处的过程中,涉及各层之间的数据传输与数据传输状态确认。
CAN网络层使用服务原语,实现数据在相邻层之间传输与传输状态确认(如对服务原语不甚了解,以下链接可供参考https://blog.csdn.net/ventry/article/details/5268539)。
CAN网络层提供了4种服务原语用于数据的传输与传输状态确认有,其分别是N_USData.request,N_USData.confirm,N_USData_FF.indication,N_USData.indication。
网络层在autosar里对应的软件模块为CAN_TP,服务原语就是网络层(can_tp)与数据链路层(can_if)的应用接口函数。其对应关系如下:
服务原语 | 函数接口 | 功能 |
N_USData.request | CanTp_Transmit | can_tp发送数据到can_if |
N_USData.confirm | CanTp_TxConfirmation | can_if通知can_tp数据是否成功发送到总线上 |
N_USData_FF.indication | - | |
N_USData.indication | CanTp_RxIndication | can_tp接受到can_if的数据 |
请求服务原语由在应用层发出,用于高层把请求的数据
注:
/该服务原语指出了函数名以及函数参数的类型*/
typedef uint8 Std_ReturnType;
typedef struct
{
uint8* Sdu_data_ptr;/*指向传输的数据*/
uint16 sdu_lentg;/*传输数据的字节数*/
}} PduInfoType;
Std_ReturnType CanTp_Transmit(PduInfoType* CanTpTxInfoPtr)
{
/*函数实体*/
}
确认服务原语由网络层发送,用以表明N_USData.request(以地址信息限定的请求服务原语)的完成状态。确认服务原语的格式如下:
请求服务原语与确认服务原语是相辅相成的,当高层通过请求服务原语把数据传输到网络层后,网络层会把数据传输到下层去。
当下层对数据发送处理后,会把相应的执行结果传输到网络层,网络层通过确认服务原语把执行结果发送给高层。
首帧指示服务原语:当网络层接收到首帧报文时,发送首帧服务原语给高层,告知高层报文首帧数据到来。
首帧指示服务原语格式如下:
当网络层完成单帧接收或者一次完整的多帧接收并对数据进行解包后,指示服务原语把接收到的数据及数据状态传输到高层。
其格式如下:
再看这幅图,多帧数据的一个发送流程,试想如果服务器发送一个单帧后,服务器没有接受到客户端的流控帧(假设此时是总线收到干扰导致流控帧接收失败),这时候客户端岂不是一直卡在等待流控帧的这个过程中,进入了等待的死循环?
对以上可能出现的请客,实际方案如下;我们定义首帧发送完成到接收到流控帧的一个时间要求BS,如50ms,首帧发送确认时开始计时,如果时间到了,还未收到流控帧,则会产生一个BS_timeout的错误,该错误表示规定时间内未接收到流控帧,该错误产生后会终止当前报文的发送,并把发送结果传输给应用层。
网络层定时参数有如下组成Ar,As,Br,Bs, Cr, Cs 6个,如下图定义了每个参数的计时的起点跟终点。
如:
As:网络层把数据传输到数据链路层为起点,数据传输到总线上为终点,As就是数据在数据链路层及物理层处理的最大时间;_超时报As_timeout的错误,
Bs: 等待流控帧的最大时间;
Cs:俩个连续流控帧的最大间隔时间;
Ar:
注:As,Ar, s代表send,r代表receive。
总结就是定义了传输中过程中的一些时间要求,如果要求时间内未完成期望的动作,则认为超时,终止当前报文后续传输。
网络定时参数由整车厂的网络开发人员定义。
网络层服务定义了如下6个网络层定义参数: As,Ar,Bs,Br,Cs,Cr (Note: s代表Sender发送节点;r代表Receiver接受节点)。
下图展示单帧报文在发送节点与接受节点的传输过程:同时理解下As参数的定义,时间范围,用法
1 发送节点:应用层传输数据到网络层(N_USData.req),于此同时,网络层传输数据到数据连路层(L_Data.req),并激活As计数器。
2 发送节点:当数据链路层检测到报文成功发送到总线上时(通过检测ACK位的变化),会激活发送确认(L_data.Con)并通过N_USData.con通知到网络层。此时清除As计数器,
接受节点:当数据链路层接受到报文,会激活接受指示(L_data.ind)并把数据传输到网络层(N_USData.ind);
据上可看出As参数的定义是,发送数据在数据链路层传输的时间(数据传输数据链路层到数据发送到总线上的时间差)。如果数据未在As时间内成功发送到总线,即是As定时器清零时仍未收到L_Data.con,则网络层会生成Timout_A 错误。
Note:数据在网络层与数据链路层的传输是同步的;
数据在发送节点确认传输与节点节点确认接受也是同步的;
接下来通过一个多帧数据传输来理解其他参数;
其流程是,应用层传输数据到网络层,网络层进行分段传输。
网络层定义参数,定义了报文发送具体的时间要求,具体如下:
网络层参数超时处理机制:
如:当应用层传输给网络层一个16个字节的数据,网络层会对数据进行解包进行发送(SF + CF +CF),如果发送SF时产生了Timeout-A错误,则会停止后续CF的发送,此时SF还是会正常发送到总线上的。
参考资源:
1 ISO 15765-2 网络层服务
2 服务原语, 服务原语和协议的区别!https://blog.csdn.net/ventry/article/details/5268539