@@ -150,6 +150,12 @@ static const char *filesystemstore_folder_path = NULL;
150150
151151using 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
154160static SingletonPtr<PlatformMutex> mutex;
155161static 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)
279285BlockDevice *_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+ }
0 commit comments