KVStore: Support block device out of mbed-os tree

To support block device out of mbed-os tree in KVStore, user needs to:
1. Configure blockdevice to "other".
2. Override get_other_blockdevice() to provide block device out of mbed-os tree.
pull/10355/head
ccli8 2019-04-08 14:43:50 +08:00
parent 71c84e851f
commit 63d9cde507
5 changed files with 97 additions and 33 deletions

View File

@ -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": {

View File

@ -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": {

View File

@ -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;
@ -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
}
@ -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
@ -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 ;
@ -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);
@ -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 ;
@ -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.
@ -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
}

View File

@ -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": {

View File

@ -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": {