小猫爪:嵌入式小知识14 - ISO15765(UDS on CAN)简介
1 前言
ISO15765,相信很多人都听说过这个协议,它还有另外一个小名叫做CAN诊断协议规范,还有个ISO14229(UDS协议规范),这两者又是什么关系呢,其实可以简单粗暴的理解成ISO15765它规定了基于CAN的UDS协议,而ISO14229则规定了UDS协议应用层以及UDS协议在不同的车载总线(CAN, Ethernet, LIN等)上的应用和限制。想搞清楚这两者的联系和区别可以参考这两篇文章:《聊聊诊断协议——UDS》,《汉子之解读ISO 14229(UDS)协议》。
接下来就来简单介绍一下ISO15765这个ISO协议里面主要规定了哪些东西。
2 ISO15765和OSI的联系
ISO15765共有四个部分,每个部分所规定的信息如下:
名称 | 规定内容 |
---|---|
ISO15765-1 | 基本信息,大致介绍了一下ISO15765的大致内容 |
ISO15765-2 | 网络层服务 |
ISO15765-3 | 统一诊断服务在CAN上的实现(UDS on CAN) |
ISO15765-4 | 相关排放系统要求 |
其中第一部分第四部分对我们理解UDS on CAN用处不到,这里就不多作介绍了,感兴趣的朋友可自行去查看,接下来着重对第二部分和第三部分进行简单介绍。简单的拉出OSI(Open System Interconnect),OSI参考模型是ISO组织在1985年研究的网络互联模型,该体系结构标准定义了网络互联的七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层和应用层),CAN诊断协议就是基于OSI模式建立的,两者的关系如下:
OSI | 汽厂增强诊断 |
---|---|
诊断应用 | 用户自定义 |
应用层 | ISO15765-3 |
表示层 | 无 |
会话层 | 无 |
传输层 | 无 |
网络层 | ISO15765-2 |
链路层 | ISO11898-1 |
物理层 | 用户自定义 |
从上表中可以看出其中ISO15765-3规定的是OSI模型中的应用层,而ISO15765-2规定了网络层,可以看到CAN的UDS协议还是比较简单的,这得益于CAN通讯比较简单。至于ISO11898-1不用想就知道它就是CAN协议标准。
注:其实对于上表中的各层对应关系,在不同的文档中存在着较大的差异,在部分文档的描述中,会话层并不是空白,而是由ISO15765-3定义,传输层也不是空白,而是由ISO15765-2定义。
3 ISO15765-2 网络层定义
在ISO15765-2中规定了网络层它需要定义什么呢?最主要的就是拆、组包以及超时控制。下面我们来针对这两个方面分别来介绍。
3.1 拆包和组包(SDU和PDU)
所谓拆包和组包其实就是SDU(服务数据单元)和PDU(协议数据单元)两者之间的转换。SDU和PDU是数据在网络模型中上下两层传输过程中格式变换的说法,这样说可能有点抽象,下面就以很通俗的说法来介绍一下。
都知道经典CAN有8个字节,每一帧最大只能传输8个字节的数据,上层网络要想通过CAN帧来传递信息就会出现两种情况,有些消息长度很短,只需要CAN的一帧就可以解决;而有些消息长度很大,无法通过CAN的一帧来完整传输,那么就需要将该消息按照一定规则进行分割成若干个CAN帧进行传输。以上其实就是ISO15765-2中定义的最关键的部分,下面具体看一下这个ISO15765中制定的拆包和组包的规则。
3.1.1 帧的定义
ISO15765-2为实现上一目标将CAN帧分成了以下四种类型。
1. 单帧(SF)
一条消息仅用一帧即可完成传输,即为单帧(SingleFrame),单帧第一个字节byte0的高4位为0,第一个字节byte0的低四位(SF_DL)为接下来准备传输的数据长度,从第二个字节byte1至最后一个字节byte7为传输的数据,所以CAN诊断数据发送长度得小于等于7个字节。
单帧中SF_DL定义如下:
16进制值 | 描述 |
---|---|
0 | 保留 |
1 ~ 6 | 单帧数据长度值(SF_DL) |
7 | SF_DL = 7 时,只允许标准地址 |
8 ~ F | 无效 |
2. 首帧(FF)
当一条消息需要多帧才能完成传输,那么第一帧即被称为首帧,首帧第一个字节byte0的高四位为1,第一个字节byte0低四位与第二个字节byte1合起来(FF_DL)为接下来传输的数据长度,从第三个字节byte2至最后一个字节byte7为传输数据。
首帧中FF_DL定义如下:
16进制值 | 描述 |
---|---|
0 ~ 6 | 无效 |
7 | FF_DL = 7 只允许扩展地址及混合地址 |
8 ~ FFF | 数据总字节数,拆分信息最大数据长度支持 4095 个用户数据 |
3. 连续帧(CF)
当一条消息需要多帧才能完成传输时,除了首帧外,其他帧被称为连续帧,连续帧第一个字节byte0的高四位为2,第一个字节byte0的低四位为连续帧编号(SN),表示当前连续帧的顺序,第一条连续帧的SN=1,后面每发出一帧连续帧SN加1,范围0~15,当SN=15时,下一条连续帧重新变成0。第二个字节byte1至最后一个字节byte7为剩余的数据。首帧已经传输了6个字节,则接下来就是通过连续帧继续传输剩下的字节。
4. 流控帧(FC)
流控帧的作用在于接收端告知发送端接收能力,包含FlowSttatus(FS),BlockSize(BS)和SeparationTimeMin(STmin)三个参数,FS用来通知发送端当前流状态;BS表示接收端在发送下一帧流控帧之前允许发送端连续发送的最大连续帧个数,STmin表示发送端发送连续帧的最小间隔时间。发送端收到接收端反馈的流控帧后,发送端会按照流控帧给出的接收能力进行发送连续帧,即连续传输的连续帧不超过BS,连续帧的发送间隔时间大于等于STmin。若接收端已经收满BS数量的数据,且与首帧中包含的数据长度对比发现数据还没接收满,则会继续发送流控帧,发送端会接着发送连续帧,以此类推,直至所有数据发送完成。
FS定义:
16进制值 | 描述 |
---|---|
0 | 继续发送(CTS),通知发送方重新发送连续帧,该值意味着接收者准备好接收最大 BS 个连续帧。 |
1 | 等待(WT),通知发送方继续等待新的流控帧(N_PDU)的到来,并重新设置 N_BS 定时器 |
2 | 溢出(OverFlow),通知发送方无法接收该多帧,该流控参数值仅能在跟在回应首帧的流控帧中使用, 并且仅能在首帧中 FF_DL 信息的长度超过了接收实体缓冲区大小时使用 |
3 ~ F | 保留 |
BS定义:
16进制值 | 描述 |
---|---|
00 | 用于指示发送端在拆分数据的发送期间流控制帧不再发送流控制帧了。发送端应当不停的发送剩下的连续帧以便接收接收端另外的流控帧。 |
01 - FF | 该范围的 BS 参数值用于指示发送方在没有接收到下一帧流控帧期间能发送的最大数目的连续帧。 |
STmin定义:
16进制值 | 描述 |
---|---|
00 - 7F | 间隔时间(STmin)范围:0ms - 127ms 该 STmin 单元的范围 00 - 7F 时,单位为毫秒(ms) |
80 - F0 | 保留 |
F1 - F9 | 间隔时间(STmin)范围 100us - 900us 该 STmin 单元的范围 F1 - F9 最小分编为 100 微秒(us),参数值 F1 代表 100us,参数值 F9 代表 900us |
FA - FF | 保留 |
3.1.2 帧的传输
ISO15765-2定义的四种帧类型是怎样组合来实现发送端和接收端数据传输的呢?
1. 单帧
单帧消息的传输比较简单,如下图:
示例:发送端需要给接收端发送三个字节,分别是0x22 0x10 0x20,所以需要使用单帧,帧中剩余未使用字节使用0xFF填充。如下所示:
Byte0 | Byte1 | Byte2 | Byte3 | Byte4 | Byte5 | Byte6 | Byte7 |
---|---|---|---|---|---|---|---|
0x03 | 0x22 | 0x10 | 0x20 | 0xFF | 0xFF | 0xFF | 0xFF |
2. 多帧
对于多帧的情况,传输就比较复杂了,如下图:
接收端接收到首帧后,发送流控帧给接收端,告知发送端自己在发送下一帧流控帧之前能够接收最大数量的连续帧,以及两个连续帧之间的间隔,发送端接收到流控帧的要求后,按照该要求继续发送连续帧。接收端不断接收连续帧,若接收端已经收满BS数量的连续帧,且与首帧中包含的数据长度对比发现数据还没接收满,则会继续发送流控帧,发送端会接着发送连续帧,以此类推,直至所有数据发送完成。
示例:发送端需要给接收端发送0x2E 0x10 0x20 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13共23个字节长度的数据,未使用字节用0xFF填充,这时就需要多帧的形式来进行发送。
- 发送端发出首帧:
Byte0 | Byte1 | Byte2 | Byte3 | Byte4 | Byte5 | Byte6 | Byte7 |
---|---|---|---|---|---|---|---|
0x10 | 0x17 | 0x2E | 0x10 | 0x20 | 0x00 | 0x01 | 0x02 |
- 接收端发出流控帧:
Byte0 | Byte1 | Byte2 | Byte3 | Byte4 | Byte5 | Byte6 | Byte7 |
---|---|---|---|---|---|---|---|
0x30 | 0x00 | 0x01 | 0xFF | 0xFF | 0xFF | 0xFF | 0xFF |
- 发送端发出连续帧1:
Byte0 | Byte1 | Byte2 | Byte3 | Byte4 | Byte5 | Byte6 | Byte7 |
---|---|---|---|---|---|---|---|
0x21 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 | 0x08 | 0x09 |
- 发送端发出连续帧2:
Byte0 | Byte1 | Byte2 | Byte3 | Byte4 | Byte5 | Byte6 | Byte7 |
---|---|---|---|---|---|---|---|
0x22 | 0x0A | 0x0B | 0x0C | 0x0D | 0x0E | 0x0F | 0x10 |
- 发送端发出连续帧3:
Byte0 | Byte1 | Byte2 | Byte3 | Byte4 | Byte5 | Byte6 | Byte7 |
---|---|---|---|---|---|---|---|
0x23 | 0x11 | 0x12 | 0x13 | 0xFF | 0xFF | 0xFF | 0xFF |
3.2 地址定义
除了数据部分,为了将数据发送到对的地方,所以还需要对源地址以及目标地址进行定义,对于地址的定义,网络层定义了三种类型,分别是标准,扩展和混合,其实说白了就是按照一定要求把CAN ID进行定义。在介绍之前先列举以下下面出现的一些符号代表的意思,如下:
缩写符号 | 描述 |
---|---|
N_AI | network address information |
N_TA | network target address |
N_SA | network source address |
N_TAtype | network target address type,分为功能选址和物理选址 |
Mtype | message type |
N_PCI | network protocol control information,在帧的定义中已详细解释 |
标准地址是最通用的一种地址编码格式,这里就以标准地址编码展开,标准地址其又分为两种,分别是标准地址和标准固定地址,标准地址如下:
N_AI为N_SA, N_TA, N_TAtype, Mtype混合在一起形容的唯一CAN ID。
标准固定地址只能在29-bit扩展CAN ID中才能被应用,格式如下:
至于扩展地址和混合地址的编码格式感兴趣的朋友可以参考ISO15765原文。
3.3 超时控制
ISO15765-2中还针对时间制定了严格的超时机制,在网络层中主要有如下几个时间参数:
时间参数 | 描述 | 超时时间(ms) | 运行需求(ms) |
---|---|---|---|
N_As | 发送端发送一条CAN消息的时间 | 1000 | N/A |
N_Ar | 接收端发送一条CAN消息的时间 | 1000 | N/A |
N_Bs | 发送端发送首帧后到接受到流控帧的时间 | 1000 | N/A |
N_Br | 接收端收到首帧后到发送流控帧的时间 | N/A | (N_Br+N_Ar)<(0.9*N_Bs) |
N_Cs | 发送端收到流控帧后到发送连续帧的时间 | N/A | N_Cs+N_As)<(0.9*N_Cr) |
N_Cr | 接收端收下一个连续帧的时间 | 1000 | -------- |
再结合多帧的流程图就可以更清晰的了解到每个时间参数具体限制的地方:
这些事件参数的使用以及触发超时事件后的动作如下:
超时参数 | 触发 | 动作 |
---|---|---|
N_As | 发送方没有及时发送 N_PDU | 放 弃 信 息 的 接 收 并 传 递 <N_Result>=N_TIMEOUT_A 的 N_USData.confirm 指示 |
N_Ar | 接收方没有及时发送 N_PDU | 放 弃 信 息 的 接 收 并 传 递 <N_Result>=N_TIMEOUT_A 的 N_USData.confirm 指示 |
N_Bs | 发送方没有接收到流控帧(丢失,覆盖)或在首帧前收到,或连续帧没有被接收方接收到。 | 放 弃 信 息 的 发 送 并 传 递 <N_Result>=N_TIMEOUT_Bs 的 N_USData.confirm 指示 |
N_Cr | 接收方没有收到连续帧或之前流控帧未被发送方收到 | 放 弃 信 息 的 接 收 并 传 递 <N_Result>=N_TIMEOUT_Cr 的 N_USData.confirm 指示 |
4 ISO15765-3 应用层定义
首先要搞清楚UDS协议是一种服务器-客户端交互模式,发送端发送请求,接收端返回响应。为了来实现这种通话模式,网络层负责的是数据的传输,而应用层则考虑的是数据的定义,所以ISO15765-3主要规定数据的应用定义以及应用层层面的超时控制。
4.1 超时控制
对于应用层的超时控制,ISO15765-3定义的时间参数如下表所示:
不想翻译的朋友可以参考这篇文章来理解哦:https://blog.csdn.net/wjz110201/article/details/114837749[引用]。
上表中的参数
Δ
P
2
C
A
N
\Delta P2_{CAN}
ΔP2CAN分为两个时间,即:
Δ
P
2
C
A
N
=
Δ
P
2
C
A
N
−
R
e
q
+
Δ
P
2
C
A
N
−
R
s
p
\Delta P2_{CAN} = \Delta P2_{CAN-Req} + \Delta P2_{CAN-Rsp}
ΔP2CAN=ΔP2CAN−Req+ΔP2CAN−Rsp
其中
Δ
P
2
C
A
N
−
R
e
q
\Delta P2_{CAN-Req}
ΔP2CAN−Req为客户端发送请求至服务器的时间,
Δ
P
2
C
A
N
−
R
s
p
\Delta P2_{CAN-Rsp}
ΔP2CAN−Rsp为服务器发送响应至客户端的时间,如下图所示:
应用层定义了几种会话模式,在不同的会话模式下,客户端和服务端所被允许进行的访问内容是不同的,常规的有默认会话模式(defaultSession),拓展会话模式(extendedSession),编程会话模式(programmingSession)。在一个非默认会话模式启动后,则需要两个时间参数去约束,如下:
对于应用层的超时控制及其复杂,ISO15765中花了大把的篇幅来进行描述,感兴趣的朋友可以自行参考ISO15765-3原文。
4.2 数据定义
上面网络层定义章节中介绍了为了将数据完整发送出去,将一帧CAN报文的ID和数据分别进行定义,网络层的定义和应用层的定义的对应关系如下:
从上表中可以看到地址部分应用层和网络层都是一一对应的,所以应用层的地址层就不多介绍了,不同的地方在于数据部分,回顾一下ISO15765-2的内容,经典CAN的8个字节需要前几个字节作单帧,多帧等帧格式规范,剩下来的才是数据部分,而ISO15765则继续针对这部分数据再作定义,也就是说ISO15765-3是基于ISO15765-2的基础上再定义。那么应用层针对数据部分做了哪些定义呢?或者换种说话,应用层定义在哪些具体服务。
这里的数据定义其实就是我们常常所说的诊断服务,即真正意义上的UDS,前面所介绍的ISO15765-2网络层,其实都是为了在CAN总线上实现UDS所制定的一系列基础,而UDS在OSI分级中属于应用层。UDS其实是ISO14229-1定义的,ISO15765-3直接给它照搬过来了,所实现的具体服务类型如下:
补充:除以上部分,ISO15765-3还对地址的路由进行了相关规定,在这里就不作介绍了,感兴趣的朋友可以参考ISO16765-3原文。ISO15765-3说白了其实就是对ISO14229-1(UDS)的实现,后面将会另有一篇文章专门对UDS进行详细的介绍,以及对于每一项服务的应用和举例后面会专门有文章进行介绍。
5 AUTUSAR上的实现
下图是AUTOSAR的架构图,在AUTOSAR架构中实现CAN诊断,则依次要经过CAN硬件, CAN Driver,CAN_IF,CAN_TP,PDUR,DCM模块。
其中CAN硬件,CAN Driver实现了链路层(ISO11898-1)和物理层,CAN_IF层是链路层到网络层的接口,CAN_TP实现了网络层(ISO15765-2), PDUR为AUTOSAR中的总消息路由,它承载了CAN_TP模块与DCM模块的数据拷贝和交互,DCM则是实现了应用层(ISO15765-3, ISO14229-1)。