Why are serial ports still useful? It is hard to find them on desktop PCs and laptops but they are still an important part of many embedded systems. Here is my list of uses and why I think they’re important.
1. Console i/o
When I am working on an embedded system development project, I will almost certainly have a terminal emulator connected to a serial port on the target system. This is independent of the CPU architecture and the operating system it is running. Even if there is network connection to the target, and it is possible to run a remote shell, I feel happier knowing there is a serial connection that can tell me what is going on, especially if something unexpected happens.
2. Data communications
A serial port connection can be used for inter-processor communication within a system or for communication with different parts of a system. The serial port provides the physical connection between the equipment but a communication protocol has to used to ensure a reliable, error-free data path.
Depending on the requirements of the link, a simple ad-hoc protocol can be implemented or an industry-standard protocol, such as PPP or HDLC, could be used. These protocols have their roots in data communications, allowing point-to-point networking between hosts. This is particularly useful in simple, low-cost equipment that does not include an Ethernet controller for cost, space or power considerations. TCP/IP stacks used in embedded systems generally support using a serial link for the physical connection and PPP or SLIP to provide the link layer protocol.
3. External device communication
Commissioning new equipment or updating system parameters often requires a serial connection to a piece of equipment and interacting with a service program. Network engineers routinely set up switches and other pieces of network infrastructure this way. Often the serial ports from a bank of equipment are connected to a terminal server that allows the engineer to connect to any of them over a network interface.
Serial ports are also used to connect equipment together, e.g. modems of one type or another (PSTN, 3G, satellite), GPS units, telescopes, sensors, power inverters, and many type of industrial control equipment.
4. Peripheral communication bridge
A microprocessor UART can be used to interface to on-board peripherals such as Bluetooth and wireless transceivers, using a dedicated bridge. These bridge devices often include their own firmware that manages the communication protocol over the wireless interface and provide a simple and low-cost way for the microprocessor to use the wireless interface.
UART bridges are also available for other peripheral buses such as SPI and I2C. The microprocessor uses a simple protocol to control the bus master interface and to transmit and receive data from the slave devices connector to the external bus. The details of managing the peripheral bus are handled by the bridge itself. This allows the microprocessor to use a single UART to connect to multiple devices such as EEPROMs, memory devices, temperature sensors, etc.
5. Firmware download
A serial port can used to download firmware to new board or recover a corrupted flash image in the field where access to a JTAG header might be difficult. A simple bootloader in a protected flash sector or in on-chip ROM checks for an external device connected to the serial port and if one is present waits for a new image that will be programmed into flash.
There are many simple file download protocols that can be used for this purpose. For example, one system I worked on had a processor embedded in a Xilinx FPGA which implemented a variant of XMODEM in the bootloader in order to accept a new image to burn into flash.
6. Debugging interface
GNU GDB provides a remote serial protocol that allows debugging sessions to run over a serial interface. This can be used to debug code on systems that do not have a network interface or have processors that do not run an operating system that is capable of running a debugger locally.
Implementing support for GDB on your target system requires you to provide a small number of functions that form what is known to as the debugging stub. These functions are responsible for managing the debug session and providing target-specific support for the debugger such as a reading registers.
Using the GDB serial protocol you can perform most of the standard debugging activities such as loading and running new code, setting breakpoints, dumping registers, etc.
The GDB manual has information on what is required: https://sourceware.org/gdb/current/onlinedocs/gdb/Remote-Stub.html#Remote-Stub
7. Using the Modem status lines as GPIO
In addition to the Tx and Rx signals many UARTs provide modem signals that may or may not be used by the application. Console ports in my experience rarely use these additional signals so they can often be used for some other purpose, assuming they are available and routed to the connector. One thing they’re often useful for is general-purpose outputs for debugging and timing. There are two outputs: RTS, DTR, and 4 inputs: CTS, DSR, DCD, RI. The state of the inputs is read from a status register and the state of the outputs is set by writing to a control register.
In a 16550-compatible UART this is the Modem Status Register (MSR) and Modem Control Register (MCR) respectively. In an ARM PrimeCell UART this is the Flag Register (UARTFR) and the Control Register (UARTCR) respectively.
For example, if you need to time how long it takes to handle a particular interrupt, it’s easy enough to insert code that toggles the state of a modem output at the entry and exit of the interrupt handler. You can then measure the execution time easily on a scope.
What do you do?
Do you still rely on serial interfaces in your embedded systems? What’s the most creative way you’ve found to use a serial port?