初始版本
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
#include "protocol.h"
|
||||
#include "string.h"
|
||||
#include "utils.h"
|
||||
|
||||
int protocol_pack_frame(
|
||||
uint16_t slave_addr,
|
||||
uint8_t command,const
|
||||
uint8_t *payload,
|
||||
uint16_t payload_len,
|
||||
uint8_t *buffer,uint16_t buffer_size,
|
||||
uint16_t *packed_len)
|
||||
{
|
||||
|
||||
// 构建基础帧头
|
||||
|
||||
buffer[0] = PROTOCOL_HEAD & 0xFF;
|
||||
buffer[1] = (PROTOCOL_HEAD >> 8) & 0xFF;
|
||||
buffer[2] = slave_addr & 0xFF;
|
||||
buffer[3] = (slave_addr >> 8) & 0xFF;
|
||||
|
||||
buffer[4] = command;
|
||||
|
||||
buffer[5] = payload_len & 0xFF;
|
||||
buffer[6] = (payload_len >> 8) & 0xFF;
|
||||
|
||||
// 复制有效载荷(保持小端格式)
|
||||
if (payload_len > 0 && payload != NULL) {
|
||||
memcpy(buffer + PROTOCOL_FRAME_HEAD_SIZE , payload, payload_len);
|
||||
}
|
||||
|
||||
// 设置实际长度
|
||||
int fram_len = PROTOCOL_FRAME_MIN_SIZE + payload_len;
|
||||
|
||||
|
||||
// 计算CRC(覆盖地址、命令、长度和有效载荷)
|
||||
uint16_t crc = 0xFFFF;
|
||||
|
||||
crc = modbus_crc16(buffer,fram_len -2);
|
||||
|
||||
// 写入CRC(保持小端格式)
|
||||
|
||||
buffer[fram_len-2] = (uint8_t)(crc & 0xFF);
|
||||
buffer[fram_len-1] = (uint8_t)(crc >> 8);
|
||||
|
||||
*packed_len =fram_len;
|
||||
|
||||
return PROTOCOL_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
int protocol_unpack_frame(
|
||||
const uint8_t *frame,
|
||||
uint16_t frame_len,
|
||||
uint16_t *slave_addr,
|
||||
uint8_t *command,
|
||||
uint8_t *payload,
|
||||
uint16_t *payload_len
|
||||
) {
|
||||
// 参数校验
|
||||
if (frame == NULL || slave_addr == NULL || command == NULL || payload_len == NULL) {
|
||||
return PROTOCOL_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (frame_len < PROTOCOL_FRAME_MIN_SIZE) {
|
||||
return PROTOCOL_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// 帧头校验
|
||||
uint16_t header = (frame[0] | frame[1] <<8);
|
||||
|
||||
if (header != PROTOCOL_HEAD) {
|
||||
|
||||
return PROTOCOL_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// 基础字段解析
|
||||
*slave_addr = (frame[2] | frame[3] << 8);
|
||||
|
||||
|
||||
*command = frame[4];
|
||||
|
||||
|
||||
*payload_len = (frame[5] | frame[6] << 8);
|
||||
|
||||
// 数据完整性校验
|
||||
if (*payload_len > (frame_len - PROTOCOL_FRAME_MIN_SIZE)) {
|
||||
|
||||
return PROTOCOL_ERR_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
int frame_size = *payload_len + 9;
|
||||
|
||||
uint16_t calc_crc =0xffff;
|
||||
|
||||
calc_crc = modbus_crc16((uint8_t *)frame, frame_size -2 );
|
||||
|
||||
// 校验CRC(保持小端格式)
|
||||
union{
|
||||
|
||||
uint16_t value;
|
||||
struct{
|
||||
uint8_t crcl;
|
||||
uint8_t crch;
|
||||
}bytes;
|
||||
|
||||
}crc_data;
|
||||
|
||||
crc_data.bytes.crcl =(frame[frame_size - 2] ) ;
|
||||
crc_data.bytes.crch =(frame[frame_size - 1] ) ;
|
||||
|
||||
if (calc_crc != crc_data.value) {
|
||||
return PROTOCOL_ERR_CRC;
|
||||
}
|
||||
|
||||
// 复制有效载荷(保持小端格式)
|
||||
if (*payload_len > 0 && payload != NULL) {
|
||||
memcpy(payload, frame + PROTOCOL_FRAME_HEAD_SIZE, *payload_len);
|
||||
}
|
||||
|
||||
return PROTOCOL_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user