bm_storage_erase() triggers Usage Fault (division by zero)

I’m evaluating the nRF Connect SDK Bare Metal SDK and hit an issue with the bm_storage library.
bm_storage_write() and bm_storage_read() work correctly, but bm_storage_erase() immediately crashes with a division-by-zero usage fault.

SDK version: nRF Connect SDK Bare Metal v0.9.0-9b7766ff2787

Kconfig settings:

CONFIG_BM_STORAGE=y
CONFIG_RING_BUFFER=y
CONFIG_BM_STORAGE_BACKEND_SD=y

Problem Analysis

The fault occurs inside this check in bm_storage.c:

if (len == 0 || len % storage->nvm_info->erase_unit != 0) {
    return NRF_ERROR_INVALID_LENGTH;
}

During debugging I noticed:

storage->nvm_info->erase_unit is always 0 for both SD and RRAM backends.

Both drivers define bm_storage_info without an erase_unit field:

const struct bm_storage_info bm_storage_info = {
    .program_unit = SD_WRITE_BLOCK_SIZE,
    .no_explicit_erase = true
};

const struct bm_storage_info bm_storage_info = {
    .program_unit = RRAMC_WRITE_BLOCK_SIZE,
    .no_explicit_erase = true
};


Why is erase_unit left as zero in the Bare Metal storage backends, and what is the correct fix or recommended way to handle erase operations when using the SD or RRAM backend?

  • Hi,

    Thank you for reporting ,this is clearly a bug and we will fix this in a future release. You can fix this specific bug by also populating .erase_unit in the bm_storage_info struct, and setting it equal to the write block size. However, please note that you will then get -ENOTSUP (-34) returned from bm_storage_erase(), as it is currently not implemented.

    Fundamentally, with RRAM you can write both 0 and 1 (unlike flash where write only flips bits from 1 to 0, and erase is needed to flip all bits in a page back to 1). So you can conceptually erase by simply writing (typically all 0). This is what is done in the bm_storage sample which has implemented this in a function called storage_erases(). For now, the recommendation is to do something similar.

Related