Using serial ports in Linux
by Richard Russell, March 2022
In both Windows and Linux-derived operating systems serial ports are treated like files, i.e. to read data from a serial port you would use INPUT# or BGET# etc. and to write data to a serial port you would use PRINT# or BPUT# etc. Apart from the fact that serial ports are typically much slower than files, you access them the same way.
However serial ports differ from files in two important respects. Firstly they require configuring before use (for example to set the baud rate, number of bits, parity etc.) and secondly you cannot rely on input data being immediately available to read.
With a file you can generally assume that, until the end-of-file is reached, any amount of data can be read (although there may be a delay when accessing a network drive), but with a serial port you may have to wait an indefinite period for incoming data to arrive.
So to avoid your BASIC program 'blocking' in a statement like INPUT# whilst it waits for data to arrive, there needs to be some way to test how much data is 'waiting' in an input buffer. Then the program can continue to perform useful tasks whilst it waits.
To configure and open a serial port in Linux you should use code similar to the following (in this case the port /dev/ttyUSB0 is being configured for 1 stop bit, 8 data bits, no parity and a speed of 9600 baud). Note the addition of a trailing dot in the OPENUP function to suppress appending a .bbc extension:
OSCLI "ldattach -1 -8 -n -s 9600 0 /dev/ttyUSB0;" OSCLI "stty -F /dev/ttyUSB0 9600 raw;" serial% = OPENUP("/dev/ttyUSB0.")
To test how much data is 'waiting' in an input buffer, and can therefore be read safely without blocking, use the EXT# function, similar to this:
WHILE EXT#serial% byte& = BGET#serial% REM Do something with the data here ENDWHILE REM Continue with any background tasks
Notes on permissions
Typically to access a serial port in Linux you will either need root privileges (e.g. by using sudo) or be a member of the dialout group. You can add the current user to the dialout group as follows:
sudo usermod -a -G dialout $USER
For this change to become active it is likely that you will need to restart your PC.