Welcome to the next installment in my series about different
ways to use the venerable UART in Virtual Platforms. If you missed the first
two parts you can review the introduction and use case 1, about using xterm in slave mode
for an interactive terminal.
This article explains another way to provide an interactive
terminal. Instead of using the xterm in slave mode we can use a network
connection and the telnet program to connect to a UART and have an interactive
terminal.
Recall that the UART has a simple byte interface to send characters
into it and receive characters from it. As long we do this, any implementation
is possible to interact with it.
To use telnet as a way to connect to the UART we replace the
xterm we had before with the telnet program as shown below.

As with the xterm, the telnet program is a separate
executable running in its own process. With the xterm we implemented inter-process
communication (IPC) using a series of system calls to send and receive data to
and from the xterm. This time we again provide inter-process communication, but
using a networking socket. The implementation requires a new SystemC model which
replaces the terminal model. Let's see how we can use telnet to add a
connection to a SystemC UART model.
-
Create a new SystemC model, let's call this one
a "telnet terminal model" with a thread to create a network connection and act
as a server listening for characters to arrive on the socket, and another
thread waiting for characters to arrive from the UART and sending them out on
the network socket.
-
The telnet terminal model can have an option to
either launch the telnet program automatically and connect to the telnet
terminal model on the same machine or allow the user to manually run telnet and
connect to the telnet terminal model from any other machine on the network.
-
Use the SystemC thread that was setup to process
input from the network connection to read the network socket using a read
system call and forward any characters that come in to the UART's rx port.
-
Use the SystemC thread that was setup to process
output from the UART to wait for characters to arrive from the UART tx port and
send them out on the socket using a write system call.
As you can see the flow is very much the same as the xterm
solution; only the implementation of the xterm in slave mode is replaced by a
network socket.
Below is the implementation of the SystemC method that is sensitive
to characters coming from the UART. It writes those charaters to the network
socket.

Below is the implementation of the SystemC thread that polls
the network socket for new characters and upon receiving a character sends it
on to the UART.

There is one additional detail in the code. The readThread()
method doesn't set up the socket communication until the first write to the UART occurs
in the simulation. The idea is that if there are no writes to the UART, then the
interface may not be used at all during simulation, so there is no need to do
anything. The first write to the UART will emit the startReading event and
then the network socket will be setup using a common sequence of socket,
bind, and listen system calls.
In a system running Linux, this first write will come from
the traffic generated by the getty program that is used by
init to open a port and start the login program so users can log in and start a
shell. I will have more on this in the next article that talks about using the
UART for remote debugging with gdb.
One of the configurable parameters of the SystemC telnet
terminal model is the ability to automatically launch the telnet program. This implementation
is different than the xterm from the last article in that it uses the popen
system call to start an xterm which uses the -e option to start telnet.

A screenshot of the automatically launched telnet is shown
below.

This model can also be configured to not launch telnet
automatically, but instead wait for a manual connection from any other machine on the
network. Users can just supply the machine name and port number as arguments to telnet.
A screenshot of the manual connection from another machine
is shown below. In this case I connected to a Linux machine called Pepper on
the Cadence network from my laptop using Windows telnet from the command
prompt.

Like the xterm in slave mode, there are some tricks to getting the
echo working correctly. This time you will see something called telnetOption
that is a set of characters written into the socket. By experimentation I found
that without this the characters are echoed when typed and the terminal doesn't
work all that well. This gets into the details of the telnet protocol and how
to send commands.


It's too deep for this article, but as always you can dig as
deep as you like into the details of telnet. Here is a table of common telnet
commands. You can see the commands 1 and 3 that are used in
telnetOption.

Conclusion
The full details of the code are available in tterm.cpp and
tterm.h. This code is for blogging purposes only, but does work for the
applications I have outlined here. This is another good example of using Linux
system programming to create Virtual Platform models.
Next time I'll cover how this same telnet terminal model can be used to perform
remote application debugging using gdb.
Jason Andrews