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?

Parents
  • 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.

Reply
  • 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.

Children
No Data
Related