Skip to content

KVStore: Support external storage out of mbed-os tree #10355

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion features/storage/kvstore/conf/filesystem/mbed_lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"value": "default"
},
"blockdevice": {
"help": "Options are default, SPIF, DATAFASH, QSPIF or SD. If default, the block device will be chosen according to the component defined in targets.json",
"help": "Options are default, SPIF, DATAFASH, QSPIF, SD or other. If default, the block device will be chosen according to the component defined in targets.json. If other, override get_other_blockdevice() to support block device out of Mbed OS tree.",
"value": "default"
},
"external_size": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"value": "default"
},
"blockdevice": {
"help": "Options are default, SPIF, DATAFLASH, QSPIF or SD. If default the block device will be chosen by the defined component",
"help": "Options are default, SPIF, DATAFLASH, QSPIF, SD or other. If default the block device will be chosen by the defined component. If other, override get_other_blockdevice() to support block device out of Mbed OS tree.",
"value": "default"
},
"external_size": {
Expand Down
122 changes: 93 additions & 29 deletions features/storage/kvstore/conf/kv_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ int _storage_config_FILESYSTEM_NO_RBP();
int _storage_config_tdb_external_common();
int _storage_config_filesystem_common();

/**
* @brief If block device out of Mbed OS tree is to support, please overwrite this
* function to provide it.
*
* @returns pointer to other block device.
*/
BlockDevice *get_other_blockdevice();

static const char *filesystemstore_folder_path = NULL;

using namespace mbed;
Expand Down Expand Up @@ -245,7 +253,16 @@ FileSystem *_get_filesystem_default(const char *mount)
#elif COMPONENT_SD
return _get_filesystem_FAT(mount);
#else
return NULL;
BlockDevice *bd = get_other_blockdevice();
if (bd) {
if (bd->get_erase_value() != -1) {
return _get_filesystem_LITTLE(mount);
} else {
return _get_filesystem_FAT(mount);
}
} else {
return NULL;
}
#endif
}

Expand Down Expand Up @@ -617,6 +634,64 @@ BlockDevice *_get_blockdevice_default(bd_addr_t start_address, bd_size_t size)
#endif
}

/* Same logic as _get_blockdevice_SD() except block device replaced with from
* get_other_blockdevice() */
BlockDevice *_get_blockdevice_other(bd_addr_t start_address, bd_size_t size)
{
bd_addr_t aligned_end_address;
bd_addr_t aligned_start_address;

BlockDevice *bd = get_other_blockdevice();
if (bd == NULL) {
tr_error("KV Config: \"other\" block device init fail");
return NULL;
}

if (bd->init() != MBED_SUCCESS) {
tr_error("KV Config: SDBlockDevice init fail");
return NULL;
}

if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "TDB_EXTERNAL_NO_RBP") == 0 ||
strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "TDB_EXTERNAL") == 0) {
//In TDBStore profile, we have a constraint of 4GByte
if (start_address == 0 && size == 0 && bd->size() < (uint32_t)(-1)) {
return bd;
}

//If the size of external storage is bigger than 4G we need to slice it.
size = size != 0 ? size : align_down(bd->size(), bd->get_erase_size(bd->size() - 1));

if (_get_addresses(bd, start_address, size, &aligned_start_address, &aligned_end_address) != 0) {
tr_error("KV Config: Fail to get addresses for SlicingBlockDevice.");
return NULL;
}

if (aligned_end_address - aligned_start_address != (uint32_t)(aligned_end_address - aligned_start_address)) {
aligned_end_address = aligned_start_address + (uint32_t)(-1);//Support up to 4G only
}
} else {
//For all other KVStore profiles beside TDBStore we take the entire external memory space.
if (start_address == 0 && size == 0) {
return bd;
}

if (_get_addresses(bd, start_address, size, &aligned_start_address, &aligned_end_address) != 0) {
tr_error("KV Config: Fail to get addresses for SlicingBlockDevice.");
return NULL;
}
}

aligned_end_address = align_down(aligned_end_address, bd->get_erase_size(aligned_end_address));
static SlicingBlockDevice sbd(bd, aligned_start_address, aligned_end_address);
return &sbd;
}

MBED_WEAK BlockDevice *get_other_blockdevice()
{
return NULL;
}

int _storage_config_TDB_INTERNAL()
{
#if COMPONENT_FLASHIAP
Expand Down Expand Up @@ -750,17 +825,10 @@ int _storage_config_TDB_EXTERNAL()
return MBED_ERROR_FAILED_OPERATION ;
}

//TDBStore needs a block device base on flash. so if this is SD block device or the default block device is SD
//add FlashSimBlockDevice on top of the SDBlockDevice
#if defined(COMPONENT_SD)
if (strcmp(STR(MBED_CONF_STORAGE_TDB_EXTERNAL_BLOCKDEVICE), "SD") == 0
#if defined(COMPONENT_SD) && !defined(COMPONENT_SPIF) && !defined(COMPONENT_QSPIF) && !defined(COMPONENT_DATAFLASH)
|| strcmp(STR(MBED_CONF_STORAGE_TDB_EXTERNAL_BLOCKDEVICE), "default") == 0) {
#else
) {

#endif
//TDBStore need FlashSimBlockDevice when working with SD block device
//TDBStore needs a block device base on flash. So if this is non-flash type block device,
//add FlashSimBlockDevice on top of it.
if (bd->get_erase_value() == -1) {
//TDBStore needs FlashSimBlockDevice when working with non-flash type block device
if (bd->init() != MBED_SUCCESS) {
tr_error("KV Config: Fail to init external BlockDevice.");
return MBED_ERROR_FAILED_OPERATION ;
Expand All @@ -771,9 +839,6 @@ int _storage_config_TDB_EXTERNAL()
} else {
kvstore_config.external_bd = bd;
}
#else
kvstore_config.external_bd = bd;
#endif

kvstore_config.flags_mask = ~(0);

Expand All @@ -795,17 +860,10 @@ int _storage_config_TDB_EXTERNAL_NO_RBP()
return MBED_ERROR_FAILED_OPERATION ;
}

//TDBStore needs a block device base on flash. so if this is SD block device or the default block device is SD
//TDBStore needs a block device base on flash. So if this is non-flash type block device,
//add FlashSimBlockDevice on top of the SDBlockDevice
#if defined(COMPONENT_SD)
if (strcmp(STR(MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_BLOCKDEVICE), "SD") == 0
#if defined(COMPONENT_SD) && !defined(COMPONENT_SPIF) && !defined(COMPONENT_QSPIF) && !defined(COMPONENT_DATAFLASH)
|| strcmp(STR(MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_BLOCKDEVICE), "default") == 0) {
#else
) {

#endif
//TDBStore need FlashSimBlockDevice when working with SD block device
if (bd->get_erase_value() == -1) {
//TDBStore needs FlashSimBlockDevice when working with non-flash type block device
if (bd->init() != MBED_SUCCESS) {
tr_error("KV Config: Fail to init external BlockDevice.");
return MBED_ERROR_FAILED_OPERATION ;
Expand All @@ -816,9 +874,6 @@ int _storage_config_TDB_EXTERNAL_NO_RBP()
} else {
kvstore_config.external_bd = bd;
}
#else
kvstore_config.external_bd = bd;
#endif

//Masking flag - Actually used to remove any KVStore flag which is not supported
//in the chosen KVStore profile.
Expand Down Expand Up @@ -1069,7 +1124,16 @@ int _storage_config_default()
#elif COMPONENT_FLASHIAP
return _storage_config_TDB_INTERNAL();
#else
return MBED_ERROR_UNSUPPORTED;
BlockDevice *bd = get_other_blockdevice();
if (bd) {
if (bd->get_erase_value() != -1) {
return _storage_config_TDB_EXTERNAL();
} else {
return _storage_config_FILESYSTEM();
}
} else {
return MBED_ERROR_UNSUPPORTED;
}
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion features/storage/kvstore/conf/tdb_external/mbed_lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"value": "0"
},
"blockdevice": {
"help": "Options are default, SPIF, DATAFASH, QSPIF or SD. If default the block device will be chosen by the defined component",
"help": "Options are default, SPIF, DATAFASH, QSPIF, SD or other. If default the block device will be chosen by the defined component. If other, override get_other_blockdevice() to support block device out of Mbed OS tree.",
"value": "default"
},
"external_size": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "storage_tdb_external_no_rbp",
"config": {
"blockdevice": {
"help": "Options are default, SPIF, DATAFASH, QSPIF or SD. If default the block device will be chosen by the defined component",
"help": "Options are default, SPIF, DATAFASH, QSPIF, SD or other. If default the block device will be chosen by the defined component. If other, override get_other_blockdevice() to support block device out of Mbed OS tree.",
"value": "default"
},
"external_size": {
Expand Down