embassy-rs/embassy · error

The erase sizes for the concatenated flashes must have have…

Error message

The erase sizes for the concatenated flashes must have have a gcd equal to the max erase size

What it means

`get_max_erase_size` requires the larger of the two ERASE_SIZE values to be divisible by both erase sizes, i.e. the max erase size equals the gcd. ConcatFlash must expose one ERASE_SIZE that covers both devices' erase alignment; if neither erase size divides the max, the invariant fails and it panics at const evaluation.

Solutions

  1. Pick two flashes whose erase sizes divide evenly (one must be a multiple of the other)
  2. Use a flash chip with a sector size that is a multiple of the other's
  3. Add a software erase-size wrapper presenting a compatible ERASE_SIZE (translate erase addresses to the chip's sector grid)
  4. Reduce to using only one flash type if alignment cannot be achieved

Example fix

// before
let flash = ConcatFlash::new(flash_a /* ERASE_SIZE=4096 */, flash_b /* ERASE_SIZE=6144 */); // 6144 % 4096 != 0
// after
let flash = ConcatFlash::new(flash_a /* ERASE_SIZE=4096 */, flash_b /* ERASE_SIZE=8192 */); // 8192 % 4096 == 0
Defensive patterns

Strategy: validation

Validate before calling

const fn erase_ok(a: usize, b: usize) -> bool {
    let max = if a > b { a } else { b };
    max % a == 0 && max % b == 0
}
const _: () = assert!(erase_ok(FLASH_A_ERASE, FLASH_B_ERASE), "erase sizes not aligned");

Prevention

When it happens

Trigger: `ConcatFlash::new(a, b)` where e.g. ERASE_SIZE values are 4096 and 65536? no — 65536%4096==0 passes; it fails for values like 4096 and 8192? also passes. It fails for mutually non-dividing sizes, e.g. 4096 and 6144, or 2048 and 4096 fails only when the smaller doesn't divide the larger (e.g. 3072 & 4096).

Common situations: Concatenating flash from different families with incompatible sector sizes (e.g. 4 KiB and 32 KiB subsectors that don't divide each other); off-brand SPI NOR with unusual sector sizes; changing the second flash in a design without re-checking erase alignment.

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/97f808d68109f5f1. Report an issue: GitHub.

Appendix: source

Thrown at embassy-embedded-hal/src/flash/concat_flash.rs:39

    }
    first_read_size
}

const fn get_write_size(first_write_size: usize, second_write_size: usize) -> usize {
    if first_write_size != second_write_size {
        panic!("The write size for the concatenated flashes must be the same");
    }
    first_write_size
}

const fn get_max_erase_size(first_erase_size: usize, second_erase_size: usize) -> usize {
    let max_erase_size = if first_erase_size > second_erase_size {
        first_erase_size
    } else {
        second_erase_size
    };
    if max_erase_size % first_erase_size != 0 || max_erase_size % second_erase_size != 0 {
        panic!("The erase sizes for the concatenated flashes must have have a gcd equal to the max erase size");
    }
    max_erase_size
}

impl<First, Second, E> ErrorType for ConcatFlash<First, Second>
where
    First: ErrorType<Error = E>,
    Second: ErrorType<Error = E>,
    E: NorFlashError,
{
    type Error = E;
}

impl<First, Second, E> ReadNorFlash for ConcatFlash<First, Second>
where
    First: ReadNorFlash<Error = E>,
    Second: ReadNorFlash<Error = E>,
    E: NorFlashError,

View on GitHub (pinned to 463a07b963)