embassy-rs/embassy · error

Bank 2 not present

Error message

Bank 2 not present

What it means

Generated into embassy-stm32's flash driver: when the chip metadata has no second flash bank region, `bank_2` compiles to `panic!("Bank 2 not present")`. It fires at runtime when code accesses flash bank 2 on a single-bank chip (or when bank swap mode is queried and the alternate bank is absent).

Solutions

  1. Use only bank 1 / single-bank flash APIs on single-bank parts.
  2. Build for the correct chip feature that actually has two flash banks if dual-bank operation is required.
  3. Remove dual-bank/swap logic (fb_mode checks) when targeting a single-bank device.

Example fix

// before
flash.write(FLASH_BANK2_BASE + addr, data);
// after
// single-bank chip: operate only via the default flash region
flash.write(addr, data);
Defensive patterns

Strategy: validation

Validate before calling

// runtime guard before dual-bank access
if single_bank_chip() { /* restrict all writes to bank 1 region */ }

Prevention

When it happens

Trigger: Enabling dual-bank flash usage or flash bank swap (check_fb_mode / SYSCFG fb_mode path) on a chip that only has one flash bank, so any access to bank 2 hits the generated panic.

Common situations: Running single-bank parts (many F4/G0/G4/WB variants) with code written for dual-bank parts; setting the DUAL_BANK option bytes or reading `SYSCFG.MEMRMP.fb_mode` on single-bank parts.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at embassy-stm32/build.rs:544

        let mut bank_1_base = None;
        let mut bank_2_base = None;
        let mut otp_base = None;
        for region in flash_memory_regions.iter() {
            if region.name == "BANK_1" || region.name == "BANK_1_REGION_1" {
                bank_1_base = Some(region.address);
            } else if region.name == "BANK_2" || region.name == "BANK_2_REGION_1" {
                bank_2_base = Some(region.address);
            } else if region.name == "OTP" {
                otp_base = Some(region.address);
            }
        }
        let bank_1 = bank_1_base
            .map(|a| quote!(#a))
            .unwrap_or_else(|| quote!(panic!("Bank 1 not present")));
        let bank_2 = bank_2_base
            .map(|a| quote!(#a))
            .unwrap_or_else(|| quote!(panic!("Bank 2 not present")));
        let otp = otp_base
            .map(|a| quote!(#a))
            .unwrap_or_else(|| quote!(panic!("OTP not present")));

        let (swap_check, bank1, bank2) = if check_fb_mode {
            (
                quote! { let is_swapped = crate::pac::SYSCFG.memrmp().read().fb_mode(); },
                quote! { if is_swapped { #bank_2 } else { #bank_1 } },
                quote! { if is_swapped { #bank_1 } else { #bank_2 } },
            )
        } else {
            (quote! {}, quote! { #bank_1 }, quote! { #bank_2 })
        };

        flash_regions.extend(quote! {
            impl crate::flash::FlashBank {
                /// Absolute base address.
                pub fn base(&self) -> u32 {

View on GitHub (pinned to 463a07b963)