Raspberry Pi Serial Ports
Table of Contents
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.
- If bluetooth is enabled
- the primary port is UART1 which
- is disabled by default so to enable it
- assert
enable_uart=1
in/boot/config.txt
.
- However, when UART1 is enabled
- the VPU core clock is locked 250MHz which
- is required to enable UART1 (Mini UART) to work properly but
- this slows the operation of the VPU unless
force_turbo=1
is also set (in/boot/config.txt
) in which case- it's locked to the highest VPU frequency instead but this
- 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?
- assert
dtoverlay=disable-bt
(in/boot/config.txt
) which - selects UART0 as the primary port (enabled by default) and
- 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.