串口通信工程笔记之协议设计
下面设计的串口通信协议用于完成双机互联程序的文件传输功能,简称SPCP。设计思想基于枕帧传输方式,即在向串口发送数据时是一帧一帧地发送。为了保证可靠传输,通过握手建立连接,在每一帧的传输中,采用发送/应答/重连/失败方式。
一、帧格式
双机互联采用3种帧:控制帧、数据帧与短语帧。控制帧与数据帧用于文件传输,短语帧用于短消息发送。
1. 数据帧
包括帧头、负载数据和校验和。帧头6个字节,如下图所示,其中count表示负载数据的字节数,Check1表示第2与第3字节校验和。
0 |
1 |
2 |
3 |
4 |
5 |
0x00 |
0x00 |
count |
Check1 |
图1 数据帧头
负载数据长count字节,最多不超过0x1000字节。校验和占2个字节,是对负载数据计算校验和的结构。
2. 控制帧
控制帧和控制信号合作完成通信同步与控制任务,它只有帧头,长为6字节。
0 |
1 |
2 |
3 |
4 |
5 |
0x00 |
0x01 |
nPack |
Check2 |
图2 传输起始控制帧
nPack表示本次传输共发送帧数,便于让接收方控制进度,Check2为第2,3字节的校验和。当nPack=Check2=0时,表示本次传输结束,当接收方收到该帧时,不管是否已收到应收的帧数,都将结束此次传输。在没有发生传输错误的情况下,一次传输只会出现两次控制帧,第一次在传输开始时,第二次在传输结束时。
3. 短语帧
短语帧中负载均为文本数据。发送与接收该帧不需要建立连接也没有错误控制,只是在帧头和帧尾插入了同步信号。
0x03 |
文本数据 |
0x03 |
图3 短语帧结构
二、控制信号
为提高通信效率,SPCP使用控制信号进行通信同步、纠错灯各种控制人物。SPCP定义了6中控制信号:
const BYTE SYN[1] = {0x1}; //请求
const BYTE ACK[1] = {0x2}; //响应
const BYTE RESEND[1] = {0x4}; //重发
const BYTE BUSY[1] = {0x7}; //忙
const BYTE BYE[3] = {6, 0, 6}; //断开连接
const BYTE STR[1] = {0x3}; //短信息同步信号
三、数据分帧及数据重组
应用程序发送过来的数据作为一个流按SPCP进行分帧,切割后为每帧加上帧头和校验和,放入SPCP内部缓冲区内准备发送;在接收端,分帧的数据去掉帧头重新归到接收缓冲区流,由应用程序接收。
图4 数据分帧过程
图5 数据重组过程
四、传输流程
在发送数据前,SPCP发送方将应用程序希望发送的数据进行分帧,然后按照下面的步骤通信。
1. 握手
- 由发送端发送SYN信号,等待反馈;
- 接收端收到SYN后返回ACK信号;
- 发送端接收到ACK信号后,由发送端发送控制首帧;
- 接收到收到控制首帧后,CheckSum错误则发送RESEND信号,然后重复步骤c~d;如果正确,发ACK信号;
- 发送端收到ACK信号后,转到2数据传输的步骤a。
2. 数据传输
- 由发送端发送第i帧帧头,等待反馈;若发送方发现该帧是控制结束帧,则转到3断开连接的步骤a;
- 接收端收到帧头后,帧长度校验和错误则发RESEND信号,然后重复步骤a~b。如果正确,发ACK信号;
- 若发送端收到ACK信号,则发送帧中数据和校验和;
- 接收端收到数据后,数据校验和错误则发RESEND信号,然后重复步骤c~d。如果正确,发ACK信号;
- 若发送端收到ACK信号,则该帧数据发送成功。发送端发送SYN信号,开始下一帧的握手过程;
- 若接收端收到SYN信号,则发送ACK信号进行确认;
- 若发送端接收到ACK信号,则重复a~e步骤进行下一帧的传输。
3. 断开连接
- 发送方发送控制结束帧,准备结束此次通信;
- 若接收端接收控制结束帧,则发送ACK信号,准备结束此次通信;
- 若发送端收到ACK信号,则发送BYE控制信号;
- 若接收方收到BYE信号,则拆除此次连接,同时发送ACK信号;
- 发送方收到ACK信号后,拆除连接。
注意:上述3个阶段的所有步骤中都存在超时处理,即若通信的某一方在限定时间内没有收到答复,则将断开连接,结束此次通信。此外,如果因为某错误而引起的重发次数超过3次,也就中断此次通信。