Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 103 additions & 7 deletions plugins/modbus/modbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,22 @@

#include "modbus.h"

/**
* modbus.c
* 本文件实现了 Modbus 协议的基础功能,包括:
* - 数据包的打包和解包
* - CRC 校验计算
* - 字节序转换
* - 辅助功能
*/

/**
* 计算 Modbus RTU 的 CRC 校验值
*
* @param buf 数据缓冲区
* @param len 数据长度
* @return CRC 校验值
*/
static uint16_t calcrc(uint8_t *buf, int len)
{
uint16_t crc = 0xffff;
Expand All @@ -42,6 +58,12 @@ static uint16_t calcrc(uint8_t *buf, int len)
return crc;
}

/**
* 打包 Modbus 报文头部
*
* @param buf 打包缓冲区
* @param seq 序列号
*/
void modbus_header_wrap(neu_protocol_pack_buf_t *buf, uint16_t seq)
{
assert(neu_protocol_pack_buf_unused_size(buf) >=
Expand All @@ -53,11 +75,18 @@ void modbus_header_wrap(neu_protocol_pack_buf_t *buf, uint16_t seq)
header->seq = htons(seq);
header->protocol = 0x0;
header->len = htons(neu_protocol_pack_buf_used_size(buf) -
sizeof(struct modbus_header));
sizeof(struct modbus_header));
}

/**
* 解析 Modbus 报文头部
*
* @param buf 解包缓冲区
* @param out_header 输出头部结构
* @return 成功返回头部大小,失败返回负数
*/
int modbus_header_unwrap(neu_protocol_unpack_buf_t *buf,
struct modbus_header * out_header)
struct modbus_header *out_header)
{
struct modbus_header *header =
(struct modbus_header *) neu_protocol_unpack_buf(
Expand All @@ -79,6 +108,13 @@ int modbus_header_unwrap(neu_protocol_unpack_buf_t *buf,
return sizeof(struct modbus_header);
}

/**
* 打包 Modbus 功能码
*
* @param buf 打包缓冲区
* @param slave_id 从站 ID
* @param function 功能码
*/
void modbus_code_wrap(neu_protocol_pack_buf_t *buf, uint8_t slave_id,
uint8_t function)
{
Expand All @@ -91,8 +127,15 @@ void modbus_code_wrap(neu_protocol_pack_buf_t *buf, uint8_t slave_id,
code->function = function;
}

/**
* 解析 Modbus 功能码
*
* @param buf 解包缓冲区
* @param out_code 输出功能码结构
* @return 成功返回功能码大小,失败返回负数
*/
int modbus_code_unwrap(neu_protocol_unpack_buf_t *buf,
struct modbus_code * out_code)
struct modbus_code *out_code)
{
struct modbus_code *code = (struct modbus_code *) neu_protocol_unpack_buf(
buf, sizeof(struct modbus_code));
Expand All @@ -106,6 +149,14 @@ int modbus_code_unwrap(neu_protocol_unpack_buf_t *buf,
return sizeof(struct modbus_code);
}

/**
* 打包 Modbus 地址
*
* @param buf 打包缓冲区
* @param start 起始地址
* @param n_register 寄存器数量
* @param action Modbus 动作类型
*/
void modbus_address_wrap(neu_protocol_pack_buf_t *buf, uint16_t start,
uint16_t n_register, enum modbus_action action)
{
Expand All @@ -127,8 +178,15 @@ void modbus_address_wrap(neu_protocol_pack_buf_t *buf, uint16_t start,
}
}

/**
* 解析 Modbus 地址
*
* @param buf 解包缓冲区
* @param out_address 输出地址结构
* @return 成功返回地址大小,失败返回负数
*/
int modbus_address_unwrap(neu_protocol_unpack_buf_t *buf,
struct modbus_address * out_address)
struct modbus_address *out_address)
{
struct modbus_address *address =
(struct modbus_address *) neu_protocol_unpack_buf(
Expand All @@ -145,6 +203,14 @@ int modbus_address_unwrap(neu_protocol_unpack_buf_t *buf,
return sizeof(struct modbus_address);
}

/**
* 打包 Modbus 数据
*
* @param buf 打包缓冲区
* @param n_byte 数据字节数
* @param bytes 数据字节数组
* @param action Modbus 动作类型
*/
void modbus_data_wrap(neu_protocol_pack_buf_t *buf, uint8_t n_byte,
uint8_t *bytes, enum modbus_action action)
{
Expand All @@ -163,8 +229,15 @@ void modbus_data_wrap(neu_protocol_pack_buf_t *buf, uint8_t n_byte,
}
}

/**
* 解析 Modbus 数据
*
* @param buf 解包缓冲区
* @param out_data 输出数据结构
* @return 成功返回数据头大小,失败返回负数
*/
int modbus_data_unwrap(neu_protocol_unpack_buf_t *buf,
struct modbus_data * out_data)
struct modbus_data *out_data)
{
struct modbus_data *mdata = (struct modbus_data *) neu_protocol_unpack_buf(
buf, sizeof(struct modbus_data));
Expand All @@ -179,16 +252,26 @@ int modbus_data_unwrap(neu_protocol_unpack_buf_t *buf,
return sizeof(struct modbus_data);
}

/**
* 计算并设置 Modbus CRC 校验值
*
* @param buf 打包缓冲区
*/
void modbus_crc_set(neu_protocol_pack_buf_t *buf)
{
uint16_t crc = calcrc(neu_protocol_pack_buf_get(buf),
neu_protocol_pack_buf_used_size(buf) - 2);
neu_protocol_pack_buf_used_size(buf) - 2);
uint16_t *p_crc = (uint16_t *) neu_protocol_pack_buf_set(
buf, neu_protocol_pack_buf_used_size(buf) - 2, 2);

*p_crc = crc;
}

/**
* 在缓冲区中预留 CRC 校验的空间
*
* @param buf 打包缓冲区
*/
void modbus_crc_wrap(neu_protocol_pack_buf_t *buf)
{
assert(neu_protocol_pack_buf_unused_size(buf) >= sizeof(struct modbus_crc));
Expand All @@ -198,8 +281,15 @@ void modbus_crc_wrap(neu_protocol_pack_buf_t *buf)
crc->crc = 0;
}

/**
* 解析 Modbus CRC 校验
*
* @param buf 解包缓冲区
* @param out_crc 输出 CRC 结构
* @return 成功返回 CRC 大小,失败返回负数
*/
int modbus_crc_unwrap(neu_protocol_unpack_buf_t *buf,
struct modbus_crc * out_crc)
struct modbus_crc *out_crc)
{
struct modbus_crc *crc = (struct modbus_crc *) neu_protocol_unpack_buf(
buf, sizeof(struct modbus_crc));
Expand All @@ -213,6 +303,12 @@ int modbus_crc_unwrap(neu_protocol_unpack_buf_t *buf,
return sizeof(struct modbus_crc);
}

/**
* 将 Modbus 区域类型转换为字符串
*
* @param area 区域类型
* @return 区域类型的字符串表示
*/
const char *modbus_area_to_str(modbus_area_e area)
{
switch (area) {
Expand Down
Loading
Loading