嵌入式Libmodbus源码分析-常用接口函数分析
Posted 沧海一笑-dj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了嵌入式Libmodbus源码分析-常用接口函数分析相关的知识,希望对你有一定的参考价值。
00. 目录
01. modbus常用接口函数概述
libmodbus开发库提供的所有接口API函数,其主要对象文件包括modbus.h和modbus.c,接口函数大致可以分为3类。
02. modbus辅助接口函数
modbus.c文件中辅助接口函数
//设置从站地址
MODBUS_API int modbus_set_slave(modbus_t* ctx, int slave);
//获取从站地址
MODBUS_API int modbus_get_slave(modbus_t* ctx);
//设置错误恢复模式
MODBUS_API int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mode error_recovery);
//设置当前socket或者串口句柄
MODBUS_API int modbus_set_socket(modbus_t *ctx, int s);
//获取当前socket或者窗口句柄
MODBUS_API int modbus_get_socket(modbus_t *ctx);
//获取响应超时
MODBUS_API int modbus_get_response_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec);
//设置响应超时
MODBUS_API int modbus_set_response_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec);
//获取连续字节之间的超时时间
MODBUS_API int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec);
//设置连续字节之间的超时时间
MODBUS_API int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec);
//获取服务端等待客户端请求超时时间
MODBUS_API int modbus_get_indication_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec);
//设置服务端等待客户端请求超时时间
MODBUS_API int modbus_set_indication_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec);
//获取报文头长度
MODBUS_API int modbus_get_header_length(modbus_t *ctx);
//用于主站设备与从站设备建立连接
MODBUS_API int modbus_connect(modbus_t *ctx);
//关闭连接
MODBUS_API void modbus_close(modbus_t *ctx);
//释放内存
MODBUS_API void modbus_free(modbus_t *ctx);
//刷新缓冲区
MODBUS_API int modbus_flush(modbus_t *ctx);
//是否设置为debug模式
MODBUS_API int modbus_set_debug(modbus_t *ctx, int flag);
//获取当前错误信息
MODBUS_API const char *modbus_strerror(int errnum);
03. modbus功能接口函数
modbus.c文件中功能接口函数
//读取线圈或者离散量输出状态(功能码 0x1)
MODBUS_API int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);
//读取离散量输入值(功能码 0x2)
MODBUS_API int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);
//读取保持寄存器(功能码 0x3)
MODBUS_API int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);
//读取输入寄存器(功能码 0x4)
MODBUS_API int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);
//写单个线圈或者单个离散量(功能码 0x5)
MODBUS_API int modbus_write_bit(modbus_t *ctx, int coil_addr, int status);
//写单个保持寄存器(功能码 0x6)
MODBUS_API int modbus_write_register(modbus_t *ctx, int reg_addr, const uint16_t value);
//写多个线圈(功能码 0xF)
MODBUS_API int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *data);
//写多个保持寄存器(功能码 0x10)
MODBUS_API int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *data);
MODBUS_API int modbus_mask_write_register(modbus_t *ctx, int addr, uint16_t and_mask, uint16_t or_mask);
MODBUS_API int modbus_write_and_read_registers(modbus_t *ctx, int write_addr, int write_nb,
const uint16_t *src, int read_addr, int read_nb,
uint16_t *dest);
//报告从站ID(功能码 0x11)
MODBUS_API int modbus_report_slave_id(modbus_t *ctx, int max_dest, uint8_t *dest);
04. modbus数据处理
在libmodbus开发库中,为了方便数据处理,在modbus.h文件中定义了一系列数据处理宏。
/**
* UTILS FUNCTIONS
**/
//获取高字节
#define MODBUS_GET_HIGH_BYTE(data) (((data) >> 8) & 0xFF)
//获取低字节
#define MODBUS_GET_LOW_BYTE(data) ((data) & 0xFF)
#define MODBUS_GET_INT64_FROM_INT16(tab_int16, index) \\
(((int64_t)tab_int16[(index) ] << 48) | \\
((int64_t)tab_int16[(index) + 1] << 32) | \\
((int64_t)tab_int16[(index) + 2] << 16) | \\
(int64_t)tab_int16[(index) + 3])
#define MODBUS_GET_INT32_FROM_INT16(tab_int16, index) \\
(((int32_t)tab_int16[(index) ] << 16) | \\
(int32_t)tab_int16[(index) + 1])
#define MODBUS_GET_INT16_FROM_INT8(tab_int8, index) \\
(((int16_t)tab_int8[(index) ] << 8) | \\
(int16_t)tab_int8[(index) + 1])
#define MODBUS_SET_INT16_TO_INT8(tab_int8, index, value) \\
do { \\
((int8_t*)(tab_int8))[(index) ] = (int8_t)((value) >> 8); \\
((int8_t*)(tab_int8))[(index) + 1] = (int8_t)(value); \\
} while (0)
#define MODBUS_SET_INT32_TO_INT16(tab_int16, index, value) \\
do { \\
((int16_t*)(tab_int16))[(index) ] = (int16_t)((value) >> 16); \\
((int16_t*)(tab_int16))[(index) + 1] = (int16_t)(value); \\
} while (0)
#define MODBUS_SET_INT64_TO_INT16(tab_int16, index, value) \\
do { \\
((int16_t*)(tab_int16))[(index) ] = (int16_t)((value) >> 48); \\
((int16_t*)(tab_int16))[(index) + 1] = (int16_t)((value) >> 32); \\
((int16_t*)(tab_int16))[(index) + 2] = (int16_t)((value) >> 16); \\
((int16_t*)(tab_int16))[(index) + 3] = (int16_t)(value); \\
} while (0)
对于浮点数等多字节数据而言,由于存在字节序和大小端处理等问题,所有辅助定义了一些特殊函数
MODBUS_API void modbus_set_bits_from_byte(uint8_t *dest, int idx, const uint8_t value);
MODBUS_API void modbus_set_bits_from_bytes(uint8_t *dest, int idx, unsigned int nb_bits,
const uint8_t *tab_byte);
MODBUS_API uint8_t modbus_get_byte_from_bits(const uint8_t *src, int idx, unsigned int nb_bits);
MODBUS_API float modbus_get_float(const uint16_t *src);
MODBUS_API float modbus_get_float_abcd(const uint16_t *src);
MODBUS_API float modbus_get_float_dcba(const uint16_t *src);
MODBUS_API float modbus_get_float_badc(const uint16_t *src);
MODBUS_API float modbus_get_float_cdab(const uint16_t *src);
MODBUS_API void modbus_set_float(float f, uint16_t *dest);
MODBUS_API void modbus_set_float_abcd(float f, uint16_t *dest);
MODBUS_API void modbus_set_float_dcba(float f, uint16_t *dest);
MODBUS_API void modbus_set_float_badc(float f, uint16_t *dest);
MODBUS_API void modbus_set_float_cdab(float f, uint16_t *dest);
05. 附录
libmodbus源码下载:https://github.com/stephane/libmodbus
以上是关于嵌入式Libmodbus源码分析-常用接口函数分析的主要内容,如果未能解决你的问题,请参考以下文章