How BE-IIS HAT++ Works
Introduction
The conventional method of enabling hardware on ARM-based Linux systems involves several manual steps:
- Creating a suitable device tree overlay for the target hardware
- Building or enabling the required kernel drivers (modules or built-in)
- Deploying the overlay to the correct location within the boot partition
- Configuring the firmware to apply the overlay during system startup
This process requires in-depth knowledge of the Linux kernel, device tree structure, and platform-specific boot mechanisms.
Example workflow:
# Build kernel module
make modules
# Copy overlay
cp my-overlay.dtbo /boot/firmware/overlays/
# Enable overlay
echo "dtoverlay=my-overlay" >> /boot/firmware/config.txt
Raspberry Pi HAT+
The Raspberry Pi HAT+ specification simplifies hardware integration significantly.
During boot, the system reads the EEPROM located on the HAT via the I²C interface and extracts the associated device tree overlay name.
If the specified overlay is available on the system, it is automatically applied by the firmware.
The EEPROM is connected to a dedicated I²C bus used for HAT identification, allowing the system to detect attached hardware automatically.
# Example: EEPROM detection
i2cdetect -y 0
However, the required driver must still be available in the system—either built into the kernel or provided as a loadable kernel module.
Overlay Handling
A brief note on device tree overlays:
The device tree describes the hardware configuration of a system, including the interconnection between the processor and attached peripherals.
It provides the information required for the Linux kernel to match devices with their corresponding drivers.
A device tree overlay (overlay) is used to extend or modify the base device tree.
It allows additional or optional hardware to be described without modifying the base system configuration.
In many systems, the base device tree defines the core hardware platform (SoC and mainboard),
while overlays are used for add-on hardware such as HATs.
From a system perspective, a HAT must be described to the ARM Linux system.
This is typically done using a device tree overlay, which enables proper driver binding and hardware initialization.
On Raspberry Pi systems, overlays are typically stored in:
ls /boot/firmware/overlays/
Applying an Overlay
The most common way to apply a device tree overlay is during system boot.
The Raspberry Pi firmware loads the base device tree and applies overlays from a predefined configuration.
On Raspberry Pi systems, this configuration is typically defined in:
cat /boot/firmware/config.txt
Example entry:
dtoverlay=my-overlay
Additionally, overlays can be automatically applied via the HAT EEPROM mechanism.
It is also possible to apply an overlay at runtime using the following command:
sudo dtoverlay my-overlay
The corresponding overlay file must be available in:
ls /boot/firmware/overlays/
The dtoverlay tool is part of the Raspberry Pi userland utilities and is usually pre-installed on Raspberry Pi OS.
However, overlays applied at runtime have limitations.
They may not take full effect if the hardware has already been initialized and bound to a driver.
For example:
lsmod | grep spi
If a device has already been created and bound to a driver during boot,
applying a new overlay at runtime will not reconfigure or override the existing binding.
HAT++
A HAT++ configured in Instance Mode I behaves exactly like a standard HAT+.
It is automatically detected by the Raspberry Pi firmware, and the corresponding device tree overlay is applied during boot.
In contrast to HAT+, the HAT++ concept enables stacking of multiple boards.
Concept
Instead of providing a single overlay per HAT, HAT++ defines multiple overlays—one for each supported instance mode.
Each instance mode represents a predefined hardware configuration, including:
- SPI chip select mapping
- IRQ assignment
- I²C addresses (if applicable)
Instance Mode I (Primary HAT)
The overlay for Instance Mode I has a special role:
- It fully describes the functionality of the primary HAT
- It defines and reserves all shared system resources used across the complete HAT++ stack
- It ensures that no generic drivers are bound to unused but reserved interfaces
This guarantees that additional HAT++ boards can be integrated later without resource conflicts.
Runtime Extension
After the kernel has booted and the system is initialized, systemd starts a dedicated service.
systemctl status be-iis-hatpp.service
This service:
- Scans for additional HAT++ boards via their EEPROM addresses
- Identifies their configured instance modes
- Dynamically loads the corresponding overlays into the running system
sudo dtoverlay hatpp-instance-2
Because all required resources have already been reserved by Instance Mode I,
these overlays can be applied at runtime without conflicts.
Summary
HAT++ does not introduce new kernel mechanisms.
It is a structured combination of existing concepts:
- HAT EEPROM identification
- Device tree overlays
- Controlled resource allocation
- Runtime overlay loading via user space
This enables reliable, conflict-free stacking of multiple HATs on a single system.