Chapter 10: Raspberry Pi 5 Hardware Overview: Peripherals and I/O

Chapter Objectives

Upon completing this chapter, you will be able to:

  • Understand the architecture and capabilities of the core peripherals on the Raspberry Pi 5, including GPIO, USB, Ethernet, and wireless interfaces.
  • Identify the key hardware interfaces like MIPI DSI/CSI and the new PCIe connector and explain their roles in an embedded system.
  • Implement basic hardware interactions using command-line tools and shell scripts to control GPIO pins and manage network connections.
  • Configure and verify the operation of various peripherals connected to the Raspberry Pi 5.
  • Debug common hardware and driver-related issues encountered during peripheral integration.
  • Analyze the trade-offs between different I/O technologies for a given embedded application.

Introduction

The heart of any embedded system is its ability to interact with the outside world. While the processor and memory are critical for computation, it is the peripherals and I/O interfaces that allow a device to sense, actuate, and communicate. The Raspberry Pi 5, a significant leap forward in single-board computing, is defined not just by its powerful 64-bit quad-core ARM Cortex-A76 processor, but by the rich array of hardware interfaces it provides. Understanding these interfaces is the foundational skill for moving from pure software development to the integrated, hardware-aware world of embedded systems engineering.

In this chapter, we will embark on a detailed exploration of the Raspberry Pi 5’s hardware capabilities. We will move beyond simply listing specifications and delve into the “how” and “why” of each major peripheral. We will investigate how the Broadcom BCM2712 system-on-chip (SoC) and the new RP1 I/O controller chip work in concert to provide a flexible and powerful platform for everything from simple hobbyist projects to complex industrial prototypes. You will learn not just what a GPIO pin is, but how to control it at a low level from the Linux command line. We will explore not just that the Pi has USB, but how the USB subsystem is managed within the Linux kernel. This knowledge is crucial because in the world of embedded Linux, the lines between hardware and software are blurred. A software driver is useless without correctly connected hardware, and the most sophisticated sensor is inert without the software to interpret its data. By the end of this chapter, you will have the practical skills to connect and control the physical world, transforming your Raspberry Pi 5 from a simple computer into the brain of a true embedded system.

Technical Background

The Raspberry Pi 5’s I/O capabilities represent a fundamental architectural shift from its predecessors. For the first time, the majority of peripheral functions have been moved off the main application processor (the BCM2712 SoC) and onto a dedicated, Raspberry Pi-designed I/O controller chip known as the RP1. This change was driven by the need to provide faster, more numerous, and more flexible I/O options without compromising the performance of the main CPU. The BCM2712 and the RP1 communicate over a high-speed PCI Express (PCIe) Gen 2.0 x4 link, a type of interface typically found in desktop PCs, which underscores the performance ambitions of this new platform. This architectural decision is central to understanding how every peripheral on the board operates.

The RP1 I/O Controller: The Heart of Peripherals

graph TD
    subgraph "Connected via PCIe to BCM2712"
        RP1[<b>RP1 I/O Controller</b>]
        style RP1 fill:#1e3a8a,stroke:#1e3a8a,stroke-width:2px,color:#ffffff
    end

    subgraph "Managed Peripherals"
        USB3[2x USB 3.0 Ports]
        USB2[2x USB 2.0 Ports]
        ETH[Gigabit Ethernet]
        GPIO[40-Pin GPIO Header]
        SERIAL["Legacy Serial<br>(SPI, I2C, UART)"]
        
        style USB3 fill:#0d9488,stroke:#0d9488,stroke-width:1px,color:#ffffff
        style USB2 fill:#0d9488,stroke:#0d9488,stroke-width:1px,color:#ffffff
        style ETH fill:#0d9488,stroke:#0d9488,stroke-width:1px,color:#ffffff
        style GPIO fill:#10b981,stroke:#10b981,stroke-width:1px,color:#ffffff
        style SERIAL fill:#f59e0b,stroke:#f59e0b,stroke-width:1px,color:#ffffff
    end

    RP1 --> USB3
    RP1 --> USB2
    RP1 --> ETH
    RP1 --> GPIO
    RP1 --> SERIAL

The RP1 is a custom-designed Application-Specific Integrated Circuit (ASIC) that acts as the southbridge for the Raspberry Pi 5. In traditional computer architecture, a southbridge is a chip that manages the slower I/O devices. On the Pi 5, the RP1 handles a vast array of functions that were previously integrated into the main SoC. This includes the USB 2.0 and 3.0 ports, the Gigabit Ethernet port, the MIPI camera and display transceivers, and the venerable 40-pin GPIO header. By offloading these tasks, the BCM2712’s resources are freed to focus on computation, and the I/O performance is significantly enhanced. For example, the USB 3.0 ports can now support simultaneous 5Gbps operation, a feat not possible on prior models where I/O bandwidth was a shared, and often limited, resource.

General-Purpose Input/Output (GPIO)

The 40-pin header is perhaps the most iconic feature of the Raspberry Pi, representing its direct connection to the world of electronics. These General-Purpose Input/Output (GPIO) pins are digital channels that can be programmatically configured as either inputs or outputs. When configured as an output, a pin can be set to a high voltage level (typically 3.3V) or a low voltage level (0V or Ground), allowing it to turn on an LED, activate a relay, or send a signal to another digital device. When configured as an input, a pin can detect the voltage level applied to it, allowing the Pi to read the state of a button, receive a signal from a sensor, or communicate with another microcontroller.

On the Raspberry Pi 5, these pins are managed by the RP1 controller. The Linux kernel exposes these GPIOs through a powerful and standardized subsystem called gpiod (GPIO device). This modern interface replaces older, less safe methods like direct memory manipulation. The gpiod subsystem treats GPIOs as character devices within the Linux filesystem, found under /dev/gpiochip*. Each gpiochip represents a bank of GPIO pins managed by a controller. This abstraction allows for safe, multi-user access to GPIOs and prevents conflicts where multiple programs might try to control the same pin simultaneously.

Beyond simple input and output, many of the GPIO pins have alternate functions. Through software configuration, a pin can be switched from a general-purpose role to a specialized one, such as being part of a Serial Peripheral Interface (SPI) bus, an Inter-Integrated Circuit (I2C) bus, or a Universal Asynchronous Receiver-Transmitter (UART). These are serial communication protocols essential for interfacing with a vast ecosystem of sensors, displays, and other integrated circuits. For example, the I2C protocol uses just two wires (SDA for data and SCL for clock) to communicate with potentially hundreds of devices, each with a unique address. SPI is a faster, full-duplex protocol often used for high-bandwidth devices like memory chips or high-resolution displays. The ability to multiplex these functions onto the 40-pin header is what makes the Raspberry Pi such a versatile tool for hardware prototyping.

Universal Serial Bus (USB)

The Universal Serial Bus is the most common peripheral interface in modern computing, and the Raspberry Pi 5 provides a significant upgrade in this domain. It features two USB 3.0 ports capable of 5Gbps speeds and two USB 2.0 ports. All four ports are managed by the RP1 controller. The key improvement is not just the speed but the available bandwidth. The PCIe link between the BCM2712 and the RP1 provides ample data throughput, allowing both USB 3.0 ports to operate at their full potential simultaneously. This is critical for applications like connecting high-speed storage devices (e.g., SSDs) for use as a boot drive or for data logging, or for interfacing with high-resolution webcams or software-defined radios.

sequenceDiagram
    actor User
    participant HW as USB Port (RP1)
    participant Kernel as Linux Kernel (Core)
    participant udev as udev Daemon
    participant Driver as Class Driver (e.g., usb-storage)

    User->>+HW: Plugs in USB Flash Drive
    HW->>+Kernel: Notifies of new device connection
    Kernel->>Kernel: Reads basic device info
    Kernel->>+udev: Emits "add" event with Vendor/Product ID
    udev->>udev: Matches ID against rules database
    udev->>+Kernel: Requests loading of 'usb-storage' driver
    Kernel->>+Driver: probe() function called with device info
    Driver->>HW: Initializes device, reads capacity, etc.
    HW-->>-Driver: Device ready
    Driver->>-Kernel: Claims the device interface
    Kernel->>udev: Confirms driver binding
    udev->>-User: Creates device node (/dev/sda1)
    Note over User,Driver: Filesystem is now mountable!

Within the Linux operating system, the USB subsystem is managed by a complex stack of drivers. At the lowest level is the host controller driver, which communicates with the USB hardware on the RP1. Above this, class drivers handle specific types of devices (e.g., usb-storage for flash drives, usbhid for keyboards and mice). When a USB device is plugged in, the kernel’s udev daemon detects the new device, identifies it using its Vendor ID and Product ID, and automatically loads the appropriate driver. This plug-and-play functionality, which we take for granted on desktop systems, is a cornerstone of what makes Linux a powerful embedded operating system. The lsusb command is an indispensable tool for inspecting the USB bus and viewing all connected devices and their properties.

Networking: Ethernet, Wi-Fi, and Bluetooth

Connectivity is central to modern embedded systems, which are often part of the Internet of Things (IoT). The Raspberry Pi 5 offers a robust suite of networking options.

The Gigabit Ethernet port, also managed by the RP1, provides a reliable, high-speed wired connection. It supports full 1Gbps throughput, making it suitable for applications requiring stable, low-latency communication, such as network-attached storage (NAS), local web servers, or streaming high-definition video. In Linux, the Ethernet interface is typically named eth0 and is managed by the standard networking stack. Tools like ip and ethtool are used to configure the interface’s IP address and inspect its status, link speed, and other properties.

For wireless connectivity, the Raspberry Pi 5 integrates a dual-band (2.4GHz and 5.0GHz) Wi-Fi 5 (802.11ac) and Bluetooth 5.0 with Bluetooth Low Energy (BLE) support. This wireless module is one of the few I/O components that remains connected directly to the BCM2712 SoC, not the RP1. This design choice likely relates to the high-frequency radio engineering requirements and the need for a short, clean signal path to the antenna. The Wi-Fi interface allows the Pi to connect to standard wireless networks, acting as a client or even as a wireless access point. The Bluetooth radio enables communication with a wide range of peripherals, from wireless keyboards and audio devices to the vast ecosystem of BLE sensors used in health, fitness, and home automation. In Linux, Wi-Fi interfaces are typically named wlan0, and tools like iw and wpa_supplicant are used to scan for and connect to networks. Bluetooth is managed by the BlueZ stack, with tools like bluetoothctl providing a command-line interface for pairing and managing devices.

Display and Camera Interfaces (MIPI DSI/CSI)

The Raspberry Pi has always excelled at multimedia tasks, and the Pi 5 continues this tradition with two four-lane MIPI (Mobile Industry Processor Interface) ports. These are high-speed serial interfaces designed specifically for connecting cameras and displays in mobile devices. The Pi 5 can use these two ports in any combination of camera or display (two cameras, two displays, or one of each).

graph TD
    subgraph "Camera Input Path (CSI)"
        A[Camera Module] -->|MIPI CSI-2<br>Raw Image Data| B(Image Signal Processor<br><i>in BCM2712</i>);
        B --> C{System Memory / CPU};
        style A fill:#1e3a8a,stroke:#1e3a8a,stroke-width:2px,color:#ffffff
        style B fill:#8b5cf6,stroke:#8b5cf6,stroke-width:1px,color:#ffffff
        style C fill:#ef4444,stroke:#ef4444,stroke-width:1px,color:#ffffff
    end

    subgraph "Display Output Path (DSI)"
        D{Application / OS<br>Generates Framebuffer} --> E(VideoCore VII GPU<br><i>in BCM2712</i>);
        E -->|MIPI DSI<br>Pixel Stream| F[Display Panel];
        style D fill:#ef4444,stroke:#ef4444,stroke-width:1px,color:#ffffff
        style E fill:#8b5cf6,stroke:#8b5cf6,stroke-width:1px,color:#ffffff
        style F fill:#10b981,stroke:#10b981,stroke-width:2px,color:#ffffff
    end

    linkStyle 0 stroke:#0d9488,stroke-width:2px;
    linkStyle 1 stroke:#0d9488,stroke-width:2px;
    linkStyle 2 stroke:#0d9488,stroke-width:2px;
    linkStyle 3 stroke:#0d9488,stroke-width:2px;

The Display Serial Interface (DSI) is used for output, connecting the Pi’s graphics processor (the VideoCore VII GPU) to a compatible display. The Camera Serial Interface (CSI) is used for input, connecting a compatible camera module directly to the Image Signal Processor (ISP) within the BCM2712. Using these direct interfaces, rather than a more general-purpose one like USB, offers significant advantages. The data path is highly optimized, resulting in very low latency and minimal CPU overhead. This allows the Pi to capture and process high-resolution, high-frame-rate video (e.g., 1080p at 60fps or 4K at 30fps) without bogging down the main processor, which is critical for computer vision applications.

PCI Express (PCIe)

Perhaps the most exciting new feature for advanced users is the external PCI Express Gen 2.0 x1 slot. PCIe is a high-speed serial computer expansion bus standard that is ubiquitous in desktop and server computers for connecting graphics cards, network cards, and fast storage devices. Its inclusion on a low-cost single-board computer is a game-changer, opening the door to a new class of high-performance peripherals.

sequenceDiagram
    actor User
    participant Kernel
    participant PCIeBus
    participant PCIDevice

    User->>+Kernel: Boots System
    Kernel->>+PCIeBus: Scans for devices (Enumeration)
    PCIeBus->>+PCIDevice: Configuration Read Request
    PCIDevice-->>-PCIeBus: Returns Vendor & Device ID
    PCIeBus-->>-Kernel: Reports detected device IDs

    Kernel->>Kernel: Search driver matching Vendor/Device ID
    alt Driver Found
        Kernel->>+PCIDevice: Assigns resources (IRQ, Memory)
        Kernel->>PCIDevice: Calls driver's probe() function
        PCIDevice-->>-Kernel: Initializes hardware
        Note right of PCIDevice: Device is now active
        Kernel-->>User: Creates device node (e.g., /dev/nvme0n1)
    else Driver Not Found
        Kernel-->>User: Logs "Unknown device" message
        Note right of PCIDevice: Device remains inactive
    end
    deactivate Kernel

The interface is exposed as a 16-pin, 0.5mm pitch FPC (Flexible Printed Circuit) connector on the board. While it only provides a single lane (x1) of PCIe Gen 2.0, this still offers a theoretical throughput of 500 MB/s, which is significantly faster than USB 3.0. This makes it ideal for connecting high-speed devices that were previously impractical, such as NVMe SSDs for ultra-fast storage, dedicated AI accelerators, or multi-gigabit network interface cards. Because PCIe is a standard bus, many existing devices can be used with an appropriate physical adapter (an “FPC to M.2” adapter, for example). The Linux kernel has mature and robust support for PCIe, and devices that are compliant with the standard will often be detected and work with existing drivers, a process known as “enumeration.” The lspci command is the standard tool for listing and inspecting devices connected to the PCIe bus. This interface truly bridges the gap between the hobbyist and professional embedded worlds.

Practical Examples

Theory provides the foundation, but true understanding comes from hands-on practice. In this section, we will walk through practical, step-by-step examples of how to interact with the key peripherals of the Raspberry Pi 5 directly from the Raspberry Pi OS command line. These examples assume you are running a fresh installation of Raspberry Pi OS (Bookworm or later) and are logged in via SSH or using a directly connected keyboard and monitor.

Warning: Always exercise caution when working with electronics. Double-check your wiring before powering on the Raspberry Pi. Incorrect connections can permanently damage the board or connected components.

Example 1: Basic GPIO Control – Blinking an LED

This “Hello, World!” of embedded systems demonstrates fundamental output control. We will connect an LED to a GPIO pin and use the gpiod command-line tools to turn it on and off.

Hardware Integration

  • Components:
    • 1x Raspberry Pi 5
    • 1x Breadboard
    • 1x 5mm LED (any color)
    • 1x 330Ω resistor
    • Jumper wires
  • Wiring:
    1. Connect a jumper wire from a Ground pin on the Raspberry Pi 5 (e.g., Pin 6) to the blue rail (ground rail) of the breadboard.
    2. Place the LED into the breadboard. Note that it has a long leg (anode, positive) and a short leg (cathode, negative).
    3. Connect the 330Ω resistor from the anode (long leg) of the LED to an empty row on the breadboard.
    4. Connect the cathode (short leg) of the LED to the ground rail on the breadboard.
    5. Connect a jumper wire from the other end of the resistor to GPIO 17 (Pin 11) on the Raspberry Pi 5.

Build and Configuration Steps

The gpiod tools provide a modern, safe way to interact with GPIOs. First, we need to identify the GPIO controller and the line number.

Identify GPIO Chips:List the available GPIO controllers on the system. On the Pi 5, the main GPIOs are on the RP1, which will likely be gpiochip0 or gpiochip1.

Bash
gpiodetect


Expected Output:

Plaintext
gpiochip0 [pinctrl-rp1] (54 lines)
gpiochip10 [gpio-brcmstb@107d508500] (32 lines)
gpiochip11 [gpio-brcmstb@107d517c00] (17 lines)
gpiochip12 [gpio-brcmstb@107d517c20] (6 lines)
gpiochip13 [gpio-brcmstb@107d508520] (4 lines)
gpiochip0 [pinctrl-rp1] (54 lines)


Here, gpiochip0 is the controller we want, managed by the rp1 driver.

Get GPIO Line Information:Let’s check the status of line 17 (which corresponds to GPIO 17).gpioinfo gpiochip0
You will see a long list of all pins. Look for line 17:... line 17: "GPIO17" unused input active-high ...
This tells us the line is currently unused and configured as an input.

Code Snippets (Shell Script)

graph TD
    subgraph "Hardware Initialization"
        A[Power On / Reset] --> B{Boot ROM};
        style A fill:#1e3a8a,stroke:#1e3a8a,stroke-width:2px,color:#ffffff
    end

    subgraph "Bootloader Stages"
        B --> C["1st Stage Bootloader <br><i>(e.g., SPL)</i>"];
        C --> D["2nd Stage Bootloader <br><i>(e.g., U-Boot)</i>"];
        style C fill:#0d9488,stroke:#0d9488,stroke-width:1px,color:#ffffff
        style D fill:#0d9488,stroke:#0d9488,stroke-width:1px,color:#ffffff
    end

    subgraph "Kernel Initialization"
        D --> E{"Load Kernel Image <br> & Device Tree Blob (DTB)"};
        E --> F[Kernel Decompression];
        F --> G[Kernel Starts Execution];
        G --> H[Initialize Hardware <br> based on DTB];
        H --> I["Mount Root Filesystem <br><i>(read-only)</i>"];
        style E fill:#8b5cf6,stroke:#8b5cf6,stroke-width:1px,color:#ffffff
        style F fill:#8b5cf6,stroke:#8b5cf6,stroke-width:1px,color:#ffffff
        style G fill:#8b5cf6,stroke:#8b5cf6,stroke-width:1px,color:#ffffff
        style H fill:#8b5cf6,stroke:#8b5cf6,stroke-width:1px,color:#ffffff
        style I fill:#8b5cf6,stroke:#8b5cf6,stroke-width:1px,color:#ffffff
    end

    subgraph "Userspace Initialization"
        I --> J{"Execute init Process <br><i>(e.g., systemd, SysVinit)</i>"};
        J --> K["Remount Root FS (read/write)"];
        K --> L[Start System Services <br> & Daemons];
        L --> M{Login Prompt / GUI};
        style J fill:#ef4444,stroke:#ef4444,stroke-width:1px,color:#ffffff
        style K fill:#0d9488,stroke:#0d9488,stroke-width:1px,color:#ffffff
        style L fill:#0d9488,stroke:#0d9488,stroke-width:1px,color:#ffffff
        style M fill:#10b981,stroke:#10b981,stroke-width:2px,color:#ffffff
    end

    %% Styling
    classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px;
    classDef decision fill:#f59e0b,stroke:#f59e0b,stroke-width:1px,color:#ffffff
    class B,E decision;

We can now use gpioset to control the pin. The following script will blink the LED 5 times.

Create a file named blink.sh:

Bash
nano blink.sh

Add the following content:

ShellScript
#!/bin/bash

# A simple script to blink an LED connected to GPIO 17 on a Raspberry Pi 5

# Define the GPIO chip and line number
GPIO_CHIP="gpiochip0"
LED_PIN=17

echo "Starting LED blink script..."

# Set the GPIO pin as an output and initialize it to low (off)
# The -m time option will release the line after 20 seconds automatically
gpioset -m time -s 20 "$GPIO_CHIP" "$LED_PIN"=0

# Loop 5 times to blink the LED
for i in {1..5}
do
  echo "Turning LED ON"
  gpioset "$GPIO_CHIP" "$LED_PIN"=1 # Set pin high (3.3V)
  sleep 1

  echo "Turning LED OFF"
  gpioset "$GPIO_CHIP" "$LED_PIN"=0 # Set pin low (0V)
  sleep 1
done

echo "Script finished."

Make the script executable and run it:

Bash
chmod +x blink.sh
./blink.sh

You should see the LED on your breadboard turn on and off for one-second intervals. This example demonstrates the fundamental output capability that is the basis for controlling motors, relays, and countless other actuators.

Example 2: Managing Network Interfaces

This example shows how to view and manage the Ethernet and Wi-Fi interfaces using standard Linux command-line tools.

Viewing Interface Status

The ip command is the modern tool for network configuration in Linux.

Show all interfaces:

Bash
ip addr


Expected Output (abbreviated):

Plaintext
1: lo: <LOOPBACK,UP,LOWER_UP> ...
    inet 127.0.0.1/8 scope host lo
       ...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
    inet 192.168.1.100/24 brd 192.168.1.255 scope global dynamic noprefixroute eth0
       ...
3: wlan0: <BROADCAST,MULTICAST> ...
    ...


This shows the loopback (lo), Ethernet (eth0), and Wi-Fi (wlan0) interfaces. Here, eth0 has an IP address assigned (192.168.1.100).

Connecting to a Wi-Fi Network

Connecting to a Wi-Fi network from the command line typically involves using wpa_supplicant.

1. Scan for Networks:Use the iw tool to scan for available wireless networks.

Bash
sudo iw wlan0 scan | grep SSID


This will list the SSIDs of all nearby networks.

2. Configure wpa_supplicant: Edit the configuration file to add your network credentials.

Bash
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf


Add the following block to the end of the file, replacing "YourSSID" and "YourPassword" with your network’s details.

Plaintext
network={
    ssid="YourSSID"
    psk="YourPassword"
}


Tip: For security, the password (psk) can be pre-encrypted using the wpa_passphrase utility.

3. Restart the Interface: Reconfigure the interface to apply the new settings.

Plaintext
sudo wpa_cli -i wlan0 reconfigure


After a few moments, check the interface status again with ip addr. You should see that wlan0 now has an IP address.

Example 3: Inspecting USB and PCIe Devices

This example demonstrates how to use lsusb and lspci to discover and inspect devices connected to these high-speed buses.

Inspecting USB Devices

1. Plug a USB device, such as a flash drive or a keyboard, into one of the USB ports on the Pi 5.

Run the lsusb command.

Bash
lsusb


Expected Output:

Plaintext
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub
Bus 001 Device 003: ID 0424:2514 Microchip Technology, Inc. (formerly SMSC) USB 2.0 Hub
Bus 001 Device 004: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 005: ID 0951:1666 Kingston Technology DataTraveler 100 or compatible
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub


The output shows a hierarchy of hubs built into the Pi, and importantly, it has identified a “Kingston Technology DataTraveler” flash drive. The ID 0951:1666 is the Vendor and Product ID that Linux uses to find the correct driver.

Inspecting PCIe Devices

To test the PCIe slot, you need a compatible device and an adapter, such as an M.2 NVMe SSD with an FPC-to-M.2 adapter board.

Hardware Integration:

  • Safely power down the Raspberry Pi 5.
  • Connect the PCIe adapter to the FPC connector on the Pi.
  • Install an NVMe SSD into the adapter’s M.2 slot.
  • Power on the Raspberry Pi 5.

Enable PCIe in Firmware: By default, the external PCIe port may be disabled. You need to enable it in the bootloader configuration.

Bash
sudo rpi-eeprom-config --edit


In the editor that opens, add the following line:

Plaintext
PCIE_EXT_ENABLE=1


Save and exit. You will be prompted to reboot for the changes to take effect.

List PCIe Devices: After rebooting, run the lspci command.

Bash
lspci


Expected Output (if an NVMe drive is detected):

Plaintext
0000:00:00.0 PCI bridge: Broadcom Inc. and subsidiaries BCM2712 PCIe Bridge
0000:01:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd NVMe SSD Controller SM981/PM981/PM983
0001:00:00.0 PCI bridge: Broadcom Inc. and subsidiaries BCM2712 PCIe Bridge
0001:01:00.0 Ethernet controller: Raspberry Pi (Trading) Ltd RP1 Ethernet Controller
...


This output confirms that the system has enumerated the PCIe bus and found a “Non-Volatile memory controller,” which is our NVMe SSD. The kernel will automatically load the nvme driver, and the drive should now appear as a block device (e.g., /dev/nvme0n1) that can be partitioned and formatted.

Common Mistakes & Troubleshooting

Even with careful planning, issues are a normal part of embedded development. Here are some common pitfalls encountered when working with Raspberry Pi 5 peripherals and how to approach them.

Mistake / Issue Symptom(s) Troubleshooting / Solution
Incorrect GPIO Voltage GPIO pin stops working, erratic behavior, or permanent damage to the Pi. Solution: The Pi’s GPIOs are 3.3V only. Never connect 5V logic directly. Use a logic level shifter or a voltage divider circuit to interface with 5V devices.
Insufficient Power Supply Random reboots, under-voltage warnings (lightning bolt icon), USB devices disconnecting. Solution: Use the official Raspberry Pi 5 27W (5V/5A) USB-C power supply. For power-hungry peripherals (like SSDs), use a powered USB hub.
Wi-Fi Connection Fails Cannot find SSID, authentication fails, no IP address assigned. 1. Update System: Run sudo apt update && sudo apt full-upgrade.
2. Set Country Code: Use sudo raspi-config to set the correct Wi-Fi country.
3. Check Kernel Log: Use dmesg | grep wlan for firmware or driver error messages.
PCIe Device Not Detected Device does not appear in lspci output after installation. 1. Check Connection: Ensure the FPC cable is fully seated and latched.
2. Enable in EEPROM: Add PCIE_EXT_ENABLE=1 via sudo rpi-eeprom-config –edit and reboot.
3. External Power: Ensure the PCIe device/adapter has adequate power; some need a separate power input.
I2C/SPI Device Not Found Code reports “No such device” or cannot communicate with a connected sensor. For I2C: Run i2cdetect -y 1 to scan the bus and verify the device’s address.
For SPI: Double-check all four wire connections: MISO, MOSI, SCLK, and CS (Chip Select).
Both: Ensure the interface is enabled in raspi-config and the device is powered with 3.3V.

Exercises

These exercises are designed to reinforce the concepts from this chapter and build your practical skills. They range from simple verification to a more involved configuration task.

  1. Button Input Detection:
    • Objective: Read the state of a push button using a GPIO pin.
    • Guidance:
      1. Connect a push button to the breadboard. Wire one side to GPIO 23 (Pin 16) and the other side to Ground (e.g., Pin 20).
      2. Use the gpioget command to read the state of the pin. Since the other side is connected to ground, when you press the button, the pin’s value will be 0. When released, it will be “floating”.
      3. Improve the circuit by enabling the internal pull-up resistor. This can be done with the gpioset command by setting the pin’s bias. Research how to set a pull-up using the gpiod tools. Now, the pin should read 1 when the button is not pressed and 0 when it is.
    • Verification: Write a simple shell script that uses a while loop and gpioget to continuously print “Button Pressed” or “Button Released” to the console.
  2. USB Drive Performance Test:
    • Objective: Measure the read/write speed of a USB 3.0 flash drive.
    • Guidance:
      1. Plug a USB 3.0 compatible flash drive into one of the blue USB 3.0 ports.
      2. Use lsblk or dmesg to identify the device name (e.g., /dev/sda1).
      3. Mount the drive to a directory, e.g., sudo mount /dev/sda1 /mnt.
      4. Use the dd command to test write and read speeds.
        • Write Test: dd if=/dev/zero of=/mnt/testfile bs=1M count=1024 conv=fdatasync
        • Read Test: First, clear the buffer cache: sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'. Then, read the file: dd if=/mnt/testfile of=/dev/null bs=1M.
    • Verification: Note the speeds reported by dd. Repeat the test with the drive plugged into a black USB 2.0 port. Compare the results and explain the difference based on the underlying technology.
  3. Create a Wireless Access Point:
    • Objective: Configure the Raspberry Pi 5’s Wi-Fi interface to act as a wireless access point (AP).
    • Guidance:
      1. This is a more advanced task. You will need to install software like hostapd (to manage the AP) and dnsmasq (to provide DHCP/DNS services).
      2. Follow a reputable online tutorial for setting up a Raspberry Pi as a “bridged access point.” This involves configuring hostapd.conf with your desired SSID and password, and configuring dnsmasq to assign IP addresses to clients that connect.
      3. You will need to create a network bridge between eth0 and wlan0 so that wireless clients can access the network that the Pi is wired into.
    • Verification: From your laptop or smartphone, scan for Wi-Fi networks. You should see the SSID you configured. Connect to it using the password you set. You should be assigned an IP address and be able to access the internet.
  4. Explore the Device Tree:
    • Objective: Understand how Linux represents hardware using the Device Tree.
    • Guidance:
      1. The Device Tree is a data structure used to describe the hardware in a system so that the kernel knows which drivers to load. The compiled device tree is located in /boot/firmware/bcm2712-rpi-5-b.dtb.
      2. Install the device tree compiler: sudo apt install device-tree-compiler.
      3. Decompile the binary file into a human-readable source file: dtc -I dtb -O dts /boot/firmware/bcm2712-rpi-5-b.dtb -o my_pi5.dts.
      4. Open my_pi5.dts in a text editor.
    • Verification: Browse through the file. Try to find the nodes that correspond to the hardware we’ve discussed: find the gpio node, the ethernet node, the i2c nodes, and the pcie controller. You don’t need to understand everything, but see if you can identify properties like pin assignments or register addresses. This provides a glimpse into how the OS abstracts the physical hardware.

Summary

This chapter provided a comprehensive tour of the hardware interfaces available on the Raspberry Pi 5, emphasizing the new architecture centered around the RP1 I/O controller.

  • Core Architecture: The Raspberry Pi 5 splits I/O functions between the main BCM2712 SoC and the new RP1 controller, connected by a high-speed PCIe bus. This design significantly boosts peripheral performance.
  • GPIO: The 40-pin header, controlled by the RP1, provides versatile digital I/O. The modern gpiod subsystem in Linux offers a safe and standardized way to control these pins from user space.
  • High-Speed Interfaces: The platform’s capabilities are enhanced by true Gigabit Ethernet, dual USB 3.0 ports with dedicated bandwidth, and a new external PCIe Gen 2.0 x1 slot, opening the door for high-performance peripherals like NVMe SSDs.
  • Connectivity: A full suite of networking options, including wired Ethernet, dual-band Wi-Fi 5, and Bluetooth 5.0/BLE, makes the Pi 5 an ideal platform for IoT and connected applications.
  • Multimedia: Dual four-lane MIPI DSI/CSI ports allow for flexible combinations of high-resolution cameras and displays with low-latency, direct connections to the GPU and ISP.
  • Practical Skills: You have learned to use essential Linux command-line tools (gpiodetect, gpioset, ip, lsusb, lspci) to inspect, configure, and control the hardware, bridging the gap between software commands and physical actions.

By mastering these I/O capabilities, you are now equipped to design and build embedded systems that can effectively and efficiently interact with the physical world.

Further Reading

  1. Raspberry Pi 5 Product Brief: The official starting point for hardware details from the Raspberry Pi Foundation.
  2. RP1 Peripheral Datasheet: A detailed technical document covering the registers and functionality of the I/O controller.
  3. Linux Kernel GPIO Interface Documentation: The official documentation for the gpiod character device interface, essential for modern GPIO control.
  4. PCI-SIG (PCI Special Interest Group): The official source for specifications on the PCI Express standard. While dense, it provides the ultimate authority on how the bus works.
  5. MIPI Alliance: The organization that defines the DSI and CSI specifications. Their website offers overviews of the technologies.
  6. “Linux Device Drivers, 3rd Edition” by Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman: While slightly dated, this book is a seminal, freely available text that provides a deep understanding of how the Linux kernel manages hardware. The core concepts are still highly relevant.
  7. Jeff Geerling’s Blog: A consistently excellent and practical resource for all things Raspberry Pi, often featuring deep dives into new hardware performance and capabilities.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top