rpi-eeprom
Raspberry Pi EEPROM management tool for reading, writing, and managing EEPROM content on RPi HAT devices. Supports JSON and YAML custom data formats with multi-section storage.
Installation
pip install rpi-eeprom
On a Raspberry Pi with GPIO hardware access:
pip install rpi-eeprom[gpio]
Prerequisites
EEPROM hardware operations require eepmake, eepdump, and eepflash.sh from the Raspberry Pi utils eeptools. Pre-compiled ARM64 binaries are bundled in release builds. If using a source install, compile them manually:
git clone https://github.com/raspberrypi/utils
cd utils/eeptools
cmake .
make
sudo make install
The I2C bus overlay must be loaded before use:
sudo dtoverlay i2c-gpio i2c_gpio_sda=0 i2c_gpio_scl=1 bus=9
Note: Most EEPROM operations require
sudofor hardware access.
Python Library
from rpi_eeprom import EEPROM, EEPROMConfig
# Use default configuration (bus=9, address=0x50, model=24c32)
with EEPROM() as eeprom:
# Read EEPROM content
content = eeprom.read()
print(content.product_uuid)
print(content.vendor)
print(content.serial_number) # From first custom data section
print(content.custom_data) # All custom data sections
# Write new content (resets EEPROM first)
eeprom.write(custom_data=[{"serial_number": "ABC123XYZ"}])
# Update custom data while preserving UUID and settings
eeprom.update(custom_data=[{"serial_number": "NEW456"}])
# Append a new custom data section
eeprom.update(custom_data=[{"extra": "data"}], append=True)
# Replace a specific section by index
eeprom.update(custom_data=[{"replaced": True}], index=1)
# Reset to blank
eeprom.reset()
Custom configuration
config = EEPROMConfig(
model="24c64",
size_kbytes=8,
i2c_bus=1,
i2c_address=0x51,
write_protect_pin=17,
settings_template="/path/to/custom_settings.txt",
)
with EEPROM(config) as eeprom:
content = eeprom.read()
Reading from device tree
with EEPROM() as eeprom:
# Read how Linux currently sees the EEPROM via /proc/device-tree/
# (reflects state at boot, not live changes)
data = eeprom.read_device_tree(index=0)
print(data["serial_number"])
Writing custom data from files
from pathlib import Path
with EEPROM() as eeprom:
# Write from JSON/YAML files
eeprom.write(custom_data=[
Path("config.json"),
Path("metadata.yaml"),
])
# Mix files and dicts
eeprom.write(custom_data=[
Path("config.json"),
{"serial_number": "ABC123"},
])
Error handling
All operations raise typed exceptions instead of returning booleans:
from rpi_eeprom import (
EEPROM,
EEPROMNotFoundError,
EEPROMReadError,
EEPROMWriteError,
EEPROMConfigError,
)
try:
with EEPROM() as eeprom:
content = eeprom.read()
except EEPROMNotFoundError:
print("No EEPROM device detected on I2C bus")
except EEPROMReadError:
print("Failed to read EEPROM content")
except EEPROMWriteError:
print("Failed to write to EEPROM")
except EEPROMConfigError:
print("Invalid configuration")
CLI
The rpi-eeprom command provides three subcommands: read, write, and reset.
Read EEPROM content
# Read and display as JSON (default)
rpi-eeprom read
# Read as YAML
rpi-eeprom read --format yaml
# Save to a file (format auto-detected from extension)
rpi-eeprom read --output eeprom_data.yaml
# Read a specific custom data section
rpi-eeprom read --index 1
# Read from device tree instead of hardware
rpi-eeprom read --device-tree
rpi-eeprom read --device-tree --index 1
Write to EEPROM
# Write custom data from a JSON file
rpi-eeprom write --data config.json
# Write multiple custom data sections
rpi-eeprom write --data section1.json --data section2.yaml
# Append new sections while preserving existing ones
rpi-eeprom write --data new_section.json --append
# Replace a specific section by index
rpi-eeprom write --data replacement.json --index 1
# Update the serial number
rpi-eeprom write --serial ABC123XYZ
# Auto-detect and handle existing content
rpi-eeprom write
rpi-eeprom write --force # Force overwrite corrupt content
Reset EEPROM
# Reset EEPROM to blank state (all zeros)
rpi-eeprom reset
Configuration file
Use --config to specify EEPROM hardware settings (JSON or YAML):
rpi-eeprom --config my_config.yaml read
Example config.yaml:
model: 24c64
size_kbytes: 8
i2c_bus: 1
i2c_address: 0x51
write_protect_pin: 17
Verbose output
rpi-eeprom -v read
EEPROM Content
A valid EEPROM contains a product UUID, vendor/product info, and one or more custom data sections. Each custom data section can be JSON or YAML.
product_uuid 12345678-1234-5678-1234-567812345678
product_id 0x0105
product_ver 0x0001
vendor "Ubo Technology Company"
product "Ubo HAT+"
custom_data "
{"serial_number": "ZF64JA81VPPZ", "eeprom": {"model": "24c32"}}
\"
A valid EEPROM must have a non-zero product_uuid and a serial_number in its first custom data section. Blank or zero-UUID EEPROMs are automatically re-initialized when using the CLI write command.
Development
# Install in development mode with all dev tools
pip install -e ".[dev]"
# Run tests (unit tests only — no hardware required)
pytest tests/ -v
# Run with coverage
pytest tests/ -v --cov=rpi_eeprom
# Lint
ruff check src/ tests/
# Type check
mypy src/rpi_eeprom/
Hardware end-to-end tests
The tests/test_e2e_hardware.py suite runs against a real EEPROM chip over I2C. These tests are skipped by default and must be opted into explicitly.
Prerequisites
- A Raspberry Pi with an EEPROM-equipped HAT connected
- I2C overlay loaded:
sudo dtoverlay i2c-gpio i2c_gpio_sda=0 i2c_gpio_scl=1 bus=9
- EEPROM tools installed (eepmake, eepdump, eepflash.sh) — see Prerequisites
- Development dependencies with GPIO support:
pip install -e ".[dev,gpio]"
Running hardware tests
# Run all hardware tests (requires sudo for I2C access)
sudo pytest tests/test_e2e_hardware.py -v -m hardware
# Run a specific hardware test
sudo pytest tests/test_e2e_hardware.py -v -m hardware -k "test_full_lifecycle"
# Run both unit and hardware tests together
sudo pytest tests/ -v -m ""
Warning: Hardware tests write to and erase the EEPROM. Any existing data on the chip will be overwritten. The test suite resets the EEPROM to a blank state at the end of the full lifecycle test. If tests are interrupted, the EEPROM may be left in a partially written state.
Custom hardware configuration
The tests use the default EEPROMConfig (bus=9, address=0x50, model=24c32). If your hardware differs, edit the _HW_CONFIG variable at the top of tests/test_e2e_hardware.py:
_HW_CONFIG = EEPROMConfig(
model="24c64",
i2c_bus=1,
i2c_address=0x51,
write_protect_pin=17,
)
License
Apache License 2.0 - see LICENSE for details.
Pre-compiled eeptools binaries (eepmake, eepdump, eepflash.sh) are from raspberrypi/utils under the BSD 3-Clause License - see THIRD_PARTY_NOTICES.
Metadata
Release files for rpi-eeprom 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rpi_eeprom-1.1.0.tar.gz | 49.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rpi_eeprom-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 94.5 kB
Release files / rpi_eeprom-1.1.0.tar.gz
| Download URL | rpi_eeprom-1.1.0.tar.gz |
|---|---|
| Size | 49.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fc1b36accc744d4d70442e6fd531bf3ba73f6aed61d3bfebf4bb2bd68835a088
|
|
BLAKE2b-256 checksum How to use checksums |
bf7b23428c9367dadfddb71fb30b4e88f536ddb69baaab98d2d72dfe0216cee9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 13, 2026.
Transparency logRelease files / rpi_eeprom-1.1.0-py3-none-any.whl
| Download URL | rpi_eeprom-1.1.0-py3-none-any.whl |
|---|---|
| Size | 45.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6c51e9654bb508261837548b10289981f56f3270ab795be3983b19269512d17f
|
|
BLAKE2b-256 checksum How to use checksums |
e2e94e570287a01a8dbe02dc48a7517d7f41003a8b73a4867d56a6e8d5f98fec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 13, 2026.
Transparency log