@@ -150,6 +150,12 @@ static const char *filesystemstore_folder_path = NULL;
150
150
151
151
using namespace mbed ;
152
152
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 ;
153
159
154
160
static SingletonPtr<PlatformMutex> mutex;
155
161
static bool is_kv_config_initialize = false ;
@@ -183,13 +189,13 @@ int _calculate_blocksize_match_tdbstore(BlockDevice *bd)
183
189
bd_size_t page_size = bd->get_program_size ();
184
190
bd_size_t number_of_sector = size / erase_size;
185
191
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);
188
194
return -1 ;
189
195
}
190
196
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);
193
199
return -1 ;
194
200
}
195
201
@@ -279,7 +285,7 @@ FileSystem *_get_filesystem_default(const char *mount)
279
285
BlockDevice *_get_blockdevice_FLASHIAP (bd_addr_t start_address, bd_size_t size)
280
286
{
281
287
#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);
283
289
if (ret != 0 ) {
284
290
tr_error (" KV Config: Determination of internal block device bounds failed. The configured start address/size is likely invalid." );
285
291
return NULL ;
@@ -572,7 +578,7 @@ int _create_internal_tdb(BlockDevice **internal_bd, KVStore **internal_tdb, bd_s
572
578
// Get the default address and size for the TDBStore
573
579
if (size == 0 && start_address == 0 ) {
574
580
// 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);
576
582
if (ret != MBED_SUCCESS) {
577
583
return MBED_ERROR_FAILED_OPERATION;
578
584
}
@@ -594,7 +600,7 @@ int _create_internal_tdb(BlockDevice **internal_bd, KVStore **internal_tdb, bd_s
594
600
595
601
// Check if TDBStore has at least 2 sectors or 14 pages.
596
602
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);
598
604
return MBED_ERROR_INVALID_ARGUMENT;
599
605
}
600
606
@@ -991,3 +997,131 @@ MBED_WEAK int kv_init_storage_config()
991
997
mutex->unlock ();
992
998
return ret;
993
999
}
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