stephane / libmodbus

A Modbus library for Linux, Mac OS, FreeBSD and Windows
http://libmodbus.org
GNU Lesser General Public License v2.1
3.52k stars 1.77k forks source link

RS485 Half Duplex Problems (multithreaded application) #360

Open ulimitedCoder opened 8 years ago

ulimitedCoder commented 8 years ago

Hi,

I would like to know if libmodbus inherently supports half duplex communication over serial. If so how can I set it. I am currently trying to use libmodbus stack in half duplex RS485 serial mode. I have two threads one which is a writer and one which is reader but it appears that libmodbus is not blocking the threads from using the serial port at the same time.

Is there anyway to tell libmodbus that the communication is half duplex?

libmodbus version

3.0.4

thunder-weasel commented 7 years ago

Seems like a standard shared resource issue, mutex maybe?

musedavid commented 6 years ago

libmodbus support half duplex communication over serial RS485 and use rts pin control the read/write state

static ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length)
{
#if defined(_WIN32)
    modbus_rtu_t *ctx_rtu = ctx->backend_data;
    DWORD n_bytes = 0;
    return (WriteFile(ctx_rtu->w_ser.fd, req, req_length, &n_bytes, NULL)) ? (ssize_t)n_bytes : -1;
#else
#if HAVE_DECL_TIOCM_RTS
    modbus_rtu_t *ctx_rtu = ctx->backend_data;
    if (ctx_rtu->rts != MODBUS_RTU_RTS_NONE) {
        ssize_t size;

        if (ctx->debug) {
            fprintf(stderr, "Sending request using RTS signal\n");
        }

        ctx_rtu->set_rts(ctx, ctx_rtu->rts == MODBUS_RTU_RTS_UP);
        usleep(ctx_rtu->rts_delay);

        size = write(ctx->s, req, req_length);

        usleep(ctx_rtu->onebyte_time * req_length + ctx_rtu->rts_delay);
        ctx_rtu->set_rts(ctx, ctx_rtu->rts != MODBUS_RTU_RTS_UP);

        return size;
    } else {
#endif
        return write(ctx->s, req, req_length);
#if HAVE_DECL_TIOCM_RTS
    }
#endif
#endif
}