Skip to content

Commit

Permalink
Bluetooth: Mesh: Improve logic for serving devices erase capabilities
Browse files Browse the repository at this point in the history
The commit fixes issue where flash_area_flatten has been used where
code was only supposed to erase devices by hardware requirement prior
to write, by replacing the call with flash_area_erase and supporting
logic to select proper path.
There have been following Kconfig options added:
 - CONFIG_BT_MESH_BLOB_IO_FLASH_WITHOUT_ERASE
 - CONFIG_BT_MESH_BLOB_IO_FLASH_WITH_ERASE
that are available for user depending on devices in the system and allow
to turn off paths that are not used by BLOB IO; for example if user
never writes to device with erase CONFIG_BT_MESH_BLOB_IO_FLASH_WITH_ERASE
will disable the path.
Both Kconfig options are y by default and enable all paths.

Signed-off-by: Dominik Ermel <[email protected]>
  • Loading branch information
de-nordic authored and kartben committed Jan 23, 2025
1 parent fa795f4 commit 49f5598
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 24 deletions.
24 changes: 24 additions & 0 deletions subsys/bluetooth/mesh/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,30 @@ config BT_MESH_BLOB_IO_FLASH
Enable the BLOB flash stream for reading and writing BLOBs directly to
and from flash.

if BT_MESH_BLOB_IO_FLASH

config BT_MESH_BLOB_IO_FLASH_WITHOUT_ERASE
bool "BLOB flash support for devices without erase"
default y if FLASH_HAS_NO_EXPLICIT_ERASE
depends on FLASH_HAS_NO_EXPLICIT_ERASE
help
Enable path supporting devices without erase. This option appears only
if there are devices without explicit erase requirements in the system
and may be disabled to reduce code size in case when no operations
are intended on such type of devices.

config BT_MESH_BLOB_IO_FLASH_WITH_ERASE
bool "BLOB flash support for devices with erase"
default y if FLASH_HAS_EXPLICIT_ERASE
depends on FLASH_HAS_EXPLICIT_ERASE
help
Enable path supporting devices with erase. This option appears only
if there are devices requiring erase, before write, in the system
and may be disabled to reduce code size in case when no operations
are intended on such type of devices.

endif # BT_MESH_BLOB_IO_FLASH

config BT_MESH_DFU_SRV
bool "Support for Firmware Update Server model"
depends on BT_MESH_MODEL_EXTENSIONS
Expand Down
63 changes: 39 additions & 24 deletions subsys/bluetooth/mesh/blob_io_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,40 +56,55 @@ static void io_close(const struct bt_mesh_blob_io *io,
flash_area_close(flash->area);
}

static inline int erase_device_block(const struct flash_area *fa, off_t start, size_t size)
{
/* If there are no devices requiring erase, then there is nothing to do */
if (IS_ENABLED(CONFIG_BT_MESH_BLOB_IO_FLASH_WITH_ERASE)) {
const struct device *fdev = flash_area_get_device(fa);

if (!fdev) {
return -ENODEV;
}

/* We have a mix of devices in system */
if (IS_ENABLED(CONFIG_BT_MESH_BLOB_IO_FLASH_WITHOUT_ERASE)) {
const struct flash_parameters *fparam = flash_get_parameters(fdev);

/* If device has no erase requirement then do nothing */
if (!(flash_params_get_erase_cap(fparam) & FLASH_ERASE_C_EXPLICIT)) {
return 0;
}
}

if (IS_ENABLED(CONFIG_FLASH_PAGE_LAYOUT)) {
struct flash_pages_info page;
int err;

err = flash_get_page_info_by_offs(fdev, start, &page);
if (err) {
return err;
}

size = page.size * DIV_ROUND_UP(size, page.size);
start = page.start_offset;
}
return flash_area_erase(fa, start, size);
}

return 0;
}

static int block_start(const struct bt_mesh_blob_io *io,
const struct bt_mesh_blob_xfer *xfer,
const struct bt_mesh_blob_block *block)
{
struct bt_mesh_blob_io_flash *flash = FLASH_IO(io);
size_t erase_size;

if (flash->mode == BT_MESH_BLOB_READ) {
return 0;
}

#if defined(CONFIG_FLASH_PAGE_LAYOUT)
struct flash_pages_info page;
const struct device *flash_dev;
int err;

flash_dev = flash_area_get_device(flash->area);
if (!flash_dev) {
return -ENODEV;
}

err = flash_get_page_info_by_offs(flash_dev,
flash->offset + block->offset, &page);
if (err) {
return err;
}

erase_size = page.size * DIV_ROUND_UP(block->size, page.size);
#else
erase_size = block->size;
#endif

return flash_area_flatten(flash->area, flash->offset + block->offset,
erase_size);
return erase_device_block(flash->area, flash->offset + block->offset, block->size);
}

static int rd_chunk(const struct bt_mesh_blob_io *io,
Expand Down

0 comments on commit 49f5598

Please sign in to comment.