【嵌入式】Libmodbus源码分析(二)-常用接口函数分析

00. 目录

01. modbus常用接口函数概述

libmodbus开发库提供的所有接口API函数,其主要对象文件包括modbus.hmodbus.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

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值