关于rtthread中libmodbus多从机无法读取信息的解决方案
关于rtthread中libmodbus多从机无法读取信息的解决方案,本人测试了两台从机下的情况,发现单独的读取每个从机都没有问题,把两台从机并在一起就会出现问题,只能读取其中的一台,读取哪台是随机的。
问题解决
- 在modbus-rtu-private.h的modbus_rtu_t的结构体中加上int confirmation_to_ignore;
typedef struct _modbus_rtu {
/* Device: "/dev/ttyS0", "/dev/ttyUSB0" or "/dev/tty.USA19*" on Mac OS X. */
char *device;
/* Bauds: 9600, 19200, 57600, 115200, etc */
int baud;
/* Data bit */
uint8_t data_bit;
/* Stop bit */
uint8_t stop_bit;
/* Parity: 'N', 'O', 'E' */
char parity;
#if defined(_WIN32)
struct win32_ser w_ser;
DCB old_dcb;
#else
/* Save old termios settings */
struct termios old_tios;
#endif
#if HAVE_DECL_TIOCSRS485
int serial_mode;
#endif
#if HAVE_DECL_TIOCM_RTS
int rts;
int rts_delay;
int onebyte_time;
int rts_pin;
void (*set_rts) (modbus_t *ctx, int on);
#endif
/* To handle many slaves on the same link */
int confirmation_to_ignore; //这是新增的一条,其他不动
} modbus_rtu_t;
- 将modbus-rtu.c的 _modbus_rtu_receive(void) 函数修改为以下
static int _modbus_rtu_receive(modbus_t *ctx, uint8_t *req)
{
int rc;
modbus_rtu_t *ctx_rtu = ctx->backend_data;
if (ctx_rtu->confirmation_to_ignore) {
_modbus_receive_msg(ctx, req, MSG_CONFIRMATION);
/* Ignore errors and reset the flag */
ctx_rtu->confirmation_to_ignore = FALSE;
rc = 0;
if (ctx->debug) {
printf("Confirmation to ignore\n");
}
} else {
rc = _modbus_receive_msg(ctx, req, MSG_INDICATION);
if (rc == 0) {
/* The next expected message is a confirmation to ignore */
ctx_rtu->confirmation_to_ignore = TRUE;
}
}
return rc;
}
- 测试
修改之后可以看到,两台设备都没有问题,并且以10ms的速度扫描了一个晚上也没有出现异常,libmodbus还是非常稳定的。