基于UDS的DoIp实现(一) -- UDS单帧、多帧数据结构
单帧(SF)是UDS协议中数据传输的一种方式,用于传输长度小于等于7个字节的数据块。下面是单帧的数据结构图:
BYTE 1 BYTE 2 BYTE 3 ... BYTE 8
+------+------+------+------+------+------+------+------+------+------+
| 0 0 0 0 0 0 0 0| SF| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 数据字节 1 | 数据字节 2 |... | 数据字节 7 |
+------+------+------+------+------+------+------+------+------+------+
| L3 | L2 | L1 |数据块 | 校验和 |
+------+------+------+------+------+------+------+------+------+------+
解释:
- BYTE1:表示单帧的控制信息,具体格式为“0000 0000”,其中SF表示单帧帧类型(Single Frame),即单帧的数据类型。
- BYTE2-BYTE8:表示单帧中的数据,每个BYTE可用于传输一个字节的数据。
- L1:表示数据块的长度,即数据字节的数量。对于单帧,此值应小于或等于7。
- L2:表示数据块的长度的高8位。对于单帧,此值为0。
- L3:表示数据块的长度的高16位。对于单帧,此值为0。
- 校验和:表示数据的校验和,用于验证数据的完整性。
举例:
0x00(单帧 第一个字节,可以传入00) 0x19(服务号) 0x01(sub-function) 0x00 0x00 0x00 0x00 0x00(数据)
首帧是分块传输数据的第一个控制信息。它包含了数据总长度和其他必要的信息。上位机发送首帧后,ECU可以根据首帧信息判断出一共需要分成多少个数据块进行传输,同时也可以提取出首块数据并进行处理。
下面是首帧的数据结构图:
BYTE 1 BYTE 2 BYTE 3 BYTE 4 BYTE 5 ... BYTE 8
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| 0 0 0 0 0 0 0 0| FF| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 数据总长度高位 | 数据总长度低位 | 数据字节 1 | 数据字节 2 | ... | 数据字节 7 |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| L3 | L2 | L1 | 数据块 | 校验和 |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
解释:
- BYTE1:表示首帧的控制信息,具体格式为“0000 0000”,其中FF表示首帧帧类型(First Frame),即首帧的数据类型。
- BYTE2-BYTE8:表示首帧中的数据,每个BYTE可用于传输一个字节的数据。
- 数据总长度高位和数据总长度低位:表示整个数据块的长度。
- L1:表示数据块的长度,即每个连续帧中的数据量。对于首帧,此值应大于7。
- L2:表示数据块的长度的高8位。对于首帧,此值为数据总长度的高8位。
- L3:表示数据块的长度的高16位。对于首帧,此值为数据总长度的高16位。
- 校验和:表示数据的校验和,用于验证数据的完整性。
举例:
0x11(首帧 第一个字节,必须&0xF0 == 0x10,这个是首帧的标志) 0x13(第二字节) 0x19(服务号) 0x01(sub-function) 00 00 00 00(数据)
数据长度 = (0x11 & 0xF0) | 0x13 表示后续会有多少字节的数据过来。
连续帧是用于传输数据的控制信息。ECU接收到首帧后,如果需要分块传输,则ECU向上位机发送流控制信息后,上位机可以继续发送数据。上位机发送的每个连续帧都包含了一个分块序号和部分数据,直到ECU接收到所有的数据块为止。
下面是连续帧的数据结构图:
BYTE 1 BYTE 2 BYTE 3 BYTE 4 ... BYTE 8
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| 0 0 0 0 0 0 0 0| CF| SEQNUM | 0 | 0 | 0 | 0 | 0 | 0 | 数据字节 1 | 数据字节 2 | ... | 数据字节 7 |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| L3 | L2 | L1 | 数据块 | 校验和 |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
解释:
- BYTE1:表示连续帧的控制信息,具体格式为“0000 0000”,其中CF表示连续帧帧类型(Consecutive Frame),即连续帧的数据类型。
- BYTE2:SEQNUM表示连续帧的序号。
- BYTE3-BYTE8:表示连续帧中的数据,每个BYTE可用于传输一个字节的数据。
- L1:表示数据块的长度,即每个连续帧中的数据量。对于连续帧,此值应小于等于7。
- L2:表示数据块的长度的高8位。对于连续帧,此值为0。
- L3:表示数据块的长度的高16位。对于连续帧,此值为0。
- 校验和:表示数据的校验和,用于验证数据的完整性。
举例(接上面的FF):
0x21(第一个字节,必须&0xF0 == 0x20,这是连续帧的标志) 0x01 0x02 0x03 0x04 0x05 0x06 0x07(数据)
0x22(第一个字节,必须&0xF0 == 0x20) 0x01 0x02 0x03 0x04 0x05 0x06 0x07(数据)
0x23(第一个字节,必须&0xF0 == 0x20) 0x01 0x02 0x03 0x04 0x05 0x06 0x07(数据)
......................
这个里面的字节数+FF后面的6个字节 == 首帧的数据长度
流控帧是ECU向上位机发送的控制帧。在ECU接收到上位机发送的连续帧或某个分块时,如果接收缓冲区已满,将会向上位机发送流控制信息,告知上位机可以继续发送数据的时间或条件。
下面是流控帧的数据结构图:
BYTE 1 BYTE 2 BYTE 3
+------+------+------+------+------+------+------+------+------+------+------+------+
| 0 0 0 0 0 0 0 0| FC| FS |下一个连续帧序号| 延迟时间 |
+------+------+------+------+------+------+------+------+------+------+------+------+
| L3 | L2 | L1 | 校验和 |
+------+------+------+------+------+------+------+------+------+------+------+------+
解释:
- BYTE1:表示流控帧的控制信息,具体格式为“0000 0000”,其中FC表示流控帧帧类型(Flow Control Frame),即流控帧的数据类型。
- BYTE2:FS表示流控帧的状态(如等待继续传输或停止传输)。
- BYTE3:下一个连续帧序号。
- BYTE4:延迟时间,用于控制连续帧的传输速率。
- L1:表示数据块的长度,即每个流控帧中的数据量。对于流控帧,此值为0。
- L2:表示数据块的长度的高8位。对于流控帧,此值为0。
- L3:表示数据块的长度的高16位。对于流控帧,此值为0。
- 校验和:表示数据的校验和,用于验证数据的完整性。
举例:
0x31(第一帧,必须&0xF0 == 0x30,这是流控帧的标志) 0x00 0x00 0x00(数据,按照需求进行设置)
其中,0x31中的低四位(可以是1、2、3.....),被用来标记当前的块数量,也就是CF中展示的0x21、0x22、0x23......
对于首帧、流控帧以及连续帧的关系:
首帧提供数据的总长度信息,流控帧用于控制分块传输的速度,连续帧用于传输分块数据的控制信息和数据。它们按照一定的规则组合使用,可以有效地进行大数据量的传输。