说明
Agile Modbus 提供了 agile_modbus_slave_callback_t 的一种实现方式,使用户能够简单方便接入。
使用示例可查看 examples/slave。
使用方式:
#include "agile_modbus.h"
#include "agile_modbus_slave_util.h"
const agile_modbus_slave_util_t slave_util = {
/* User implementation */
};
agile_modbus_slave_handle(ctx, read_len, 0, agile_modbus_slave_util_callback, &slave_util, NULL);
agile_modbus_slave_util_callback 介绍
Agile Modbus 提供的一种 agile_modbus_slave_callback_t 实现方式,需要 agile_modbus_slave_util_t 类型变量指针作为私有数据。
私有数据为 NULL,所有功能码都能响应且为成功,但寄存器数据依然为 0。
agile_modbus_slave_util_t 介绍
typedef struct agile_modbus_slave_util {
const agile_modbus_slave_util_map_t *tab_bits;
int nb_bits;
const agile_modbus_slave_util_map_t *tab_input_bits;
int nb_input_bits;
const agile_modbus_slave_util_map_t *tab_registers;
int nb_registers;
const agile_modbus_slave_util_map_t *tab_input_registers;
int nb_input_registers;
int (*addr_check)(agile_modbus_t *ctx, struct agile_modbus_slave_info *slave_info);
int (*special_function)(agile_modbus_t *ctx, struct agile_modbus_slave_info *slave_info);
int (*done)(agile_modbus_t *ctx, struct agile_modbus_slave_info *slave_info, int ret);
} agile_modbus_slave_util_t;
寄存器相关
用户需要实现 bits、input_bits、registers、input_registers 定义。如果某个寄存器定义为 NULL,该寄存器对应的功能码能响应且为成功,但寄存器数据都为 0。
接口调用过程
agile_modbus_slave_util_map 介绍
typedef struct agile_modbus_slave_util_map {
int start_addr;
int end_addr;
int (*get)(void *buf, int bufsz);
int (*set)(int index, int len, void *buf, int bufsz);
} agile_modbus_slave_util_map_t;
注意事项:
起始地址和结束地址决定的寄存器个数有限制。更改函数内部 map_buf 数组大小可使其变大。
bit 寄存器 < 250
register 寄存器 < 125
接口函数为 NULL,寄存器对应的功能码能响应且为成功。
get 接口
将地址域内的数据全部拷贝到 buf 中。
set 接口
index: 地址域内的偏移
len: 长度
根据 index 和 len 修改数据。
示例
以 01 功能码为例:
#include <stdint.h>
#include <pthread.h>
#include "agile_modbus.h"
#include "agile_modbus_slave_util.h"
static uint8_t _tab_bits[10] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1};
static int get_map_buf(void *buf, int bufsz)
{
uint8_t *ptr = (uint8_t *)buf;
pthread_mutex_lock(&slave_mtx);
for (int i = 0; i < sizeof(_tab_bits); i++) {
ptr[i] = _tab_bits[i];
}
pthread_mutex_unlock(&slave_mtx);
return 0;
}
static int set_map_buf(int index, int len, void *buf, int bufsz)
{
uint8_t *ptr = (uint8_t *)buf;
pthread_mutex_lock(&slave_mtx);
for (int i = 0; i < len; i++) {
_tab_bits[index + i] = ptr[index + i];
}
pthread_mutex_unlock(&slave_mtx);
return 0;
}
const agile_modbus_slave_util_map_t bit_maps[1] = {
{0x041A, 0x0423, get_map_buf, set_map_buf}};
原作者:Cfly