Bluetooth: Mesh: Improve logic for serving devices erase capabilities
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 <dominik.ermel@nordicsemi.no>
This commit is contained in:
parent
fa795f4912
commit
49f5598835
2 changed files with 63 additions and 24 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue