embassy-rs/embassy · error

EEPROM regions for chip

Error message

EEPROM regions for chip {} are not contiguous, which is unexpected for L0/L1 series. First region: '{}' at {:#X}. Found next non-contiguous region: '{}' at {:#X}. Please verify chip metadata. Embassy currently assumes contiguous EEPROM for these series.

What it means

embassy-stm32's build script validates that, for STM32L0/L1 chips, the EEPROM regions parsed from chip metadata are contiguous in address space. When the next sorted region does not start exactly where the previous one ends, the build panics because the EEPROM driver assumes a single contiguous block for these series. This is a compile-time (build-time) assertion, not a runtime failure.

Solutions

  1. Check the printed region names/addresses and compare against the ST datasheet for that chip
  2. Fix or regenerate the stm32-data metadata for the chip (stm32-data YAML) so EEPROM regions are contiguous
  3. Report/patch the chip metadata in embassy-stm32 or stm32-data upstream if the hardware really is contiguous but metadata is wrong
  4. If the chip genuinely has non-contiguous EEPROM, model it as separate regions instead of relying on the L0/L1 contiguous assumption

Example fix

// before (chip metadata yaml)
eeprom:
  - address: 0x08080000
    size: 1024
  - address: 0x08081000
    size: 1024
// after
 eeprom:
  - address: 0x08080000
    size: 1024
  - address: 0x08080400
    size: 1024
Defensive patterns

Strategy: validation

Validate before calling

// build-time: verify EEPROM region contiguity for L0/L1 before building
let regions = get_eeprom_regions(chip); // from your metadata source
let mut expected = regions[0].address + regions[0].size;
for r in &regions[1..] {
    assert_eq!(r.address, expected, "non-contiguous EEPROM region {}", r.name);
    expected = r.address + r.size;
}

Prevention

When it happens

Trigger: Running `cargo build` on an embassy-stm32 project targeting an L0/L1 chip whose generated metadata lists multiple EEPROM regions with an address gap (chip_name, first region name/address and offending region name/address are printed in the message).

Common situations: Using a recently added or uncommon L0/L1 chip whose metadata files were generated incorrectly; embassy version updates that introduced region parsing for L0/L1; manually edited or regenerated stm32-data metadata.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/4163408225764c4d. Report an issue: GitHub.

Appendix: source

Thrown at embassy-stm32/build.rs:2958

    let eeprom_memory_regions: Vec<&MemoryRegion> =
        memory.iter().filter(|x| x.kind == MemoryRegionKind::Eeprom).collect();

    if !eeprom_memory_regions.is_empty() {
        cfgs.enable("eeprom");

        let mut sorted_eeprom_regions = eeprom_memory_regions.clone();
        sorted_eeprom_regions.sort_by_key(|r| r.address);

        let first_eeprom_address = sorted_eeprom_regions[0].address;
        let mut total_eeprom_size = 0;
        let mut current_expected_address = first_eeprom_address;

        for region in sorted_eeprom_regions.iter() {
            if region.address != current_expected_address {
                // For STM32L0 and STM32L1, EEPROM regions (if multiple) are expected to be contiguous.
                // If they are not, this indicates an issue with the chip metadata or an unsupported configuration.
                panic!(
                    "EEPROM regions for chip {} are not contiguous, which is unexpected for L0/L1 series. \
                    First region: '{}' at {:#X}. Found next non-contiguous region: '{}' at {:#X}. \
                    Please verify chip metadata. Embassy currently assumes contiguous EEPROM for these series.",
                    chip_name, sorted_eeprom_regions[0].name, first_eeprom_address, region.name, region.address
                );
            }
            total_eeprom_size += region.size;
            current_expected_address += region.size;
        }

        let eeprom_base_usize = first_eeprom_address as usize;
        let total_eeprom_size_usize = total_eeprom_size as usize;

        g.extend(quote! {
            pub const EEPROM_BASE: usize = #eeprom_base_usize;
            pub const EEPROM_SIZE: usize = #total_eeprom_size_usize;
        });
    }

View on GitHub (pinned to 463a07b963)