当前位置:网站首页>Design and implementation of communication protocol
Design and implementation of communication protocol
2022-07-07 12:47:00 【Gudong Mengxi】
List of articles
Communication protocol classification
Hardware protocol
During data transmission at the physical layer , The corresponding hardware protocol should be followed between the sender and the receiver , For example, we passed IO Collect a voltage signal , When the input voltage is higher than 2V When , The hardware will think that a high level has been collected , lower than 2V It is considered as a low level . Common optical fibers , A serial port ,CAN Bus we divide it into hardware protocols , They are the carriers of data transmission .
Software protocol
According to the physical characteristics of the bus , On this basis, various software protocols can be designed , The explanation of the agreement involved here is the software agreement , Hereinafter referred to as the agreement . For example, through IO You can design SPI Communication protocol and IIC agreement , adopt CAN The bus can be designed CANOpen agreement , Through serial port, we can design Modbus agreement .
The frame format
When data transmission is based on hardware, a frame format needs to be designed , For example, the data transmitted by serial port is usually in bytes , Then the smallest unit of transmission in protocol design must also be bytes , Communication frames are usually divided into two categories , One is fixed length frame , One is the indefinite length frame .
Fixed length frame
All frames have the same length , The receiver receives the specified length characters first , Then do further processing according to the message type , This kind of agreement has low scalability , Suitable for simple data transmission .
Indefinite frame
The first one is : Communication parties are divided according to functions , It is divided into different message types , The length of each type is different , But the receiver and sender agree on the length of each type of data in advance , The transmission data does not contain length information .
The second kind : The frame length is not fixed , Each frame can be divided into three parts , Frame head , data , check , The length of frame header and check is fixed , The length of the data is variable , The frame header contains length information , Analyze after receiving a complete frame header , The length of the remaining data is obtained by reading the length information , Then continue to receive , Until the verification is received , One frame data reception is completed , Then check the data , Check successfully and proceed to the next step , In this case, the receiving end does not know the length of data to be received before sending , Compared with the first protocol, it is more scalable , It can be used to transfer super long information such as files .
Communication frame design
Starting mark | Frame head | data | check | End identification |
---|---|---|---|---|
1 byte | 16 bytes | n bytes | 1 byte | 1 byte |
The communication message is mainly divided into two parts :
- The user layer contains frame headers and data , This part defines the type of message and the content of transmission
- In order to ensure the accuracy and integrity of data , Add the starting mark , Checksum End ID
Start and end marks
In order to avoid the occurrence of start identification and end identification in the data , Therefore, when this character appears in the data, it needs to be escaped .
Starting mark | End identification | 0xdb |
---|---|---|
0x55 | 0x56 | 0xdb |
0xdb 0xdc | 0xdb 0xdd | 0xdb 0xde |
Frame head
type | Instructions | Frame number | Total length | Data length |
---|---|---|---|---|
2 byte | 2 byte | 2 bytes | 4 bytes | 4 bytes |
- Types and instructions are used to tell the receiver how to process data
- Frame number and total length are used to transmit big data , Such as files
- The data length represents the number of bytes in the data area
data
Data |
---|
n bytes |
Data length is not fixed , Is variable , The receiving end will receive data according to the length information contained in the frame header , If there is no data, the end of the frame is directly received
check
CRC |
---|
1 bytes |
The end of the frame contains 1 byte CRC, Used to verify the whole data , If the TCP This reliable communication , Can be removed CRC,CRC To prevent errors during transmission
Frame data structure
typedef struct
{
uint16_t type;
uint16_t cmd;
uint16_t index;
uint32_t total;
uint32_t len;
} msg_header_t;
typedef struct
{
msg_header_t header;
uint8_t payload[];
} msg_t;
- according to C The default boundary alignment of the language , Frame header size is 16 byte .
- The data length is not fixed, and a pointer is used here to represent .
- msg_t The size is 20 byte .
Communication frame transmission
Send message
uint32_t msg_data_convert(uint8_t *in, uint32_t in_len, uint8_t *out, uint32_t out_len)
{
int i = 0;
int j = 0;
uint8_t *p = in;
for (; (i < in_len) && (j < (out_len - 1)); i++, p++)
{
if (MSG_BEGIN_FLAG == *p)
{
out[j++] = 0xdb;
out[j++] = 0xdc;
}
else if (MSG_END_FLAG == *p)
{
out[j++] = 0xdb;
out[j++] = 0xdd;
}
else
{
out[j++] = *p;
if (0xdb == *p)
{
out[j++] = 0xde;
}
}
}
DEBUG_ASSERT(j < (out_len - 1));
return j;
}
bool msg_create(msg_parser_t *obj, msg_type_def type, msg_cmd_def cmd, uint32_t index, uint32_t total, uint8_t *payload, uint32_t len)
{
uint8_t crc = 0;
bool ret = false;
msg_t msg = {
0};
uint32_t offset = 0;
if ((payload && (len > 0)) || (!payload && (len == 0)))
{
ret = true;
}
msg.header.type = (uint16_t)type;
msg.header.cmd = (uint16_t)cmd;
msg.header.index = index;
msg.header.total = total;
msg.header.len = len;
msg.payload = payload;
crc = msg_parser_calculate_crc(0, (uint8_t *)&msg, sizeof(msg_header_t));
crc = msg_parser_calculate_crc(crc, msg.payload, msg.header.len);
obj->msg_send_buffer[offset++] = MSG_BEGIN_FLAG;
/* Escape the frame header and tail in the data */
offset += msg_data_convert((uint8_t *)&msg, sizeof(msg_header_t), &obj->msg_send_buffer[offset], sizeof(obj->msg_send_buffer) - offset);
offset += msg_data_convert(msg.payload, msg.header.len, &obj->msg_send_buffer[offset], sizeof(obj->msg_send_buffer) - offset);
offset += msg_data_convert(&crc, sizeof(crc), &obj->msg_send_buffer[offset], sizeof(obj->msg_send_buffer) - offset);
obj->msg_send_buffer[offset++] = MSG_END_FLAG;
/* Send message through serial port */
com_write(obj->com_drv, obj->msg_send_buffer, offset);
return ret;
}
Receive message
msg_t *msg_parser_recv(msg_parser_t *obj)
{
uint8_t temp = 0;
uint32_t crc = 0;
uint8_t recv_crc = 0;
uint32_t recv_cnt = 0;
msg_t *ret = &obj->recv_msg;
/* Receive frame header */
do
{
com_read_byte(obj->com_drv, &temp, osWaitForever);
} while (MSG_BEGIN_FLAG != temp);
/* Receive remaining data */
do
{
com_read_byte(obj->com_drv, &temp, osWaitForever);
if (temp == 0xdb)
{
com_read_byte(obj->com_drv, &temp, osWaitForever);
if (0xdc == temp)
obj->msg_recv_buffer[recv_cnt++] = MSG_BEGIN_FLAG;
else if (0xdd == temp)
obj->msg_recv_buffer[recv_cnt++] = MSG_END_FLAG;
else if (0xde == temp)
obj->msg_recv_buffer[recv_cnt++] = 0xdb;
}
else
{
obj->msg_recv_buffer[recv_cnt++] = temp;
}
} while ((MSG_END_FLAG != temp) && (recv_cnt < sizeof(obj->msg_recv_buffer)));
if (recv_cnt < sizeof(obj->msg_recv_buffer))
{
/* Get frame header */
memcpy(&ret->header, obj->msg_recv_buffer, sizeof(msg_header_t));
if (recv_cnt == (sizeof(msg_header_t) + 2 + ret->header.len))
{
/* get data */
ret->payload = obj->msg_recv_buffer + sizeof(msg_header_t);
/* Get verification */
recv_crc = obj->msg_recv_buffer[recv_cnt - 2];
/* Calculation check */
crc = msg_parser_calculate_crc(0, (uint8_t *)ret, sizeof(msg_header_t));
crc = msg_parser_calculate_crc(crc, ret->payload, ret->header.len);
if (recv_crc != crc)
{
ret = NULL;
}
}
else
{
ret = NULL;
}
}
else
{
ret = NULL;
}
return ret;
}
边栏推荐
- [statistical learning methods] learning notes - Chapter 4: naive Bayesian method
- 【统计学习方法】学习笔记——第四章:朴素贝叶斯法
- Learning and using vscode
- [pytorch practice] write poetry with RNN
- 如何将 @Transactional 事务注解运用到炉火纯青?
- Day-14 common APIs
- File upload vulnerability - upload labs (1~2)
- About sqli lab less-15 using or instead of and parsing
- idm服务器响应显示您没有权限下载解决教程
- SQL Lab (41~45) (continuous update later)
猜你喜欢
Customize the web service configuration file
3D content generation based on nerf
图形对象的创建与赋值
ACL 2022 | 序列标注的小样本NER:融合标签语义的双塔BERT模型
opencv的四个函数
[statistical learning method] learning notes - support vector machine (I)
leetcode刷题:二叉树21(验证二叉搜索树)
【统计学习方法】学习笔记——提升方法
Charles: four ways to modify the input parameters or return results of the interface
SQL lab 21~25 summary (subsequent continuous update) (including secondary injection explanation)
随机推荐
Ctfhub -web SSRF summary (excluding fastcgi and redI) super detailed
"Series after reading" my God! It's so simple to understand throttling and anti shake~
Routing strategy of multi-point republication [Huawei]
【从 0 开始学微服务】【01】什么是微服务
[pytorch practice] image description -- let neural network read pictures and tell stories
[Q&A]AttributeError: module ‘signal‘ has no attribute ‘SIGALRM‘
Solve server returns invalid timezone Go to ‘Advanced’ tab and set ‘serverTimezone’ property manually
Using stack to convert binary to decimal
Day-15 common APIs and exception mechanisms
【深度学习】图像多标签分类任务,百度PaddleClas
Sorting, dichotomy
Realize all, race, allsettled and any of the simple version of promise by yourself
layer弹出层的关闭问题
Preorder, inorder and postorder traversal of binary tree
Static comprehensive experiment
2022A特种设备相关管理(锅炉压力容器压力管道)模拟考试题库模拟考试平台操作
leetcode刷题:二叉树25(二叉搜索树的最近公共祖先)
(to be deleted later) yyds, paid academic resources, please keep a low profile!
对话PPIO联合创始人王闻宇:整合边缘算力资源,开拓更多音视频服务场景
静态Vxlan 配置