Using UART in Linux using C (termios)

UART or Universal Asynchronous Receiver/Transmitter is an extremely common serial communication method used in embedded systems. There is also something called USART or Universal Synchronous Asynchronous Receiver Transmitter which is almost the same as UART except that you have an explicit clock signal that acts as the heartbeat of the bit transfer.

One of the reasons why modern-day embedded systems use UART so heavily is the sheer ease of use as well as ease of implementation. The protocol is simple to understand and since it uses only 2 pins (3 in case of USART), it is very easy to implement even on low-end microcontrollers with a small physical footprint!

This is what a typical U(S)ART system looks like.

U(S)ART Connections

While this post is not meant to dive into the details of the protocol, a short explanation is warranted.

A Typical UART Frame

A typical UART frame has 4 main components – one of which may be absent from the frame altogether depending on the configuration being used.

Start Bit

As the name suggests, the start bit indicates the start of a new UART frame. The idle state of the transmitter line is a HIGH state. So, logic would tell us that this has to something different – it indeed is!

The start bit is basically a LOW bit at the start of the frame and is 1 bit-time long. For example: if the baud rate for the communication is 115200 bps (bits per second), then the start bit is a transition from idle (HIGH) to LOW and lasts for 1/115200 seconds i.e. roughly 8.7 microseconds.

Character and Character Size

What follows the start bit is the character. This is the data that the transmitter wants to send to the receiver.

The character size in a typical embedded system is 8 bits but you do see possible configurations being 6 bits, 7 bits and even 9 bits. The 9 bit implementation is generally used where you want to use one of the bits to indicate something to the other party. For example: if a transmitter wants to send n number of bytes to the receiver but does not have a way to explicitly tell the number to expect, it may simply use the 9th bit to indicate whether the character being sent is the last one or not. There are many other uses like using the 9th bit in a chained serial bus.

The character may be sent with the least significant bit first or most significant bit first – this can be chosen in the configuration of the UART peripheral.

Parity Bit

This is an optional bit that can be configured to be present or absent in the UART frame. If enabled, the parity bit gets sent after the character. Simply put, the parity bit is a rudimentary data integrity indicator for the receiver. It is of two types.

  1. Even Parity Bit – this means that the parity bit will be HIGH if the number of HIGH bits in the character is odd i.e. 1, 3, 5, etc. This ensures that the number of HIGH bits in the frame (excluding the start and stop bits) is even – hence the name Even Parity bit.
  2. Odd Parity Bit – this means that the parity bit will be HIGH if the number of HIGH bits in the character is even i.e. 0, 2, 4, etc. This ensures that the number of HIGH bits in the frame (excluding the start and stop bits) is odd – hence the name Odd Parity bit.

For example: if the data to be sent is the number 7 i.e. 0b00000111 i.e. 3 HIGH bits. Then, if the parity configuration of the peripheral is set to odd parity, then the parity bit sent out is LOW (since there are already odd number of HIGH bits). Similarly, if the parity configuration of the peripheral is set to even parity, then the parity bit sent out is HIGH to make the total number of HIGH bits even i.e. 4 (3 + 1).

Stop Bit(s)

The stop bit is located at the end of the UART frame.

It is basically a HIGH state which is 1 or 2 bits long depending on the configuration of the UART peripheral. This indicates to the receiver that the frame has ended and the next LOW state will be basically be interpreted as a start bit.

So, overall this is how a typical UART frame would look like!

Remember – the parity bit is optional!

MAKE SURE THE UART CONFIGURATIONS ARE THE SAME ON BOTH SIDES i.e. the transmitter and the receiver!

UART in Linux

Termios is a very common user-space frameworks in Linux that make using UART a breeze! This is in line with the philosophy of linux – heavy abstraction, modularity and portability!

Would you like to learn about termios, its usage and how you can do a simple UART implementation in linux using termios? Check out this video on our YouTube channel!

The GitHub link for the loopback application used in the video is located here:

https://github.com/sckulkarni246/ke-rpi-samples/tree/main/uart-c-termios

Leave a ReplyCancel reply