mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #11629 from kyle-cypress/pr/tdb-bounds-refactor
Refactor TDB internal bounds computationpull/12721/head
commit
4c6e59d714
|
|
@ -145,6 +145,7 @@ set(unittest-includes-base
|
|||
"${PROJECT_SOURCE_DIR}/../features/mbedtls"
|
||||
"${PROJECT_SOURCE_DIR}/../features/mbedtls/inc"
|
||||
"${PROJECT_SOURCE_DIR}/../features/mbedtls/mbed-crypto/inc"
|
||||
"${PROJECT_SOURCE_DIR}/../features/storage/kvstore/conf"
|
||||
)
|
||||
|
||||
# Create a list for test suites.
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ int get_virtual_TDBStore_position(uint32_t conf_start_address, uint32_t conf_si
|
|||
uint32_t flash_start_address;
|
||||
uint32_t aligned_start_address;
|
||||
FlashIAP flash;
|
||||
static const int STORE_SECTORS = 2;
|
||||
|
||||
int ret = flash.init();
|
||||
if (ret != 0) {
|
||||
|
|
@ -93,19 +92,11 @@ int get_virtual_TDBStore_position(uint32_t conf_start_address, uint32_t conf_si
|
|||
}
|
||||
}
|
||||
} else {
|
||||
// Assumption is that last two sectors are reserved for the TDBStore
|
||||
aligned_start_address = flash.get_flash_start() + flash.get_flash_size();
|
||||
|
||||
for (int i = STORE_SECTORS; i; i--) {
|
||||
bd_size_t sector_size = flash.get_sector_size(aligned_start_address - 1);
|
||||
aligned_start_address -= sector_size;
|
||||
}
|
||||
|
||||
if (aligned_start_address < flash_first_writable_sector_address) {
|
||||
flash.deinit();
|
||||
return -2;
|
||||
}
|
||||
bd_final_size = (flash_end_address - aligned_start_address);
|
||||
bd_addr_t default_start;
|
||||
bd_size_t default_size;
|
||||
kv_get_default_flash_addresses(&default_start, &default_size);
|
||||
aligned_start_address = (uint32_t)default_start;
|
||||
bd_final_size = (uint32_t)default_size;
|
||||
}
|
||||
|
||||
(*tdb_start_address) = aligned_start_address;
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
"name": "storage_filesystem",
|
||||
"config": {
|
||||
"rbp_internal_size": {
|
||||
"help": "Default is the size of the 2 last sectors of internal flash",
|
||||
"help": "Default is the larger of the last 2 sectors or last 14 pages of flash.",
|
||||
"value": "0"
|
||||
},
|
||||
"internal_base_address": {
|
||||
"help": "If default, base address is the first sector after the application code",
|
||||
"help": "If default, base address is set to internal_size bytes before the end of flash.",
|
||||
"value": "0"
|
||||
},
|
||||
"filesystem": {
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
},
|
||||
"target_overrides": {
|
||||
"MCU_PSOC6": {
|
||||
"rbp_internal_size": 7168
|
||||
"rbp_internal_size": "7168"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,6 +150,12 @@ static const char *filesystemstore_folder_path = NULL;
|
|||
|
||||
using namespace mbed;
|
||||
|
||||
// Use the last 2 sectors or 14 pages of flash for the TDBStore by default (whichever is larger)
|
||||
// For each area: must be a minimum of 1 page of reserved and 2 pages for master record
|
||||
/** Minimum number of internal flash sectors required for TDBStore */
|
||||
static const int STORE_SECTORS = 2;
|
||||
/** Minimum number of internal flash pages required for TDBStore */
|
||||
static const int STORE_PAGES = 14;
|
||||
|
||||
static SingletonPtr<PlatformMutex> mutex;
|
||||
static bool is_kv_config_initialize = false;
|
||||
|
|
@ -180,14 +186,14 @@ int _calculate_blocksize_match_tdbstore(BlockDevice *bd)
|
|||
{
|
||||
bd_size_t size = bd->size();
|
||||
bd_size_t erase_size = bd->get_erase_size();
|
||||
bd_size_t page_size = bd->get_program_size();
|
||||
bd_size_t number_of_sector = size / erase_size;
|
||||
|
||||
if (number_of_sector < 2) {
|
||||
tr_warning("KV Config: There are less than two sectors - TDBStore will not work.");
|
||||
bd_size_t number_of_page = size / page_size;
|
||||
if (number_of_sector < STORE_SECTORS) {
|
||||
tr_error("KV Config: There are less than %d sectors - TDBStore will not work.", STORE_SECTORS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (number_of_sector % 2 != 0) {
|
||||
tr_warning("KV Config: Number of sectors is not an even number. Consider changing the BlockDevice size");
|
||||
}
|
||||
|
|
@ -270,175 +276,17 @@ FileSystem *_get_filesystem_default(const char *mount)
|
|||
#endif
|
||||
}
|
||||
|
||||
//Calculates the start address of FLASHIAP block device for TDB_INTERNAL profile.
|
||||
//Last two sectors to have a predictable location for the TDBStore
|
||||
int _get_flashiap_bd_default_addresses_tdb_internal(bd_addr_t *start_address, bd_size_t *size)
|
||||
{
|
||||
int ret = MBED_SUCCESS;
|
||||
|
||||
#if COMPONENT_FLASHIAP
|
||||
|
||||
FlashIAP flash;
|
||||
static const int STORE_SECTORS = 2;
|
||||
|
||||
if (*start_address || *size) {
|
||||
return MBED_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (flash.init() != 0) {
|
||||
return MBED_ERROR_FAILED_OPERATION;
|
||||
}
|
||||
|
||||
// Lets work from end of the flash backwards
|
||||
bd_addr_t curr_addr = flash.get_flash_start() + flash.get_flash_size();
|
||||
|
||||
for (int i = STORE_SECTORS; i; i--) {
|
||||
bd_size_t sector_size = flash.get_sector_size(curr_addr - 1);
|
||||
curr_addr -= sector_size;
|
||||
}
|
||||
|
||||
// Store- and application-sectors mustn't overlap
|
||||
uint32_t first_wrtbl_sector_addr =
|
||||
(uint32_t)(align_up(FLASHIAP_APP_ROM_END_ADDR, flash.get_sector_size(FLASHIAP_APP_ROM_END_ADDR)));
|
||||
|
||||
MBED_ASSERT(curr_addr >= first_wrtbl_sector_addr);
|
||||
if (curr_addr < first_wrtbl_sector_addr) {
|
||||
ret = MBED_ERROR_MEDIA_FULL;
|
||||
} else {
|
||||
*start_address = curr_addr;
|
||||
}
|
||||
|
||||
flash.deinit();
|
||||
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//Calculates address and size for FLASHIAP block device in TDB_EXTERNAL and FILESYSTEM profiles.
|
||||
//The size of the block device will be 2 sectors at the ends of the internal flash for
|
||||
//the use of the rbp internal TDBStore.
|
||||
int _get_flashiap_bd_default_addresses_rbp(bd_addr_t *start_address, bd_size_t *size)
|
||||
{
|
||||
#if COMPONENT_FLASHIAP
|
||||
|
||||
bd_addr_t flash_end_address;
|
||||
bd_addr_t flash_start_address;
|
||||
bd_addr_t aligned_start_address;
|
||||
bd_addr_t flash_first_writable_sector_address;
|
||||
FlashIAP flash;
|
||||
|
||||
if (*start_address != 0 || *size != 0) {
|
||||
return MBED_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
int ret = flash.init();
|
||||
if (ret != 0) {
|
||||
return MBED_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
flash_first_writable_sector_address = align_up(FLASHIAP_APP_ROM_END_ADDR, flash.get_sector_size(FLASHIAP_APP_ROM_END_ADDR));
|
||||
flash_start_address = flash.get_flash_start();
|
||||
flash_end_address = flash_start_address + flash.get_flash_size();;
|
||||
*start_address = flash_end_address - 1;
|
||||
aligned_start_address = align_down(*start_address, flash.get_sector_size(*start_address));
|
||||
*size = (flash_end_address - aligned_start_address) * 2;
|
||||
*start_address = (flash_end_address - *size);
|
||||
aligned_start_address = align_down(*start_address, flash.get_sector_size(*start_address));
|
||||
|
||||
flash.deinit();
|
||||
|
||||
if (aligned_start_address < flash_first_writable_sector_address) {
|
||||
tr_error("KV Config: Internal block device start address overlapped ROM address ");
|
||||
return MBED_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return MBED_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
BlockDevice *_get_blockdevice_FLASHIAP(bd_addr_t start_address, bd_size_t size)
|
||||
{
|
||||
#if COMPONENT_FLASHIAP
|
||||
|
||||
bd_addr_t flash_end_address;
|
||||
bd_addr_t flash_start_address;
|
||||
bd_addr_t flash_first_writable_sector_address;
|
||||
bd_addr_t aligned_start_address;
|
||||
bd_addr_t aligned_end_address;
|
||||
bd_addr_t end_address;
|
||||
FlashIAP flash;
|
||||
|
||||
int ret = flash.init();
|
||||
int ret = kv_get_flash_bounds_from_config(&start_address, &size);
|
||||
if (ret != 0) {
|
||||
tr_error("KV Config: Determination of internal block device bounds failed. The configured start address/size is likely invalid.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Get flash parameters before starting
|
||||
flash_first_writable_sector_address = align_up(FLASHIAP_APP_ROM_END_ADDR, flash.get_sector_size(FLASHIAP_APP_ROM_END_ADDR));
|
||||
flash_start_address = flash.get_flash_start();
|
||||
flash_end_address = flash_start_address + flash.get_flash_size();;
|
||||
|
||||
//Non default configuration
|
||||
if (start_address != 0) {
|
||||
|
||||
aligned_start_address = align_down(start_address, flash.get_sector_size(start_address));
|
||||
if (start_address != aligned_start_address) {
|
||||
tr_error("KV Config: Internal block device start address is not aligned. Better use %02llx", aligned_start_address);
|
||||
flash.deinit();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
//The block device will have all space from start address to the end of the flash
|
||||
size = (flash_end_address - start_address);
|
||||
|
||||
static FlashIAPBlockDevice bd(start_address, size);
|
||||
flash.deinit();
|
||||
return &bd;
|
||||
}
|
||||
|
||||
if (size != 0) {
|
||||
end_address = start_address + size;
|
||||
if (end_address > flash_end_address) {
|
||||
tr_error("KV Config: Internal block device end address is out of boundaries");
|
||||
flash.deinit();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
aligned_end_address = align_up(end_address, flash.get_sector_size(end_address - 1));
|
||||
if (end_address != aligned_end_address) {
|
||||
tr_error("KV Config: Internal block device start address is not aligned. Consider changing the size parameter");
|
||||
flash.deinit();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static FlashIAPBlockDevice bd(start_address, size);
|
||||
flash.deinit();
|
||||
return &bd;
|
||||
}
|
||||
}
|
||||
|
||||
//Non default configuration start_address = 0
|
||||
start_address = flash_end_address - size;
|
||||
aligned_start_address = align_down(start_address, flash.get_sector_size(start_address));
|
||||
if (start_address != aligned_start_address) {
|
||||
tr_error("KV Config: Internal block device start address is not aligned. Consider changing the size parameter");
|
||||
flash.deinit();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
flash.deinit();
|
||||
|
||||
if (aligned_start_address < flash_first_writable_sector_address) {
|
||||
tr_error("KV Config: Internal block device start address overlapped ROM address ");
|
||||
return NULL;
|
||||
}
|
||||
static FlashIAPBlockDevice bd(aligned_start_address, size);
|
||||
static FlashIAPBlockDevice bd(start_address, size);
|
||||
return &bd;
|
||||
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
|
|
@ -474,6 +322,9 @@ BlockDevice *_get_blockdevice_SPIF(bd_addr_t start_address, bd_size_t size)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
start_address = aligned_start_address;
|
||||
size = aligned_end_address - aligned_start_address;
|
||||
|
||||
static SlicingBlockDevice sbd(&bd, aligned_start_address, aligned_end_address);
|
||||
return &sbd;
|
||||
|
||||
|
|
@ -515,6 +366,9 @@ BlockDevice *_get_blockdevice_QSPIF(bd_addr_t start_address, bd_size_t size)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
start_address = aligned_start_address;
|
||||
size = aligned_end_address - aligned_start_address;
|
||||
|
||||
static SlicingBlockDevice sbd(&bd, aligned_start_address, aligned_end_address);
|
||||
return &sbd;
|
||||
|
||||
|
|
@ -552,6 +406,9 @@ BlockDevice *_get_blockdevice_DATAFLASH(bd_addr_t start_address, bd_size_t size)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
start_address = aligned_start_address;
|
||||
size = aligned_end_address - aligned_start_address;
|
||||
|
||||
static SlicingBlockDevice sbd(&bd, aligned_start_address, aligned_end_address);
|
||||
return &sbd;
|
||||
|
||||
|
|
@ -618,6 +475,10 @@ BlockDevice *_get_blockdevice_SD(bd_addr_t start_address, bd_size_t size)
|
|||
}
|
||||
|
||||
aligned_end_address = align_down(aligned_end_address, bd.get_erase_size(aligned_end_address));
|
||||
|
||||
start_address = aligned_start_address;
|
||||
size = aligned_end_address - aligned_start_address;
|
||||
|
||||
static SlicingBlockDevice sbd(&bd, aligned_start_address, aligned_end_address);
|
||||
return &sbd;
|
||||
|
||||
|
|
@ -691,6 +552,10 @@ BlockDevice *_get_blockdevice_other(bd_addr_t start_address, bd_size_t size)
|
|||
}
|
||||
|
||||
aligned_end_address = align_down(aligned_end_address, bd->get_erase_size(aligned_end_address));
|
||||
|
||||
start_address = aligned_start_address;
|
||||
size = aligned_end_address - aligned_start_address;
|
||||
|
||||
static SlicingBlockDevice sbd(bd, aligned_start_address, aligned_end_address);
|
||||
return &sbd;
|
||||
}
|
||||
|
|
@ -700,57 +565,71 @@ MBED_WEAK BlockDevice *get_other_blockdevice()
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int _storage_config_TDB_INTERNAL()
|
||||
int _create_internal_tdb(BlockDevice **internal_bd, KVStore **internal_tdb, bd_size_t size, bd_addr_t start_address)
|
||||
{
|
||||
#if COMPONENT_FLASHIAP
|
||||
bd_size_t internal_size = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_SIZE;
|
||||
bd_addr_t internal_start_address = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_BASE_ADDRESS;
|
||||
int ret;
|
||||
|
||||
if (internal_size == 0 && internal_start_address == 0) {
|
||||
//Get the default address and size for the TDBStore
|
||||
if (size == 0 && start_address == 0) {
|
||||
//Calculate the block device size and start address in case default values are used.
|
||||
ret = _get_flashiap_bd_default_addresses_tdb_internal(&internal_start_address, &internal_size);
|
||||
ret = kv_get_default_flash_addresses(&start_address, &size);
|
||||
if (ret != MBED_SUCCESS) {
|
||||
return ret;
|
||||
return MBED_ERROR_FAILED_OPERATION;
|
||||
}
|
||||
}
|
||||
|
||||
//Get internal memory FLASHIAP block device.
|
||||
kvstore_config.internal_bd = GET_BLOCKDEVICE(INTERNAL_BLOCKDEVICE_NAME, internal_start_address, internal_size);
|
||||
if (kvstore_config.internal_bd == NULL) {
|
||||
//Create internal FLASHIAP block device
|
||||
*internal_bd = GET_BLOCKDEVICE(INTERNAL_BLOCKDEVICE_NAME, start_address, size);
|
||||
if (*internal_bd == NULL) {
|
||||
tr_error("KV Config: Fail to get internal BlockDevice.");
|
||||
return MBED_ERROR_FAILED_OPERATION;
|
||||
return MBED_ERROR_FAILED_OPERATION ;
|
||||
}
|
||||
|
||||
|
||||
ret = kvstore_config.internal_bd->init();
|
||||
// Initialize internal block device
|
||||
ret = (*internal_bd)->init();
|
||||
if (ret != MBED_SUCCESS) {
|
||||
tr_error("KV Config: Fail to init internal BlockDevice.");
|
||||
return MBED_ERROR_FAILED_OPERATION;
|
||||
return MBED_ERROR_FAILED_OPERATION ;
|
||||
}
|
||||
|
||||
//Check that internal flash has 2 or more sectors
|
||||
if (_calculate_blocksize_match_tdbstore(kvstore_config.internal_bd) != MBED_SUCCESS) {
|
||||
tr_error("KV Config: Can not create TDBStore with less then 2 sector.");
|
||||
//Check if TDBStore has at least 2 sectors or 14 pages.
|
||||
if (_calculate_blocksize_match_tdbstore(*internal_bd) != MBED_SUCCESS) {
|
||||
tr_error("KV Config: Can not create TDBStore with less then %d sectors.", STORE_SECTORS);
|
||||
return MBED_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
//Deinitialize internal block device and TDB will reinitialize and take control on it.
|
||||
ret = kvstore_config.internal_bd->deinit();
|
||||
//Deinitialize internal block device and TDB will reinitialize and take control of it.
|
||||
ret = (*internal_bd)->deinit();
|
||||
if (ret != MBED_SUCCESS) {
|
||||
tr_error("KV Config: Fail to deinit internal BlockDevice.");
|
||||
return MBED_ERROR_FAILED_OPERATION;
|
||||
}
|
||||
|
||||
//Create a TDBStore in the internal FLASHIAP block device.
|
||||
static TDBStore tdb_internal(kvstore_config.internal_bd);
|
||||
kvstore_config.internal_store = &tdb_internal;
|
||||
//Create internal TDBStore
|
||||
static TDBStore tdb_internal(*internal_bd);
|
||||
*internal_tdb = &tdb_internal;
|
||||
|
||||
ret = kvstore_config.internal_store->init();
|
||||
ret = (*internal_tdb)->init();
|
||||
if (ret != MBED_SUCCESS) {
|
||||
tr_error("KV Config: Fail to init internal TDBStore.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return MBED_SUCCESS;
|
||||
}
|
||||
|
||||
int _storage_config_TDB_INTERNAL()
|
||||
{
|
||||
#if COMPONENT_FLASHIAP
|
||||
bd_size_t internal_size = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_SIZE;
|
||||
bd_addr_t internal_start_address = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_BASE_ADDRESS;
|
||||
|
||||
int ret = _create_internal_tdb(&kvstore_config.internal_bd, &kvstore_config.internal_store, internal_size, internal_start_address);
|
||||
if (MBED_SUCCESS != ret) {
|
||||
tr_error("KV Config: Fail to create internal TDBStore");
|
||||
return ret;
|
||||
}
|
||||
|
||||
kvstore_config.kvstore_main_instance =
|
||||
kvstore_config.internal_store;
|
||||
|
||||
|
|
@ -790,40 +669,9 @@ int _storage_config_TDB_EXTERNAL()
|
|||
bd_size_t internal_rbp_size = MBED_CONF_STORAGE_TDB_EXTERNAL_RBP_INTERNAL_SIZE;
|
||||
bd_addr_t internal_start_address = MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS;
|
||||
|
||||
//Get the default address and size for internal rbp TDBStore
|
||||
if (internal_rbp_size == 0 && internal_start_address == 0) {
|
||||
//Calculate the block device size and start address in case default values are used.
|
||||
if (_get_flashiap_bd_default_addresses_rbp(&internal_start_address, &internal_rbp_size) != MBED_SUCCESS) {
|
||||
return MBED_ERROR_FAILED_OPERATION;
|
||||
}
|
||||
}
|
||||
|
||||
//Create internal FLASHIAP block device
|
||||
kvstore_config.internal_bd = GET_BLOCKDEVICE(INTERNAL_BLOCKDEVICE_NAME, internal_start_address, internal_rbp_size);
|
||||
if (kvstore_config.internal_bd == NULL) {
|
||||
tr_error("KV Config: Fail to get internal BlockDevice.");
|
||||
return MBED_ERROR_FAILED_OPERATION ;
|
||||
}
|
||||
|
||||
int ret = kvstore_config.internal_bd->init();
|
||||
if (ret != MBED_SUCCESS) {
|
||||
tr_error("KV Config: Fail to init internal BlockDevice.");
|
||||
return MBED_ERROR_FAILED_OPERATION ;
|
||||
}
|
||||
|
||||
//Check if TDBStore has at least 2 sector.
|
||||
if (_calculate_blocksize_match_tdbstore(kvstore_config.internal_bd) != MBED_SUCCESS) {
|
||||
tr_error("KV Config: Can not create TDBStore with less then 2 sector.");
|
||||
return MBED_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
//Create internal TDBStore
|
||||
static TDBStore tdb_internal(kvstore_config.internal_bd);
|
||||
kvstore_config.internal_store = &tdb_internal;
|
||||
|
||||
ret = kvstore_config.internal_store->init();
|
||||
if (ret != MBED_SUCCESS) {
|
||||
tr_error("KV Config: Fail to init internal TDBStore.");
|
||||
int ret = _create_internal_tdb(&kvstore_config.internal_bd, &kvstore_config.internal_store, internal_rbp_size, internal_start_address);
|
||||
if (MBED_SUCCESS != ret) {
|
||||
tr_error("KV Config: Fail to create internal TDBStore");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -912,9 +760,9 @@ int _storage_config_tdb_external_common()
|
|||
return MBED_ERROR_FAILED_OPERATION ;
|
||||
}
|
||||
|
||||
//Check that there is at least 2 sector for the external TDBStore
|
||||
//Check that there is at least 2 sectors or 14 pages for the external TDBStore
|
||||
if (_calculate_blocksize_match_tdbstore(kvstore_config.external_bd) != MBED_SUCCESS) {
|
||||
tr_error("KV Config: Can not create TDBStore with less then 2 sector.");
|
||||
tr_error("KV Config: Can not create TDBStore with less then 2 sectors or 14 pages.");
|
||||
return MBED_ERROR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
|
|
@ -965,47 +813,9 @@ int _storage_config_FILESYSTEM()
|
|||
bd_size_t internal_rbp_size = MBED_CONF_STORAGE_FILESYSTEM_RBP_INTERNAL_SIZE;
|
||||
bd_addr_t internal_start_address = MBED_CONF_STORAGE_FILESYSTEM_INTERNAL_BASE_ADDRESS;
|
||||
|
||||
//Get the default address and size for internal rbp TDBStore
|
||||
if (internal_rbp_size == 0 && internal_start_address == 0) {
|
||||
//Calculate the block device size and start address in case default values are used.
|
||||
if (_get_flashiap_bd_default_addresses_rbp(&internal_start_address, &internal_rbp_size) != MBED_SUCCESS) {
|
||||
return MBED_ERROR_FAILED_OPERATION;
|
||||
}
|
||||
}
|
||||
|
||||
//Get internal FLASHIAP block device
|
||||
kvstore_config.internal_bd = GET_BLOCKDEVICE(INTERNAL_BLOCKDEVICE_NAME, internal_start_address, internal_rbp_size);
|
||||
if (kvstore_config.internal_bd == NULL) {
|
||||
tr_error("KV Config: Fail to get internal BlockDevice ");
|
||||
return MBED_ERROR_FAILED_OPERATION ;
|
||||
}
|
||||
|
||||
int ret = kvstore_config.internal_bd->init();
|
||||
if (ret != MBED_SUCCESS) {
|
||||
tr_error("KV Config: Fail to init internal BlockDevice ");
|
||||
return MBED_ERROR_FAILED_OPERATION ;
|
||||
}
|
||||
|
||||
//Check that internal flash has 2 or more sectors
|
||||
if (_calculate_blocksize_match_tdbstore(kvstore_config.internal_bd) != MBED_SUCCESS) {
|
||||
tr_error("KV Config: Can not create TDBStore with less then 2 sector.");
|
||||
return MBED_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
//Deinitialize internal block device and TDB will reinitialize and take control on it.
|
||||
ret = kvstore_config.internal_bd->deinit();
|
||||
if (ret != MBED_SUCCESS) {
|
||||
tr_error("KV Config: Fail to deinit internal BlockDevice.");
|
||||
return MBED_ERROR_FAILED_OPERATION;
|
||||
}
|
||||
|
||||
//Create internal TDBStore for rbp
|
||||
static TDBStore tdb_internal(kvstore_config.internal_bd);
|
||||
kvstore_config.internal_store = &tdb_internal;
|
||||
|
||||
ret = kvstore_config.internal_store->init();
|
||||
if (ret != MBED_SUCCESS) {
|
||||
tr_error("KV Config: Fail to init internal TDBStore");
|
||||
int ret = _create_internal_tdb(&kvstore_config.internal_bd, &kvstore_config.internal_store, internal_rbp_size, internal_start_address);
|
||||
if (MBED_SUCCESS != ret) {
|
||||
tr_error("KV Config: Fail to create internal TDBStore");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1181,3 +991,131 @@ exit:
|
|||
mutex->unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kv_get_default_flash_addresses(bd_addr_t *start_address, bd_size_t *size)
|
||||
{
|
||||
int ret = MBED_SUCCESS;
|
||||
|
||||
#if COMPONENT_FLASHIAP
|
||||
FlashIAP flash;
|
||||
if (flash.init() != 0) {
|
||||
return MBED_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
// Let's work from end of the flash backwards
|
||||
bd_addr_t end_of_flash = flash.get_flash_start() + flash.get_flash_size();
|
||||
bd_addr_t curr_addr = end_of_flash;
|
||||
bd_size_t sector_space = 0;
|
||||
|
||||
for (int i = STORE_SECTORS; i; i--) {
|
||||
bd_size_t sector_size = flash.get_sector_size(curr_addr - 1);
|
||||
sector_space += sector_size;
|
||||
}
|
||||
|
||||
bd_size_t page_space = flash.get_page_size() * STORE_PAGES;
|
||||
if (sector_space > page_space) {
|
||||
curr_addr -= sector_space;
|
||||
*size = sector_space;
|
||||
} else {
|
||||
curr_addr -= page_space;
|
||||
// Align to 2 sector boundary so that garbage collection works properly
|
||||
curr_addr = align_down(curr_addr, 2 * flash.get_sector_size(curr_addr));
|
||||
*size = end_of_flash - curr_addr;
|
||||
}
|
||||
|
||||
// Store- and application-sectors mustn't overlap
|
||||
uint32_t first_wrtbl_sector_addr =
|
||||
(uint32_t)(align_up(FLASHIAP_APP_ROM_END_ADDR, flash.get_sector_size(FLASHIAP_APP_ROM_END_ADDR)));
|
||||
|
||||
MBED_ASSERT(curr_addr >= first_wrtbl_sector_addr);
|
||||
if (curr_addr < first_wrtbl_sector_addr) {
|
||||
ret = MBED_ERROR_MEDIA_FULL;
|
||||
} else {
|
||||
*start_address = curr_addr;
|
||||
}
|
||||
|
||||
flash.deinit();
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kv_get_flash_bounds_from_config(bd_addr_t *start_address, bd_size_t *size)
|
||||
{
|
||||
#if COMPONENT_FLASHIAP
|
||||
|
||||
bd_addr_t flash_end_address;
|
||||
bd_addr_t flash_start_address;
|
||||
bd_addr_t flash_first_writable_sector_address;
|
||||
bd_addr_t aligned_start_address;
|
||||
bd_addr_t aligned_end_address;
|
||||
bd_addr_t end_address;
|
||||
FlashIAP flash;
|
||||
|
||||
if (!start_address || !size) {
|
||||
return MBED_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
int ret = flash.init();
|
||||
if (ret != 0) {
|
||||
return MBED_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
// Get flash parameters
|
||||
flash_first_writable_sector_address = align_up(FLASHIAP_APP_ROM_END_ADDR, flash.get_sector_size(FLASHIAP_APP_ROM_END_ADDR));
|
||||
flash_start_address = flash.get_flash_start();
|
||||
flash_end_address = flash_start_address + flash.get_flash_size();
|
||||
|
||||
if (*start_address == 0) {
|
||||
if (*size == 0) {
|
||||
//The block device will have all space from start address to the end of the flash
|
||||
*size = flash.get_flash_size();
|
||||
}
|
||||
|
||||
*start_address = flash_end_address - *size;
|
||||
aligned_start_address = align_down(*start_address, flash.get_sector_size(*start_address));
|
||||
if (*start_address != aligned_start_address) {
|
||||
// Start address not aligned - size should likely be changed so that it is
|
||||
flash.deinit();
|
||||
return MBED_ERROR_INVALID_SIZE;
|
||||
}
|
||||
} else {
|
||||
aligned_start_address = align_down(*start_address, flash.get_sector_size(*start_address));
|
||||
if (*start_address != aligned_start_address) {
|
||||
// Start address not aligned - size should likely be changed so that it is
|
||||
flash.deinit();
|
||||
return MBED_ERROR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
if (*size == 0) {
|
||||
//The block device will have all space from start address to the end of the flash
|
||||
*size = (flash_end_address - *start_address);
|
||||
} else {
|
||||
// Do checks on end address to make sure configured start address/size are good
|
||||
|
||||
end_address = *start_address + *size;
|
||||
if (end_address > flash_end_address) {
|
||||
// End address is out of flash bounds
|
||||
flash.deinit();
|
||||
return MBED_ERROR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
aligned_end_address = align_up(end_address, flash.get_sector_size(end_address - 1));
|
||||
if (end_address != aligned_end_address) {
|
||||
// End address not aligned - size should likely be changed so that it is
|
||||
flash.deinit();
|
||||
return MBED_ERROR_INVALID_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flash.deinit();
|
||||
|
||||
if (*start_address < flash_first_writable_sector_address) {
|
||||
// Calculated start address overlaps with ROM
|
||||
return MBED_ERROR_MEDIA_FULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return MBED_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
#ifndef _KV_CONFIG
|
||||
#define _KV_CONFIG
|
||||
|
||||
#include "features/storage/blockdevice/BlockDevice.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
@ -42,6 +44,32 @@ int kv_init_storage_config();
|
|||
*/
|
||||
const char *get_filesystemstore_folder_path();
|
||||
|
||||
/**
|
||||
* @brief Get the default TDBStore flash start address and size.
|
||||
*
|
||||
* @param[out] start_address Default TDBStore start address in flash.
|
||||
* @param[out] size Default TDBStore size.
|
||||
*
|
||||
* @returns MBED_SUCCESS Success.
|
||||
* MBED_ERROR_INITIALIZATION_FAILED Failed to initialize flash driver.
|
||||
* MBED_ERROR_MEDIA_FULL Default TDBStore space overlaps with program memory.
|
||||
*/
|
||||
int kv_get_default_flash_addresses(mbed::bd_addr_t *start_address, mbed::bd_size_t *size);
|
||||
|
||||
/**
|
||||
* @brief Get the TDBStore flash bounds from the configured start address and size.
|
||||
*
|
||||
* @param[inout] start_address Configured TDBStore start address in flash.
|
||||
* @param[inout] size Configured TDBStore size. If 0, the size will be from the start address to the end of flash
|
||||
*
|
||||
* @returns MBED_SUCCESS Success.
|
||||
* MBED_ERROR_INVALID_ARGUMENT One of the arguments is NULL or both the configured start address and size are 0.
|
||||
* MBED_ERROR_INITIALIZATION_FAILED Failed to initialize flash driver.
|
||||
* MBED_ERROR_INVALID_SIZE Configured size results in misaligned start/end address or end address past the end of flash.
|
||||
* MBED_ERROR_MEDIA_FULL Configured start address/size results in bounds overlapping with program memory.
|
||||
*/
|
||||
int kv_get_flash_bounds_from_config(mbed::bd_addr_t *start_address, mbed::bd_size_t *size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // closing brace for extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
"name": "storage_tdb_external",
|
||||
"config": {
|
||||
"rbp_internal_size": {
|
||||
"help": "Default is the size of the 2 last sectors of internal flash",
|
||||
"help": "Default is the larger of the last 2 sectors or last 14 pages of flash.",
|
||||
"value": "0"
|
||||
},
|
||||
"internal_base_address": {
|
||||
"help": "If default, the base address is set to the first sector after the application code ends.",
|
||||
"help": "If default, the base address is set to internal_size bytes before the end of flash.",
|
||||
"value": "0"
|
||||
},
|
||||
"blockdevice": {
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
"name": "storage_tdb_internal",
|
||||
"config": {
|
||||
"internal_size": {
|
||||
"help": "Size of the FlashIAP block device. default size will be from internal_base_address till the end of the internal flash.",
|
||||
"help": "Size of the FlashIAP block device. Default size will be the larger of the last 2 sectors or last 14 pages of flash.",
|
||||
"value": "0"
|
||||
},
|
||||
"internal_base_address": {
|
||||
"help": "If default, the base address is set to the first sector after the application code ends.",
|
||||
"help": "If default, the base address is set to internal_size bytes before the end of flash.",
|
||||
"value": "0"
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "mbed_error.h"
|
||||
#include "MbedCRC.h"
|
||||
#include "mbed_trace.h"
|
||||
#include "kv_config.h"
|
||||
#define TRACE_GROUP "DADK"
|
||||
|
||||
using namespace mbed;
|
||||
|
|
@ -82,7 +83,7 @@ int direct_access_to_devicekey(uint32_t tdb_start_offset, uint32_t tdb_end_offse
|
|||
|
||||
status = calc_area_params(&flash, tdb_start_offset, tdb_end_offset, area_params);
|
||||
if (status != MBED_SUCCESS) {
|
||||
tr_error("Couldn't calulate Area Params - err: %d", status);
|
||||
tr_error("Couldn't calculate Area Params - err: %d", status);
|
||||
goto exit_point;
|
||||
}
|
||||
|
||||
|
|
@ -108,21 +109,17 @@ exit_point:
|
|||
return status;
|
||||
}
|
||||
|
||||
int get_expected_internal_TDBStore_position(uint32_t *out_tdb_start_offset, uint32_t *out_tdb_end_offset)
|
||||
int get_expected_internal_TDBStore_position(uint32_t *out_tdb_start_offset, uint32_t *out_tdb_end_offset)
|
||||
{
|
||||
uint32_t flash_end_address;
|
||||
uint32_t flash_start_address;
|
||||
uint32_t aligned_start_address;
|
||||
uint32_t aligned_end_address;
|
||||
bd_addr_t tdb_start_address;
|
||||
bd_size_t tdb_size;
|
||||
FlashIAP flash;
|
||||
bool is_default_configuration = false;
|
||||
uint32_t tdb_size;
|
||||
|
||||
if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "FILESYSTEM") == 0) {
|
||||
#ifndef MBED_CONF_STORAGE_FILESYSTEM_INTERNAL_BASE_ADDRESS
|
||||
return MBED_ERROR_ITEM_NOT_FOUND;
|
||||
#else
|
||||
*out_tdb_start_offset = MBED_CONF_STORAGE_FILESYSTEM_INTERNAL_BASE_ADDRESS;
|
||||
tdb_start_address = MBED_CONF_STORAGE_FILESYSTEM_INTERNAL_BASE_ADDRESS;
|
||||
tdb_size = MBED_CONF_STORAGE_FILESYSTEM_RBP_INTERNAL_SIZE;
|
||||
#endif
|
||||
|
||||
|
|
@ -130,7 +127,7 @@ int get_expected_internal_TDBStore_position(uint32_t *out_tdb_start_offset, uin
|
|||
#ifndef MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS
|
||||
return MBED_ERROR_ITEM_NOT_FOUND;
|
||||
#else
|
||||
*out_tdb_start_offset = MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS;
|
||||
tdb_start_address = MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS;
|
||||
tdb_size = MBED_CONF_STORAGE_TDB_EXTERNAL_RBP_INTERNAL_SIZE;
|
||||
#endif
|
||||
|
||||
|
|
@ -139,52 +136,28 @@ int get_expected_internal_TDBStore_position(uint32_t *out_tdb_start_offset, uin
|
|||
#ifndef MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_BASE_ADDRESS
|
||||
return MBED_ERROR_ITEM_NOT_FOUND;
|
||||
#else
|
||||
*out_tdb_start_offset = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_BASE_ADDRESS;
|
||||
tdb_start_address = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_BASE_ADDRESS;
|
||||
tdb_size = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_SIZE;
|
||||
#endif
|
||||
} else {
|
||||
return MBED_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
*out_tdb_end_offset = (*out_tdb_start_offset) + tdb_size;
|
||||
|
||||
if ((*out_tdb_start_offset == 0) && (tdb_size == 0)) {
|
||||
is_default_configuration = true;
|
||||
} else if ((*out_tdb_start_offset == 0) || (tdb_size == 0)) {
|
||||
return MBED_ERROR_UNSUPPORTED;
|
||||
int ret;
|
||||
if ((tdb_start_address == 0) && (tdb_size == 0)) {
|
||||
ret = kv_get_default_flash_addresses(&tdb_start_address, &tdb_size);
|
||||
if (ret != MBED_SUCCESS) {
|
||||
return MBED_ERROR_FAILED_OPERATION;
|
||||
}
|
||||
}
|
||||
|
||||
int ret = flash.init();
|
||||
if (ret != 0) {
|
||||
ret = kv_get_flash_bounds_from_config(&tdb_start_address, &tdb_size);
|
||||
if (ret != MBED_SUCCESS) {
|
||||
return MBED_ERROR_FAILED_OPERATION;
|
||||
}
|
||||
|
||||
uint32_t flash_first_writable_sector_address = (uint32_t)(align_up(FLASHIAP_APP_ROM_END_ADDR,
|
||||
flash.get_sector_size(FLASHIAP_APP_ROM_END_ADDR)));
|
||||
|
||||
//Get flash parameters before starting
|
||||
flash_start_address = flash.get_flash_start();
|
||||
flash_end_address = flash_start_address + flash.get_flash_size();
|
||||
|
||||
if (!is_default_configuration) {
|
||||
aligned_start_address = align_down(*out_tdb_start_offset, flash.get_sector_size(*out_tdb_start_offset));
|
||||
aligned_end_address = align_up(*out_tdb_end_offset, flash.get_sector_size(*out_tdb_end_offset - 1));
|
||||
if ((*out_tdb_start_offset != aligned_start_address) || (*out_tdb_end_offset != aligned_end_address)
|
||||
|| (*out_tdb_end_offset > flash_end_address)) {
|
||||
flash.deinit();
|
||||
return MBED_ERROR_INVALID_OPERATION;
|
||||
}
|
||||
} else {
|
||||
aligned_start_address = flash_end_address - (flash.get_sector_size(flash_end_address - 1) * 2);
|
||||
if (aligned_start_address < flash_first_writable_sector_address) {
|
||||
flash.deinit();
|
||||
return MBED_ERROR_INVALID_OPERATION;
|
||||
}
|
||||
*out_tdb_start_offset = aligned_start_address;
|
||||
*out_tdb_end_offset = flash_end_address;
|
||||
}
|
||||
|
||||
flash.deinit();
|
||||
*out_tdb_start_offset = tdb_start_address;
|
||||
*out_tdb_end_offset = tdb_start_address + tdb_size;
|
||||
|
||||
return MBED_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "mbed_assert.h"
|
||||
#include "mbed_wait_api.h"
|
||||
#include "MbedCRC.h"
|
||||
#include "FlashIAP.h"
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
|
|
@ -110,6 +111,11 @@ static inline uint32_t align_up(uint32_t val, uint32_t size)
|
|||
return (((val - 1) / size) + 1) * size;
|
||||
}
|
||||
|
||||
static inline uint32_t align_down(uint64_t val, uint64_t size)
|
||||
{
|
||||
return (((val) / size)) * size;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t calc_crc(uint32_t init_crc, uint32_t data_size, const void *data_buf)
|
||||
{
|
||||
|
|
@ -1422,7 +1428,6 @@ int TDBStore::reserved_data_get(void *reserved_data, size_t reserved_data_buf_si
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void TDBStore::offset_in_erase_unit(uint8_t area, uint32_t offset,
|
||||
uint32_t &offset_from_start, uint32_t &dist_to_end)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue