Menu

#9 Setting custom baud rate for serial ports on Linux

next_release
open
nobody
None
1
2018-04-19
2015-12-15
Steve Karg
No

On newer kernel versions for linux, there is a new way of setting
custom baud rate for serial ports, but it is not well documented yet:

#include <asm/termios.h>

...
/* termios2 is very similar to the original termios, with the addition
 * of the explicit speed fields */
struct termios2 tio;

ioctl (handle, TCGETS2, &tio);
...
/* these two lines are for telling the driver that the speed will be custom */
tio.c_cflag &= ~CBAUD;
tio.c_cflag |= BOTHER;
/* input and output speeds are always the same, to my knowledge */
tio.c_ispeed = 76800;
tio.c_ospeed = 76800;
...
ioctl (handle, TCSETS2, &tio);

All other settings are completely the same as before, but there are no
standard api for this functionality.
I thought it might be useful and more consistent for linux rs485 code.

Also, there is a standard way for setting 485 mode on linux (taken from
Documentation/serial/serail-rs485.txt):

...
4. USAGE FROM USER-LEVEL

From user-level, RS485 configuration can be get/set using the previous
ioctls. For instance, to set RS485 you can use the following code:

        #include <linux/serial.h>

        /* Driver-specific ioctls: */
        #define TIOCGRS485      0x542E
        #define TIOCSRS485      0x542F

        /* Open your specific device (e.g., /dev/mydevice): */
        int fd = open ("/dev/mydevice", O_RDWR);
        if (fd < 0) {
                /* Error handling. See errno. */
        }

        struct serial_rs485 rs485conf;

        /* Enable RS485 mode: */
        rs485conf.flags |= SER_RS485_ENABLED;

        /* Set logical level for RTS pin equal to 1 when sending: */
        rs485conf.flags |= SER_RS485_RTS_ON_SEND;
        /* or, set logical level for RTS pin equal to 0 when sending: */
        rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);

        /* Set logical level for RTS pin equal to 1 after sending: */
        rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
        /* or, set logical level for RTS pin equal to 0 after sending: */
        rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);

        /* Set rts delay before send, if needed: */
        rs485conf.delay_rts_before_send = ...;

        /* Set rts delay after send, if needed: */
        rs485conf.delay_rts_after_send = ...;

        /* Set this flag if you want to receive data even whilst sending data */
        rs485conf.flags |= SER_RS485_RX_DURING_TX;

        if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
                /* Error handling. See errno. */
        }

        /* Use read() and write() syscalls here... */

        /* Close the device when finished: */
        if (close (fd) < 0) {
                /* Error handling. See errno. */
        }

Discussion

Anonymous
Anonymous

Add attachments
Cancel