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
|
Enable the BLOB flash stream for reading and writing BLOBs directly to
|
||||||
and from flash.
|
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
|
config BT_MESH_DFU_SRV
|
||||||
bool "Support for Firmware Update Server model"
|
bool "Support for Firmware Update Server model"
|
||||||
depends on BT_MESH_MODEL_EXTENSIONS
|
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);
|
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,
|
static int block_start(const struct bt_mesh_blob_io *io,
|
||||||
const struct bt_mesh_blob_xfer *xfer,
|
const struct bt_mesh_blob_xfer *xfer,
|
||||||
const struct bt_mesh_blob_block *block)
|
const struct bt_mesh_blob_block *block)
|
||||||
{
|
{
|
||||||
struct bt_mesh_blob_io_flash *flash = FLASH_IO(io);
|
struct bt_mesh_blob_io_flash *flash = FLASH_IO(io);
|
||||||
size_t erase_size;
|
|
||||||
|
|
||||||
if (flash->mode == BT_MESH_BLOB_READ) {
|
if (flash->mode == BT_MESH_BLOB_READ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
|
return erase_device_block(flash->area, flash->offset + block->offset, block->size);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rd_chunk(const struct bt_mesh_blob_io *io,
|
static int rd_chunk(const struct bt_mesh_blob_io *io,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue