Setting custom baud rate for serial ports on Linux
Brought to you by:
skarg
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):
...
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. */
}
Anonymous