当前位置:网站首页>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;
}
边栏推荐
- JS to convert array to tree data
- 爱可可AI前沿推介(7.7)
- Session
- NPM instal reports agent or network problems
- SQL lab 11~20 summary (subsequent continuous update) contains the solution that Firefox can't catch local packages after 18 levels
- 普乐蛙小型5d电影设备|5d电影动感电影体验馆|VR景区影院设备
- sql-lab (54-65)
- 图像像素读写操作
- How to apply @transactional transaction annotation to perfection?
- Day-20 file operation, recursive copy, serialization
猜你喜欢

Minimalist movie website

SQL lab 21~25 summary (subsequent continuous update) (including secondary injection explanation)

leetcode刷题:二叉树26(二叉搜索树中的插入操作)

(to be deleted later) yyds, paid academic resources, please keep a low profile!

浅谈估值模型 (二): PE指标II——PE Band

On valuation model (II): PE index II - PE band

Airserver automatically receives multi screen projection or cross device projection

【深度学习】图像多标签分类任务,百度PaddleClas

2022聚合工艺考试题模拟考试题库及在线模拟考试

SQL Lab (32~35) contains the principle understanding and precautions of wide byte injection (continuously updated later)
随机推荐
leetcode刷题:二叉树20(二叉搜索树中的搜索)
【从 0 开始学微服务】【01】什么是微服务
Learning and using vscode
ip2long与long2IP 分析
[疑难杂症]pip运行突然出现ModuleNotFoundError: No module named ‘pip‘
[learn wechat from 0] [00] Course Overview
What if does not match your user account appears when submitting the code?
The road to success in R & D efficiency of 1000 person Internet companies
基于NeRF的三维内容生成
【统计学习方法】学习笔记——逻辑斯谛回归和最大熵模型
Routing strategy of multi-point republication [Huawei]
爱可可AI前沿推介(7.7)
利用栈来实现二进制转化为十进制
【统计学习方法】学习笔记——提升方法
opencv的四个函数
PHP调用纯真IP数据库返回具体地址
On valuation model (II): PE index II - PE band
Session
Day-14 common APIs
Experiment with a web server that configures its own content