How can I set the baud rate to 307,200 on Linux?
Linux uses a dirty method for non-standard baud rates, called "baud rate aliasing". Basically, you tell the serial driver to interpret the value B38400
differently. This is controlled with the ASYNC_SPD_CUST
flag in serial_struct
member flags
.
You need to manually calculate the divisor for the custom speed as follows:
// Configure port to use custom speed instead of 38400
ioctl(port, TIOCGSERIAL, &ss);
ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;
ss.custom_divisor = (ss.baud_base + (speed / 2)) / speed;
closestSpeed = ss.baud_base / ss.custom_divisor;
if (closestSpeed < speed * 98 / 100 || closestSpeed > speed * 102 / 100) {
fprintf(stderr, "Cannot set serial port speed to %d. Closest possible is %d\n", speed, closestSpeed));
}
ioctl(port, TIOCSSERIAL, &ss);
cfsetispeed(&tios, B38400);
cfsetospeed(&tios, B38400);
Of course, you need a serial driver with suitable baud_base
and divisor settings. The preceding snippet allows for 2% deviation, which should be ok for most purposes.
And to tell the driver to interpret B38400
as 38400 baud again:
ioctl(mHandle, TIOCGSERIAL, &ss);
ss.flags &= ~ASYNC_SPD_MASK;
ioctl(mHandle, TIOCSSERIAL, &ss);
As a word of caution: I'm not sure if this method is portable between other *nix flavors.
I accomplished this using termios2
and ioctl()
commands.
struct termios2 options;
ioctl(fd, TCGETS2, &options);
options.c_cflag &= ~CBAUD; //Remove current baud rate
options.c_cflag |= BOTHER; //Allow custom baud rate using int input
options.c_ispeed = 307200; //Set the input baud rate
options.c_ospeed = 307200; //Set the output baud rate
ioctl(fd, TCSETS2, &options);
After that, you should be able to query the port settings and see your custom baud rate, as well as the other settings (possible with stty
commands).