|
@@ -267,6 +267,26 @@ static void _modbus_rtu_ioctl_rts(modbus_t *ctx, int on)
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+ssize_t _modbus_rtu_write_n_read(modbus_t *ctx, const uint8_t *req, int req_length) {
|
|
|
|
+ ssize_t w, r, i;
|
|
|
|
+ uint8_t rb[req_length];
|
|
|
|
+
|
|
|
|
+ // Transmit
|
|
|
|
+ w = write(ctx->s, req, req_length);
|
|
|
|
+
|
|
|
|
+ // Read back written bytes if hw has echo
|
|
|
|
+ r = 0;
|
|
|
|
+ while (r < w)
|
|
|
|
+ r += read(ctx->s, rb + r, w - r);
|
|
|
|
+ if (ctx->debug) {
|
|
|
|
+ for (i = 0; i < r; ++i)
|
|
|
|
+ fprintf(stderr, "|%02X|", rb[i]);
|
|
|
|
+ fprintf(stderr, "\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return w;
|
|
|
|
+}
|
|
|
|
+
|
|
static ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length)
|
|
static ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length)
|
|
{
|
|
{
|
|
#if defined(_WIN32)
|
|
#if defined(_WIN32)
|
|
@@ -286,7 +306,10 @@ static ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_lengt
|
|
ctx_rtu->set_rts(ctx, ctx_rtu->rts == MODBUS_RTU_RTS_UP);
|
|
ctx_rtu->set_rts(ctx, ctx_rtu->rts == MODBUS_RTU_RTS_UP);
|
|
usleep(ctx_rtu->rts_delay);
|
|
usleep(ctx_rtu->rts_delay);
|
|
|
|
|
|
- size = write(ctx->s, req, req_length);
|
|
|
|
|
|
+ if(!ctx_rtu->echohw)
|
|
|
|
+ size = write(ctx->s, req, req_length);
|
|
|
|
+ else
|
|
|
|
+ size = _modbus_rtu_write_n_read(ctx, req, req_length);
|
|
|
|
|
|
usleep(ctx_rtu->onebyte_time * req_length + ctx_rtu->rts_delay);
|
|
usleep(ctx_rtu->onebyte_time * req_length + ctx_rtu->rts_delay);
|
|
ctx_rtu->set_rts(ctx, ctx_rtu->rts != MODBUS_RTU_RTS_UP);
|
|
ctx_rtu->set_rts(ctx, ctx_rtu->rts != MODBUS_RTU_RTS_UP);
|
|
@@ -294,7 +317,14 @@ static ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_lengt
|
|
return size;
|
|
return size;
|
|
} else {
|
|
} else {
|
|
#endif
|
|
#endif
|
|
- return write(ctx->s, req, req_length);
|
|
|
|
|
|
+ modbus_rtu_t *ctx_rtu = ctx->backend_data;
|
|
|
|
+ ssize_t w;
|
|
|
|
+
|
|
|
|
+ if(!ctx_rtu->echohw)
|
|
|
|
+ w = write(ctx->s, req, req_length);
|
|
|
|
+ else
|
|
|
|
+ w = _modbus_rtu_write_n_read(ctx, req, req_length);
|
|
|
|
+ return w;
|
|
#if HAVE_DECL_TIOCM_RTS
|
|
#if HAVE_DECL_TIOCM_RTS
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
@@ -1112,6 +1142,27 @@ int modbus_rtu_set_rts_delay(modbus_t *ctx, int us)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+int modbus_rtu_set_echohw_mode(modbus_t* ctx, uint8_t mode) {
|
|
|
|
+ if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
|
|
|
|
+ modbus_rtu_t* rtu = (modbus_rtu_t*) ctx->backend_data;
|
|
|
|
+ rtu->echohw= mode;
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ /* Wrong backend and invalid mode specified */
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int modbus_rtu_get_echohw_mode(modbus_t* ctx) {
|
|
|
|
+ if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
|
|
|
|
+ modbus_rtu_t* rtu = (modbus_rtu_t*) ctx->backend_data;
|
|
|
|
+ return rtu->echohw;
|
|
|
|
+ }
|
|
|
|
+ /* Wrong backend and invalid mode specified */
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
static void _modbus_rtu_close(modbus_t *ctx)
|
|
static void _modbus_rtu_close(modbus_t *ctx)
|
|
{
|
|
{
|
|
/* Restore line settings and close file descriptor in RTU mode */
|
|
/* Restore line settings and close file descriptor in RTU mode */
|