Raspberry Pi Serial Ports

Table of Contents

[2023-10-27 Fri] bookworm has introduced at least one bug in the handling of serial ports on Raspberry Pi. The upstream documentation is also not yet updated so it's not clear how much of what appears to be different is intentional and how much is due to open bugs.

The Raspberry Pi team have their own detailed documentation about the serial ports. We highly recommend you look at that if you want more in-depth explanations. The page you're reading now covers the (somewhat complex) topic of serial ports in a more procedural way. This is likely to be of interest to people who just want to get things done with BitScope Raspberry Pi Clusters.

Serial Ports

Raspberry Pi has multiple serial ports. The first two are called primary and secondary. By default, primary appears on GPIO 14 (transmit) and 15 (receive) of the J8. Secondary is used by bluetooth, on Raspberry Pi that support bluetooth. Each port is driven by a UART. On every Raspberry Pi there are at least two of them: UART0 and UART1. The assignment of which UART drives which port depends on the model and its configuration. The default assignments are:

Model UART0 UART1
Raspberry Pi Zero Primary Secondary
Raspberry Pi Zero W Primary (or Bluetooth) Secondary (or Primary)
Raspberry Pi 1 Primary Secondary
Raspberry Pi 2 Primary Secondary
Raspberry Pi 3 Primary (or Bluetooth) Secondary (or Primary)
Raspberry Pi 4 Primary (or Bluetooth) Secondary (or Primary)
Raspberry Pi 5 Primary (or Bluetooth) Secondary (or Primary)

If bluetooth is enabled UART0 is reassigned to the bluetooth chip. There is no secondary port in this case and UART1 assigned as the primary. See bluetooth for more about this complex topic.

Transceivers

There are two types of Transceiver (UART) available: PL011 and mini UART.

  • The PL011 is a capable, broadly 16550-compatible UART.
  • The mini UART has a reduced feature set (it can be difficult to use).

All UART are 3.3V only (caveat emptor). The available UARTs and their possible pin assignments are:

Name Type Models Enabled GPIO (TX) GPIO (RX) CTS/RTS
UART0 PL011 All Yes 14 32 36 15 33 37 -
UART1 mini UART All No 14 32 40 15 33 41 -
UART2 PL011 Pi4 Only No 0 3 2 3
UART3 PL011 Pi4 Only No 4 7 6 7
UART4 PL011 Pi4 Only No 8 11 10 11
UART5 PL011 Pi4 Only No 12 15 14 15

See the key card to find out which J8 pins provide access to each GPIO.

UART0 is enabled by default. All other UARTs are disabled by default.

Serial Devices

Each UART has an associated serial device. A device is a "file" by which the operating system makes the UART and its associated serial port avalilable to software. There are four serial devices:

Linux device Description
/dev/ttyAMA0 UART0 (First PL011)
/dev/ttyS0 UART1 (Mini UART)
/dev/serial0 UART assigned as primary
/dev/serial1 UART assigned as secondary

Using the second two devices allows you to think in terms of "serial ports" instead of "UARTs". Use /dev/serial0 to access the UART assigned to primary and /dev/serial1 for the secondary regardless of which physical UART that happens to be.

In Raspbian and Raspberry Pi O/S, the devices /dev/serial0 and /dev/serial1 are symbolic links. They are automatically pointed at /dev/ttyS0 or /dev/ttyAMA0 per the tables above. Other operating systems may manage the serial ports differently.

System Console

The System Console is a serial terminal which is the dfault way the kernel and other processes send text output to a user and to receive text input from the user. It (normally) uses the primary serial port (which must also be enabled) and is accessed via GPIO pins 14 and 15. It is configured to communicate as follows:

Baud Rate 115200
Bits 8
Parity None
Stop Bits 1
Flow Control None

When using Raspberry Pi in BitScope Clusters we highly recommend the system console be enabled on slave nodes. The console is enabled by default but if not it can be enabled with raspi-config. Alternatively it can be enabled by ensuring the string 1, 2 or 3 appears in the file /boot/cmdline.txt:

1 console=serial0,115200 preferred
2 console=ttyAMA0,115200 alternative (see serial devices)
3 console=ttyS0,115200 alternative (see serial devices)

To disable the console remove this string from the file and reboot.

Be sure not to accidentially change anything else in /boot/cmdline.txt.

If you want to see kernel messages via the system console before the kernel has fully started, enable Early Console for Linux (in addition to the standard system console) for slave nodes on which you want to see this information.

Bluetooth Issues

Bluetooth complicates serial port use on Raspberry Pi.

  1. If bluetooth is enabled
    1. the primary port is UART1 which
    2. is disabled by default so to enable it
    3. assert enable_uart=1 in /boot/config.txt.
  2. However, when UART1 is enabled
    1. the VPU core clock is locked 250MHz which
    2. is required to enable UART1 (Mini UART) to work properly but
    3. this slows the operation of the VPU unless
    4. force_turbo=1 is also set (in /boot/config.txt) in which case
    5. it's locked to the highest VPU frequency instead but this
    6. causes the Pi to draw a lot more current.

Bottom line: it is not possible to (A) operate the VPU at a variable speed and (B) have bluetooth enabled and (C) use the (full feature) UART0 as the primary port at the same time.

Don't need bluetooth?

  1. assert dtoverlay=disable-bt (in /boot/config.txt) which
  2. selects UART0 as the primary port (enabled by default) and
  3. selects UART1 as the secondary port (disabled by default).

The system service that initialises the modem may also need to be disabled (so it does not connect to the UART). Use sudo systemctl disable hciuart.

Alternatively if you still want bluetooth but you also need the primary port to use UART0 (for baud rate or power consumption reasons) assert dtoverlay=miniuart-bt (to switch Bluetooth to use UART1 and make UART0 the primary UART) but this may reduce the maximum usable baud rate for bluetooth and you must also set the VPU core clock to a fixed frequency using force_turbo=1 or core_freq=250 where the same caveats regarding reduced VPU performance or excessive power consumption apply.

BitScope Clusters

BitScope clusters provide a comprehensive control plane to enable the out-of-band remote control and monitoring of cluster nodes. The control plane is managed by a master node on which the primary serial port must be enabled. This allows the master to manage power, cooling, voltage and current monitoring and hardware level configuration on all the other (slave) nodes. See bluetooth section for advice about how to ensure the primary serial port is enabled on the master node.

IMPORTANT: the master node must also disable the system console (but leave the primary serial port enabled!) to avoid collisions between control plane traffic and ordinary system messages generated by the kernel, firmware or processes seeking to use the console. However, it is recommended to leave the console enabled on the slave nodes to allow full access to the bootloader, firmware and system level debug support when accessing them from the master via the control plane.