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
", 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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…