diff --git a/features/storage/kvstore/conf/filesystem/mbed_lib.json b/features/storage/kvstore/conf/filesystem/mbed_lib.json index af9727c721..5afb3ce7aa 100644 --- a/features/storage/kvstore/conf/filesystem/mbed_lib.json +++ b/features/storage/kvstore/conf/filesystem/mbed_lib.json @@ -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": { diff --git a/features/storage/kvstore/conf/filesystem_no_rbp/mbed_lib.json b/features/storage/kvstore/conf/filesystem_no_rbp/mbed_lib.json index 5ecf2841a2..8202a681fd 100644 --- a/features/storage/kvstore/conf/filesystem_no_rbp/mbed_lib.json +++ b/features/storage/kvstore/conf/filesystem_no_rbp/mbed_lib.json @@ -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": { diff --git a/features/storage/kvstore/conf/kv_config.cpp b/features/storage/kvstore/conf/kv_config.cpp index 852e153f22..7105a108ed 100644 --- a/features/storage/kvstore/conf/kv_config.cpp +++ b/features/storage/kvstore/conf/kv_config.cpp @@ -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 } diff --git a/features/storage/kvstore/conf/tdb_external/mbed_lib.json b/features/storage/kvstore/conf/tdb_external/mbed_lib.json index c102776dcb..215cd888eb 100644 --- a/features/storage/kvstore/conf/tdb_external/mbed_lib.json +++ b/features/storage/kvstore/conf/tdb_external/mbed_lib.json @@ -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": { diff --git a/features/storage/kvstore/conf/tdb_external_no_rbp/mbed_lib.json b/features/storage/kvstore/conf/tdb_external_no_rbp/mbed_lib.json index ca617b84a6..0d1204b13a 100644 --- a/features/storage/kvstore/conf/tdb_external_no_rbp/mbed_lib.json +++ b/features/storage/kvstore/conf/tdb_external_no_rbp/mbed_lib.json @@ -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": {