Skip to content

Commit 7f18a6c

Browse files
author
Kyle Kearney
committed
Move flash bounds helpers from TDBStore to kv_config
1 parent 926423c commit 7f18a6c

File tree

6 files changed

+173
-172
lines changed

6 files changed

+173
-172
lines changed

features/storage/TESTS/kvstore/direct_access_devicekey_test/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ int get_virtual_TDBStore_position(uint32_t conf_start_address, uint32_t conf_si
9494
} else {
9595
bd_addr_t default_start;
9696
bd_size_t default_size;
97-
TDBStore::get_default_flash_addresses(&default_start, &default_size);
97+
kv_get_default_flash_addresses(&default_start, &default_size);
9898
aligned_start_address = (uint32_t)default_start;
9999
bd_final_size = (uint32_t)default_size;
100100
}

features/storage/kvstore/conf/kv_config.cpp

Lines changed: 141 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ static const char *filesystemstore_folder_path = NULL;
150150

151151
using namespace mbed;
152152

153+
// Use the last 2 sectors or 14 pages of flash for the TDBStore by default (whichever is larger)
154+
// For each area: must be a minimum of 1 page of reserved and 2 pages for master record
155+
/** Minimum number of internal flash sectors required for TDBStore */
156+
static const int STORE_SECTORS = 2;
157+
/** Minimum number of internal flash pages required for TDBStore */
158+
static const int STORE_PAGES = 14;
153159

154160
static SingletonPtr<PlatformMutex> mutex;
155161
static bool is_kv_config_initialize = false;
@@ -183,13 +189,13 @@ int _calculate_blocksize_match_tdbstore(BlockDevice *bd)
183189
bd_size_t page_size = bd->get_program_size();
184190
bd_size_t number_of_sector = size / erase_size;
185191
bd_size_t number_of_page = size / page_size;
186-
if (number_of_sector < TDBStore::STORE_SECTORS) {
187-
tr_error("KV Config: There are less than %d sectors - TDBStore will not work.", TDBStore::STORE_SECTORS);
192+
if (number_of_sector < STORE_SECTORS) {
193+
tr_error("KV Config: There are less than %d sectors - TDBStore will not work.", STORE_SECTORS);
188194
return -1;
189195
}
190196

191-
if (number_of_page < TDBStore::STORE_PAGES) {
192-
tr_error("KV Config: There are less than %d pages - TDBStore will not work.", TDBStore::STORE_PAGES);
197+
if (number_of_page < STORE_PAGES) {
198+
tr_error("KV Config: There are less than %d pages - TDBStore will not work.", STORE_PAGES);
193199
return -1;
194200
}
195201

@@ -279,7 +285,7 @@ FileSystem *_get_filesystem_default(const char *mount)
279285
BlockDevice *_get_blockdevice_FLASHIAP(bd_addr_t start_address, bd_size_t size)
280286
{
281287
#if COMPONENT_FLASHIAP
282-
int ret = TDBStore::get_flash_bounds_from_config(&start_address, &size);
288+
int ret = kv_get_flash_bounds_from_config(&start_address, &size);
283289
if (ret != 0) {
284290
tr_error("KV Config: Determination of internal block device bounds failed. The configured start address/size is likely invalid.");
285291
return NULL;
@@ -572,7 +578,7 @@ int _create_internal_tdb(BlockDevice **internal_bd, KVStore **internal_tdb, bd_s
572578
//Get the default address and size for the TDBStore
573579
if (size == 0 && start_address == 0) {
574580
//Calculate the block device size and start address in case default values are used.
575-
ret = TDBStore::get_default_flash_addresses(&start_address, &size);
581+
ret = kv_get_default_flash_addresses(&start_address, &size);
576582
if (ret != MBED_SUCCESS) {
577583
return MBED_ERROR_FAILED_OPERATION;
578584
}
@@ -594,7 +600,7 @@ int _create_internal_tdb(BlockDevice **internal_bd, KVStore **internal_tdb, bd_s
594600

595601
//Check if TDBStore has at least 2 sectors or 14 pages.
596602
if (_calculate_blocksize_match_tdbstore(*internal_bd) != MBED_SUCCESS) {
597-
tr_error("KV Config: Can not create TDBStore with less then %d sectors or %d pages.", TDBStore::STORE_SECTORS, TDBStore::STORE_PAGES);
603+
tr_error("KV Config: Can not create TDBStore with less then %d sectors or %d pages.", STORE_SECTORS, STORE_PAGES);
598604
return MBED_ERROR_INVALID_ARGUMENT;
599605
}
600606

@@ -991,3 +997,131 @@ MBED_WEAK int kv_init_storage_config()
991997
mutex->unlock();
992998
return ret;
993999
}
1000+
1001+
int kv_get_default_flash_addresses(bd_addr_t *start_address, bd_size_t *size)
1002+
{
1003+
int ret = MBED_SUCCESS;
1004+
1005+
#if COMPONENT_FLASHIAP
1006+
FlashIAP flash;
1007+
if (flash.init() != 0) {
1008+
return MBED_ERROR_INITIALIZATION_FAILED;
1009+
}
1010+
1011+
// Let's work from end of the flash backwards
1012+
bd_addr_t end_of_flash = flash.get_flash_start() + flash.get_flash_size();
1013+
bd_addr_t curr_addr = end_of_flash;
1014+
bd_size_t sector_space = 0;
1015+
1016+
for (int i = STORE_SECTORS; i; i--) {
1017+
bd_size_t sector_size = flash.get_sector_size(curr_addr - 1);
1018+
sector_space += sector_size;
1019+
}
1020+
1021+
bd_size_t page_space = flash.get_page_size() * STORE_PAGES;
1022+
if (sector_space > page_space) {
1023+
curr_addr -= sector_space;
1024+
*size = sector_space;
1025+
} else {
1026+
curr_addr -= page_space;
1027+
// Align to 2 sector boundary so that garbage collection works properly
1028+
curr_addr = align_down(curr_addr, 2 * flash.get_sector_size(curr_addr));
1029+
*size = end_of_flash - curr_addr;
1030+
}
1031+
1032+
// Store- and application-sectors mustn't overlap
1033+
uint32_t first_wrtbl_sector_addr =
1034+
(uint32_t)(align_up(FLASHIAP_APP_ROM_END_ADDR, flash.get_sector_size(FLASHIAP_APP_ROM_END_ADDR)));
1035+
1036+
MBED_ASSERT(curr_addr >= first_wrtbl_sector_addr);
1037+
if (curr_addr < first_wrtbl_sector_addr) {
1038+
ret = MBED_ERROR_MEDIA_FULL;
1039+
} else {
1040+
*start_address = curr_addr;
1041+
}
1042+
1043+
flash.deinit();
1044+
#endif
1045+
1046+
return ret;
1047+
}
1048+
1049+
int kv_get_flash_bounds_from_config(bd_addr_t *start_address, bd_size_t *size)
1050+
{
1051+
#if COMPONENT_FLASHIAP
1052+
1053+
bd_addr_t flash_end_address;
1054+
bd_addr_t flash_start_address;
1055+
bd_addr_t flash_first_writable_sector_address;
1056+
bd_addr_t aligned_start_address;
1057+
bd_addr_t aligned_end_address;
1058+
bd_addr_t end_address;
1059+
FlashIAP flash;
1060+
1061+
if (!start_address || !size) {
1062+
return MBED_ERROR_INVALID_ARGUMENT;
1063+
}
1064+
1065+
int ret = flash.init();
1066+
if (ret != 0) {
1067+
return MBED_ERROR_INITIALIZATION_FAILED;
1068+
}
1069+
1070+
// Get flash parameters
1071+
flash_first_writable_sector_address = align_up(FLASHIAP_APP_ROM_END_ADDR, flash.get_sector_size(FLASHIAP_APP_ROM_END_ADDR));
1072+
flash_start_address = flash.get_flash_start();
1073+
flash_end_address = flash_start_address + flash.get_flash_size();
1074+
1075+
if (*start_address == 0) {
1076+
if (*size == 0) {
1077+
//The block device will have all space from start address to the end of the flash
1078+
*size = flash.get_flash_size();
1079+
}
1080+
1081+
*start_address = flash_end_address - *size;
1082+
aligned_start_address = align_down(*start_address, flash.get_sector_size(*start_address));
1083+
if (*start_address != aligned_start_address) {
1084+
// Start address not aligned - size should likely be changed so that it is
1085+
flash.deinit();
1086+
return MBED_ERROR_INVALID_SIZE;
1087+
}
1088+
} else {
1089+
aligned_start_address = align_down(*start_address, flash.get_sector_size(*start_address));
1090+
if (*start_address != aligned_start_address) {
1091+
// Start address not aligned - size should likely be changed so that it is
1092+
flash.deinit();
1093+
return MBED_ERROR_INVALID_SIZE;
1094+
}
1095+
1096+
if (*size == 0) {
1097+
//The block device will have all space from start address to the end of the flash
1098+
*size = (flash_end_address - *start_address);
1099+
} else {
1100+
// Do checks on end address to make sure configured start address/size are good
1101+
1102+
end_address = *start_address + *size;
1103+
if (end_address > flash_end_address) {
1104+
// End address is out of flash bounds
1105+
flash.deinit();
1106+
return MBED_ERROR_INVALID_SIZE;
1107+
}
1108+
1109+
aligned_end_address = align_up(end_address, flash.get_sector_size(end_address - 1));
1110+
if (end_address != aligned_end_address) {
1111+
// End address not aligned - size should likely be changed so that it is
1112+
flash.deinit();
1113+
return MBED_ERROR_INVALID_SIZE;
1114+
}
1115+
}
1116+
}
1117+
1118+
flash.deinit();
1119+
1120+
if (*start_address < flash_first_writable_sector_address) {
1121+
// Calculated start address overlaps with ROM
1122+
return MBED_ERROR_MEDIA_FULL;
1123+
}
1124+
#endif
1125+
1126+
return MBED_SUCCESS;
1127+
}

features/storage/kvstore/conf/kv_config.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#ifndef _KV_CONFIG
1717
#define _KV_CONFIG
1818

19+
#include "features/storage/blockdevice/BlockDevice.h"
20+
1921
#ifdef __cplusplus
2022
extern "C" {
2123
#endif
@@ -42,6 +44,32 @@ int kv_init_storage_config();
4244
*/
4345
const char *get_filesystemstore_folder_path();
4446

47+
/**
48+
* @brief Get the default TDBStore flash start address and size.
49+
*
50+
* @param[out] start_address Default TDBStore start address in flash.
51+
* @param[out] size Default TDBStore size.
52+
*
53+
* @returns MBED_SUCCESS Success.
54+
* MBED_ERROR_INITIALIZATION_FAILED Failed to initialize flash driver.
55+
* MBED_ERROR_MEDIA_FULL Default TDBStore space overlaps with program memory.
56+
*/
57+
int kv_get_default_flash_addresses(mbed::bd_addr_t *start_address, mbed::bd_size_t *size);
58+
59+
/**
60+
* @brief Get the TDBStore flash bounds from the configured start address and size.
61+
*
62+
* @param[inout] start_address Configured TDBStore start address in flash.
63+
* @param[inout] size Configured TDBStore size. If 0, the size will be from the start address to the end of flash
64+
*
65+
* @returns MBED_SUCCESS Success.
66+
* MBED_ERROR_INVALID_ARGUMENT One of the arguments is NULL or both the configured start address and size are 0.
67+
* MBED_ERROR_INITIALIZATION_FAILED Failed to initialize flash driver.
68+
* MBED_ERROR_INVALID_SIZE Configured size results in misaligned start/end address or end address past the end of flash.
69+
* MBED_ERROR_MEDIA_FULL Configured start address/size results in bounds overlapping with program memory.
70+
*/
71+
int kv_get_flash_bounds_from_config(mbed::bd_addr_t *start_address, mbed::bd_size_t *size);
72+
4573
#ifdef __cplusplus
4674
} // closing brace for extern "C"
4775
#endif

features/storage/kvstore/direct_access_devicekey/DirectAccessDevicekey.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "MbedCRC.h"
2525
#include "mbed_trace.h"
2626
#include "TDBStore.h"
27+
#include "kv_config.h"
2728
#define TRACE_GROUP "DADK"
2829

2930
using namespace mbed;
@@ -145,13 +146,13 @@ int get_expected_internal_TDBStore_position(uint32_t *out_tdb_start_offset, uint
145146

146147
int ret;
147148
if ((tdb_start_address == 0) && (tdb_size == 0)) {
148-
ret = TDBStore::get_default_flash_addresses(&tdb_start_address, &tdb_size);
149+
ret = kv_get_default_flash_addresses(&tdb_start_address, &tdb_size);
149150
if (ret != MBED_SUCCESS) {
150151
return MBED_ERROR_FAILED_OPERATION;
151152
}
152153
}
153154

154-
ret = TDBStore::get_flash_bounds_from_config(&tdb_start_address, &tdb_size);
155+
ret = kv_get_flash_bounds_from_config(&tdb_start_address, &tdb_size);
155156
if (ret != MBED_SUCCESS) {
156157
return MBED_ERROR_FAILED_OPERATION;
157158
}

0 commit comments

Comments
 (0)