aboutsummaryrefslogtreecommitdiff
path: root/NOTES.txt
blob: 1efacd19f4893b3b9ec5b50a2eef8818434b5f1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
The timing code works by calculating how long to sleep after each
character (in microseconds), but actually sleeping slightly less
than that, then busy-waiting until the rest of the interval expires.
At slower bitrates, this works well, and the CPU overhead is barely
noticeable (at least on reasonably fast modern systems).

Timing accuracy depends on your OS, kernel config (HZ and/or NO_HZ
on Linux), and system load. Also on the amount of data, since the
timing loop is self-regulating (the first few bytes will have less
accurate timing than later ones). No "fancy" techniques like realtime
scheduling or hardware event timers are used. At bitrates up to
115200, on an unloaded Linux system, the timing should be at least
99.9% accurate. At higher bitrates, accuracy will decrease.

Timing is more accurate on Linux than OSX. It's done with getitimer()
and sigwait(). This works out to be slightly more accurate than
using usleep() on both Linux and OSX. It would be possible to use
the realtime timer_create() and clock_gettime() API on Linux, for
possibly even better accuracy, but OSX doesn't have these (and I want to be
portable). On an unloaded OSX system, the accuracy gets steadily worse
as you go above 57600bps. There's also more CPU overhead on OSX.

getitimer() and gettimeofday() only have microsecond precision.
slowbaud does better than this by calculating the delay interval to
1/100 of a microsecond, then adding 1us to the delay time that many
times out of 100. For instance, 115200bps is an 86.81us delay. 19
times out of 100, slowbaud sleeps for 86us. The other 81 times, it
sleeps 87us. This puts the average at 86.81us, as it should be.

If this were a truly useful application, it would be worth trying to
increase accuracy further, with realtime process scheduling. I didn't
do this because slowbaud is just a toy, and because the RT stuff tends
to be unportable and require elevated privileges (root, or something
like setrtlimit or extended filesystem attributes to manage capabilities).

About the name... I'm aware that "baud" is not synonymous with bps. I
just think "slowbaud" sounds better than "slowbps", as a name. Anyway
the stty command on both Linux and OSX misuses the term ("speed
38400 baud"), as well as the man page for termios(3), so I'm in good
company.