Project

General

Profile

Actions

Feature #13975

closed

support for higher baud rates

Added by Joshua M. Clulow 3 months ago. Updated about 1 month ago.

Status:
Closed
Priority:
Normal
Category:
kernel
Start date:
Due date:
% Done:

100%

Estimated time:
Difficulty:
Medium
Tags:
Gerrit CR:

Description

Baud rate selection on UNIX systems is a somewhat dusty corner of history. At some point in the distant past, the lower four bits of c_cflag in the termios structure were set aside to select the baud rate, using the constant CBAUD as a mask. This worked right up until serial lines exceeded 38400 baud, with the following speeds:

#define B0      0
#define B50     1
#define B75     2
#define B110    3
#define B134    4
#define B150    5
#define B200    6
#define B300    7
#define B600    8
#define B1200   9
#define B1800   10
#define B2400   11
#define B4800   12
#define B9600   13
#define B19200  14
#define B38400  15

There are, of course, faster speeds, with higher numbers:

#define B57600  16
#define B76800  17
#define B115200 18
#define B153600 19
#define B230400 20
#define B307200 21
#define B460800 22
#define B921600 23

But where, dear reader, do we put the extra bits? CS6 with a value of 16 consumes the next bit over in c_cflag. As it turns out, we have set aside another higher bit, CBAUDEXT, to signal that we are using the extended range. Baud rates faster than 38k4 are first reduced by 16 so that they can fit in the four bit space, and CBAUDEXT is set so that the kernel knows we did it. This means B921600 is effectively a CBAUD value of 7, leaving 8 slots in the range 8-15 free for our use here.

Though one might be forgiven for imagining the wallpaper peeling away at 921600 baud, there have since been new developments in the field of asynchronous serial communications. Some UARTs now run into the megabaud range, and indeed Linux systems have a set of extra higher speeds with which we could be source compatible:

#define  B1000000  0010010
#define  B1152000  0010011
#define  B1500000  0010012
#define  B2000000  0010013
#define  B2500000  0010014
#define  B3000000  0010015
#define  B3500000  0010016
#define  B4000000  0010017

As luck would have it, adding these extra definitions would take us right up to 31, which would represent the top of the CBAUDEXT space.

See Control Modes in termio(7I) for more background.

Once we add this, at least one driver can be immediately modified to support some of the higher speeds: usbftdi, which appears ready to support some existing 3Mbaud UART parts.


Files

stty.sh (1.38 KB) stty.sh Joshua M. Clulow, 2021-08-25 11:17 PM

Related issues

Related to illumos gate - Bug #13979: support FTDI FT232H serial interfaceClosedJoshua M. Clulow

Actions
Actions #1

Updated by Joshua M. Clulow 3 months ago

  • Related to Bug #13979: support FTDI FT232H serial interface added
Actions #2

Updated by Joshua M. Clulow 3 months ago

  • Gerrit CR set to 1658
Actions #3

Updated by Joshua M. Clulow 3 months ago

Testing Plan

This change touches a lot of different things, some of which we should test:

  • stty is able to use the new speeds
    • set incoming baud rate; e.g., stty ispeed 3000000
    • set outgoing baud rate; e.g., stty ospeed 3000000
    • set baud rate in both directions at once; e.g., stty 3000000
    • check after each that stty shows the correct output
  • pppd can use the new speeds
  • the manual pages render correctly
  • serial console login still works
  • MDB still works
  • KMDB still works
  • tip works with the new speed
  • usbftdi works with at least one FTDI 232H device at the new higher speeds

Things that we are unlikely to test:

  • dial(3NSL) in libnsl
  • usbsacm, as we'd need some hardware
  • the printing bits
Actions #4

Updated by Joshua M. Clulow 2 months ago

I have attached a test program that exercises stty at some old, and all new, speeds. It fails when run on a system without the change:

$ ./stty.sh
speed 50 ok
ispeed 50 ok
ospeed 50 ok
speed 1200 ok
ispeed 1200 ok
ospeed 1200 ok
speed 4800 ok
ispeed 4800 ok
ospeed 4800 ok
speed 9600 ok
ispeed 9600 ok
ospeed 9600 ok
speed 921600 ok
ispeed 921600 ok
ospeed 921600 ok
unknown mode: 1000000
ERROR: could not set speed 1000000
Actions #5

Updated by Joshua M. Clulow 2 months ago

Testing Notes

I built and installed this change, and then rebuilt minicom and picocom (two terminal programs from outside the gate) to pick up the new baud rate definitions. I was then able to use these terminal programs with an FTDI 232H UART device to connect to a Linux machine at 115200, 2Mbaud, and 3Mbaud and exchange files (using XMODEM). To the extent that the rest of the testing involves a physical serial line (e.g., for PPP) it was also performed using this hardware and this remote peer.

I confirmed, using the stty.sh script attached to the ticket, that stty is able to set and get the new speeds. Without the change, the correctly script fails because the older system does not know about the new baud rates.

I set up PPP between the test host and a Linux machine and was able to confirm, using iperf3, reasonable performance at 3Mbaud:

-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
Accepted connection from 3.0.0.1, port 54210
[  5] local 3.0.0.2 port 5201 connected to 3.0.0.1 port 61329
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec   257 KBytes  2.11 Mbits/sec
[  5]   1.00-2.00   sec   284 KBytes  2.33 Mbits/sec
[  5]   2.00-3.00   sec   281 KBytes  2.31 Mbits/sec
[  5]   3.00-4.00   sec   284 KBytes  2.33 Mbits/sec
[  5]   4.00-5.00   sec   283 KBytes  2.32 Mbits/sec
[  5]   5.00-6.00   sec   281 KBytes  2.31 Mbits/sec
[  5]   6.00-7.00   sec   283 KBytes  2.32 Mbits/sec
[  5]   7.00-8.00   sec   283 KBytes  2.32 Mbits/sec
[  5]   8.00-9.00   sec   281 KBytes  2.31 Mbits/sec
[  5]   9.00-10.00  sec   283 KBytes  2.32 Mbits/sec
[  5]  10.00-11.00  sec   283 KBytes  2.32 Mbits/sec
[  5]  11.00-12.00  sec   283 KBytes  2.32 Mbits/sec
[  5]  12.00-13.00  sec   284 KBytes  2.33 Mbits/sec
[  5]  13.00-14.00  sec   284 KBytes  2.33 Mbits/sec
[  5]  14.00-15.00  sec   286 KBytes  2.34 Mbits/sec
[  5]  15.00-16.00  sec   283 KBytes  2.32 Mbits/sec
[  5]  16.00-17.00  sec   286 KBytes  2.34 Mbits/sec
[  5]  17.00-18.00  sec   284 KBytes  2.33 Mbits/sec
[  5]  18.00-19.00  sec   284 KBytes  2.33 Mbits/sec
[  5]  19.00-19.86  sec   246 KBytes  2.33 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-19.86  sec  5.47 MBytes  2.31 Mbits/sec                  receiver
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
Accepted connection from 3.0.0.1, port 43640
[  5] local 3.0.0.2 port 5201 connected to 3.0.0.1 port 63279
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   636 KBytes  5.21 Mbits/sec    0   79.2 KBytes
[  5]   1.00-2.00   sec   373 KBytes  3.06 Mbits/sec    0   79.2 KBytes
[  5]   2.00-3.00   sec   187 KBytes  1.53 Mbits/sec    0   79.2 KBytes
[  5]   3.00-4.00   sec   373 KBytes  3.06 Mbits/sec    0   79.2 KBytes
[  5]   4.00-5.00   sec   187 KBytes  1.53 Mbits/sec    0   79.2 KBytes
[  5]   5.00-6.00   sec   373 KBytes  3.06 Mbits/sec    0   79.2 KBytes
[  5]   6.00-7.00   sec   187 KBytes  1.53 Mbits/sec    0   79.2 KBytes
[  5]   7.00-8.00   sec   373 KBytes  3.06 Mbits/sec    0   79.2 KBytes
[  5]   8.00-9.00   sec   187 KBytes  1.53 Mbits/sec    0   79.2 KBytes
[  5]   9.00-10.00  sec   373 KBytes  3.06 Mbits/sec    0   79.2 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.03  sec  3.17 MBytes  2.65 Mbits/sec    0             sender

I confirmed that the manual pages altered in the change render correctly on the new system; i.e., termio(7I), usbsacm(7D), usbftdi(7D), and stty(1).

I confirmed that mdb still works as well as it did before.

I confirmed that tip -3000000 /dev/term/0 works for communication with a remote peer at that high baud rate (using picocom on the remote peer).

I also installed the new bits on a (virtual) machine with a serial console (ttya at 9600 baud) and confirmed that both regular console login and KMDB both still function.

Actions #6

Updated by Electric Monk about 1 month ago

  • Status changed from New to Closed
  • % Done changed from 0 to 100

git commit d9c3e05c2d8261e3f133b5e96a300b4fa6c0f1b7

commit  d9c3e05c2d8261e3f133b5e96a300b4fa6c0f1b7
Author: Joshua M. Clulow <josh@sysmgr.org>
Date:   2021-09-14T07:08:56.000Z

    13975 support for higher baud rates
    Reviewed by: Robert Mustacchi <rm@fingolfin.org>
    Approved by: Richard Lowe <richlowe@richlowe.net>

Actions

Also available in: Atom PDF