Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers kv_config.cpp Source File

kv_config.cpp

00001 /*
00002  * Copyright (c) 2018 ARM Limited. All rights reserved.
00003  * SPDX-License-Identifier: Apache-2.0
00004  * Licensed under the Apache License, Version 2.0 (the License); you may
00005  * not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "kv_config.h"
00018 #include "features/storage/kvstore/include/KVStore.h"
00019 #include "features/storage/kvstore/kv_map/KVMap.h"
00020 #include "features/storage/blockdevice/BlockDevice.h"
00021 #include "features/storage/filesystem/FileSystem.h"
00022 #include "features/storage/kvstore/filesystemstore/FileSystemStore.h"
00023 #include "features/storage/blockdevice/SlicingBlockDevice.h"
00024 #include "features/storage/filesystem/fat/FATFileSystem.h"
00025 #include "features/storage/filesystem/littlefs/LittleFileSystem.h"
00026 #include "features/storage/kvstore/tdbstore/TDBStore.h"
00027 #include "mbed_error.h"
00028 #include "drivers/FlashIAP.h"
00029 #include "features/storage/blockdevice/FlashSimBlockDevice.h"
00030 #include "mbed_trace.h"
00031 #include "features/storage/kvstore/securestore/SecureStore.h"
00032 #define TRACE_GROUP "KVCFG"
00033 
00034 #if COMPONENT_FLASHIAP
00035 #include "components/storage/blockdevice/COMPONENT_FLASHIAP/FlashIAPBlockDevice.h"
00036 #endif
00037 
00038 #if COMPONENT_QSPIF
00039 #include "components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.h"
00040 #endif
00041 
00042 #if COMPONENT_SPIF
00043 #include "components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.h"
00044 #endif
00045 
00046 #if COMPONENT_DATAFLASH
00047 #include "components/storage/blockdevice/COMPONENT_DATAFLASH/DataFlashBlockDevice.h"
00048 #endif
00049 
00050 #if COMPONENT_SD
00051 #include "components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.h"
00052 
00053 #if (STATIC_PINMAP_READY)
00054 const spi_pinmap_t static_spi_pinmap = get_spi_pinmap(MBED_CONF_SD_SPI_MOSI, MBED_CONF_SD_SPI_MISO, MBED_CONF_SD_SPI_CLK, NC);
00055 #endif
00056 #endif
00057 
00058 /**
00059  * @brief This function initializes internal memory secure storage
00060  *        This includes a TDBStore instance with a FlashIAPBlockdevice
00061  *        as the supported storage.
00062  *        The following is a list of configuration parameter
00063  *        MBED_CONF_STORAGE_TDB_INTERNAL_SIZE - The size of the underlying FlashIAPBlockdevice
00064  *        MBED_CONF_STORAGE_TDB_INTERNAL_BASE_ADDRESS - The start address of the underlying FlashIAPBlockdevice
00065  * @returns 0 on success or negative value on failure.
00066  */
00067 int _storage_config_TDB_INTERNAL();
00068 
00069 /**
00070  * @brief This function initialize external memory secure storage
00071  *        This includes a SecureStore class with TDBStore over FlashIAPBlockdevice
00072  *        and an external TDBStore over a default blockdevice unless configured differently.
00073  *        The following is a list of configuration parameter:
00074  *        MBED_CONF_STORAGE_TDB_EXTERNAL_RBP_INTERNAL_SIZE - Size of the internal FlashIAPBlockDevice and by
00075  *                                                           default is set to from start address to the end of the flash.
00076  *                                                           If start address is 0 the start address will be set to end of
00077  *                                                           flash - rbp_internal_size.
00078  *        MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS - The satrt address of the internal FlashIAPBlockDevice.
00079  *        MBED_CONF_STORAGE_TDB_EXTERNAL_EXTERNAL_SIZE - Size of the external blockdevice in bytes or NULL for
00080  *                                                       max possible size.
00081  *        MBED_CONF_STORAGE_TDB_EXTERNAL_EXTERNAL_BASE_ADDRESS - The block device start address.
00082  *        MBED_CONF_STORAGE_TDB_EXTERNAL_EXTERNAL_BLOCK_DEVICE - Alowed vlaues are: default, SPIF, DATAFASH, QSPIF or SD
00083  * @returns 0 on success or negative value on failure.
00084  */
00085 int _storage_config_TDB_EXTERNAL();
00086 
00087 /**
00088  * @brief This function initialize a external memory secure storage
00089  *        This includes a SecureStore class with external TDBStore over a blockdevice or,
00090  *        if no blockdevice was set the default blockdevice will be used.
00091  *        The following is a list of configuration parameter:
00092  *        MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_EXTERNAL_SIZE - Size of the external blockdevice in bytes
00093  *                                                              or NULL for max possible size.
00094  *        MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_EXTERNAL_BASE_ADDRESS - The block device start address
00095  *        MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_EXTERNAL_BLOCK_DEVICE - Alowed vlaues are: default, SPIF, DATAFASH, QSPIF or SD
00096  * @returns 0 on success or negative value on failure.
00097  */
00098 int _storage_config_TDB_EXTERNAL_NO_RBP();
00099 
00100 /**
00101  * @brief This function initialize a FILESYSTEM memory secure storage
00102  *        This includes a SecureStore class with TDBStore over FlashIAPBlockdevice
00103  *        in the internal memory and an external FileSysteStore. If blockdevice and filesystem not set,
00104  *        the system will use the default block device and default filesystem
00105  *        The following is a list of configuration parameter:
00106  *        MBED_CONF_STORAGE_FILESYSTEM_RBP_INTERNAL_SIZE - Size of the internal FlashIAPBlockDevice and by
00107  *                                                         default is set to from start address to the end of the flash.
00108  *                                                         If start address is 0 the start address will be set to end of
00109  *                                                         flash - rbp_internal_size.
00110  *        MBED_CONF_STORAGE_FILESYSTEM_INTERNAL_BASE_ADDRESS - The satrt address of the internal FlashIAPBlockDevice.
00111  *        MBED_CONF_STORAGE_FILESYSTEM_FILESYSTEM - Allowed values are: default, FAT or LITTLE
00112  *        MBED_CONF_STORAGE_FILESYSTEM_BLOCKDEVICE - Allowed values are: default, SPIF, DATAFASH, QSPIF or SD
00113  *        MBED_CONF_STORAGE_FILESYSTEM_EXTERNAL_SIZE - External Blockdevice size in bytes or NULL for max possible size.
00114  *        MBED_CONF_STORAGE_FILESYSTEM_EXTERNAL_BASE_ADDRESS - The block device start address.
00115  *        MBED_CONF_STORAGE_FILESYSTEM_MOUNT_POINT - Where to mount the filesystem
00116  *        MBED_CONF_STORAGE_FILESYSTEM_FOLDER_PATH - The working folder paths
00117  *
00118  * @returns 0 on success or negative value on failure.
00119  */
00120 int _storage_config_FILESYSTEM();
00121 
00122 /**
00123  * @brief This function initialize a FILESYSTEM_NO_RBP memory secure storage with no
00124  *        rollback protection. This includes a SecureStore class an external FileSysteStore over a default
00125  *        filesystem with default blockdevice unless differently configured.
00126  *        The following is a list of configuration parameter:
00127  *        MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_FILESYSTEM - Allowed values are: default, FAT or LITTLE
00128  *        MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_BLOCKDEVICE - Allowed values are: default, SPIF, DATAFASH, QSPIF or SD
00129  *        MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_EXTERNAL_SIZE - Blockdevice size in bytes. or NULL for max possible size.
00130  *        MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_EXTERNAL_BASE_ADDRESS - The block device start address.
00131  *        MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_MOUNT_POINT - Where to mount the filesystem
00132  *        MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_FOLDER_PATH - The working folder paths
00133  *
00134  * @returns 0 on success or negative value on failure.
00135  */
00136 int _storage_config_FILESYSTEM_NO_RBP();
00137 
00138 int _storage_config_tdb_external_common();
00139 int _storage_config_filesystem_common();
00140 
00141 /**
00142  * @brief If block device out of Mbed OS tree is to support, please overwrite this
00143  *        function to provide it.
00144  *
00145  * @returns pointer to other block device.
00146  */
00147 BlockDevice *get_other_blockdevice();
00148 
00149 static const char *filesystemstore_folder_path = NULL;
00150 
00151 using namespace mbed;
00152 
00153 
00154 static SingletonPtr<PlatformMutex>  mutex;
00155 static bool is_kv_config_initialize = false;
00156 static kvstore_config_t kvstore_config;
00157 
00158 #define INTERNAL_BLOCKDEVICE_NAME FLASHIAP
00159 
00160 #define STR_EXPAND(tok) #tok
00161 #define STR(tok) STR_EXPAND(tok)
00162 
00163 #define _GET_FILESYSTEM_concat(dev, ...) _get_filesystem_##dev(__VA_ARGS__)
00164 #define GET_FILESYSTEM(dev, ...) _GET_FILESYSTEM_concat(dev, __VA_ARGS__)
00165 
00166 #define _GET_BLOCKDEVICE_concat(dev, ...) _get_blockdevice_##dev(__VA_ARGS__)
00167 #define GET_BLOCKDEVICE(dev, ...) _GET_BLOCKDEVICE_concat(dev, __VA_ARGS__)
00168 
00169 static inline uint32_t align_up(uint64_t val, uint64_t size)
00170 {
00171     return (((val - 1) / size) + 1) * size;
00172 }
00173 
00174 static inline uint32_t align_down(uint64_t val, uint64_t size)
00175 {
00176     return (((val) / size)) * size;
00177 }
00178 
00179 int _calculate_blocksize_match_tdbstore(BlockDevice *bd)
00180 {
00181     bd_size_t size = bd->size();
00182     bd_size_t erase_size = bd->get_erase_size();
00183     bd_size_t number_of_sector = size / erase_size;
00184 
00185     if (number_of_sector < 2) {
00186         tr_warning("KV Config: There are less than two sectors - TDBStore will not work.");
00187         return -1;
00188     }
00189 
00190 
00191     if (number_of_sector % 2 != 0) {
00192         tr_warning("KV Config: Number of sectors is not an even number. Consider changing the BlockDevice size");
00193     }
00194 
00195     return MBED_SUCCESS;
00196 }
00197 
00198 int _get_addresses(BlockDevice *bd, bd_addr_t start_address, bd_size_t size, bd_addr_t *out_start_addr,
00199                    bd_addr_t *out_end_addr)
00200 {
00201     bd_addr_t aligned_end_address;
00202     bd_addr_t end_address;
00203     bd_addr_t aligned_start_address;
00204 
00205     aligned_start_address = align_down(start_address, bd->get_erase_size(start_address));
00206     if (aligned_start_address != start_address) {
00207         tr_error("KV Config: Start address is not aligned. Better use %02llx", aligned_start_address);
00208         return -1;
00209     }
00210 
00211     if (size == 0) {
00212         (*out_start_addr) = aligned_start_address;
00213         (*out_end_addr) = bd->size();
00214         return 0;
00215     }
00216 
00217     end_address = start_address + size;
00218     aligned_end_address = align_up(end_address, bd->get_erase_size(end_address));
00219     if (aligned_end_address != end_address) {
00220         tr_error("KV Config: End address is not aligned. Consider changing the size parameter.");
00221         return -1;
00222     }
00223 
00224     if (aligned_end_address > bd->size()) {
00225         tr_error("KV Config: End address is out of boundaries");
00226         return -1;
00227     }
00228 
00229     (*out_start_addr) = aligned_start_address;
00230     (*out_end_addr) = aligned_end_address;
00231     return 0;
00232 }
00233 
00234 FileSystem *_get_filesystem_FAT(const char *mount)
00235 {
00236     static FATFileSystem sdcard(mount);
00237     return &sdcard;
00238 
00239 }
00240 
00241 FileSystem *_get_filesystem_LITTLE(const char *mount)
00242 {
00243     static LittleFileSystem flash(mount);
00244     return &flash;
00245 }
00246 
00247 FileSystemStore *_get_file_system_store(FileSystem *fs)
00248 {
00249     static FileSystemStore fss(fs);
00250     return &fss;
00251 }
00252 
00253 FileSystem *_get_filesystem_default(const char *mount)
00254 {
00255 #if COMPONENT_QSPIF || COMPONENT_SPIF || COMPONENT_DATAFLASH
00256     return _get_filesystem_LITTLE(mount);
00257 #elif COMPONENT_SD
00258     return _get_filesystem_FAT(mount);
00259 #else
00260     BlockDevice *bd = get_other_blockdevice();
00261     if (bd) {
00262         if (bd->get_erase_value() != -1) {
00263             return _get_filesystem_LITTLE(mount);
00264         } else {
00265             return _get_filesystem_FAT(mount);
00266         }
00267     } else {
00268         return NULL;
00269     }
00270 #endif
00271 }
00272 
00273 //Calculates the start address of FLASHIAP block device for TDB_INTERNAL profile.
00274 //Last two sectors to have a predictable location for the TDBStore
00275 int _get_flashiap_bd_default_addresses_tdb_internal(bd_addr_t *start_address, bd_size_t *size)
00276 {
00277     int ret = MBED_SUCCESS;
00278 
00279 #if COMPONENT_FLASHIAP
00280 
00281     FlashIAP flash;
00282     static const int STORE_SECTORS = 2;
00283 
00284     if (*start_address || *size) {
00285         return MBED_ERROR_INVALID_ARGUMENT;
00286     }
00287 
00288     if (flash.init() != 0) {
00289         return MBED_ERROR_FAILED_OPERATION;
00290     }
00291 
00292     // Lets work from end of the flash backwards
00293     bd_addr_t curr_addr = flash.get_flash_start() + flash.get_flash_size();
00294 
00295     for (int i = STORE_SECTORS; i; i--) {
00296         bd_size_t sector_size = flash.get_sector_size(curr_addr - 1);
00297         curr_addr -= sector_size;
00298     }
00299 
00300     // Store- and application-sectors mustn't overlap
00301     uint32_t first_wrtbl_sector_addr =
00302         (uint32_t)(align_up(FLASHIAP_APP_ROM_END_ADDR, flash.get_sector_size(FLASHIAP_APP_ROM_END_ADDR)));
00303 
00304     MBED_ASSERT(curr_addr >= first_wrtbl_sector_addr);
00305     if (curr_addr < first_wrtbl_sector_addr) {
00306         ret = MBED_ERROR_MEDIA_FULL;
00307     } else {
00308         *start_address = curr_addr;
00309     }
00310 
00311     flash.deinit();
00312 
00313 #endif
00314 
00315     return ret;
00316 }
00317 
00318 //Calculates address and size for FLASHIAP block device in TDB_EXTERNAL and FILESYSTEM profiles.
00319 //The size of the block device will be 2 sectors at the ends of the internal flash for
00320 //the use of the rbp internal TDBStore.
00321 int _get_flashiap_bd_default_addresses_rbp(bd_addr_t *start_address, bd_size_t *size)
00322 {
00323 #if COMPONENT_FLASHIAP
00324 
00325     bd_addr_t flash_end_address;
00326     bd_addr_t flash_start_address;
00327     bd_addr_t aligned_start_address;
00328     bd_addr_t flash_first_writable_sector_address;
00329     FlashIAP flash;
00330 
00331     if (*start_address != 0 || *size != 0) {
00332         return MBED_ERROR_INVALID_ARGUMENT;
00333     }
00334 
00335     int ret = flash.init();
00336     if (ret != 0) {
00337         return MBED_ERROR_INITIALIZATION_FAILED;
00338     }
00339 
00340     flash_first_writable_sector_address = align_up(FLASHIAP_APP_ROM_END_ADDR, flash.get_sector_size(FLASHIAP_APP_ROM_END_ADDR));
00341     flash_start_address = flash.get_flash_start();
00342     flash_end_address = flash_start_address + flash.get_flash_size();;
00343     *start_address = flash_end_address - 1;
00344     aligned_start_address = align_down(*start_address, flash.get_sector_size(*start_address));
00345     *size = (flash_end_address - aligned_start_address) * 2;
00346     *start_address = (flash_end_address - *size);
00347     aligned_start_address = align_down(*start_address, flash.get_sector_size(*start_address));
00348 
00349     flash.deinit();
00350 
00351     if (aligned_start_address < flash_first_writable_sector_address) {
00352         tr_error("KV Config: Internal block device start address overlapped ROM address ");
00353         return MBED_ERROR_INITIALIZATION_FAILED;
00354     }
00355 
00356 #endif
00357 
00358     return MBED_SUCCESS;
00359 
00360 }
00361 
00362 BlockDevice *_get_blockdevice_FLASHIAP(bd_addr_t start_address, bd_size_t size)
00363 {
00364 #if COMPONENT_FLASHIAP
00365 
00366     bd_addr_t flash_end_address;
00367     bd_addr_t flash_start_address;
00368     bd_addr_t flash_first_writable_sector_address;
00369     bd_addr_t aligned_start_address;
00370     bd_addr_t aligned_end_address;
00371     bd_addr_t end_address;
00372     FlashIAP flash;
00373 
00374     int ret = flash.init();
00375     if (ret != 0) {
00376         return NULL;
00377     }
00378 
00379     //Get flash parameters before starting
00380     flash_first_writable_sector_address = align_up(FLASHIAP_APP_ROM_END_ADDR, flash.get_sector_size(FLASHIAP_APP_ROM_END_ADDR));
00381     flash_start_address = flash.get_flash_start();
00382     flash_end_address = flash_start_address + flash.get_flash_size();;
00383 
00384     //Non default configuration
00385     if (start_address != 0) {
00386 
00387         aligned_start_address = align_down(start_address, flash.get_sector_size(start_address));
00388         if (start_address != aligned_start_address) {
00389             tr_error("KV Config: Internal block device start address is not aligned. Better use %02llx", aligned_start_address);
00390             flash.deinit();
00391             return NULL;
00392         }
00393 
00394         if (size == 0) {
00395             //The block device will have all space from start address to the end of the flash
00396             size = (flash_end_address - start_address);
00397 
00398             static FlashIAPBlockDevice bd(start_address, size);
00399             flash.deinit();
00400             return &bd;
00401         }
00402 
00403         if (size != 0) {
00404             end_address = start_address + size;
00405             if (end_address > flash_end_address) {
00406                 tr_error("KV Config: Internal block device end address is out of boundaries");
00407                 flash.deinit();
00408                 return NULL;
00409             }
00410 
00411             aligned_end_address = align_up(end_address, flash.get_sector_size(end_address - 1));
00412             if (end_address != aligned_end_address) {
00413                 tr_error("KV Config: Internal block device start address is not aligned. Consider changing the size parameter");
00414                 flash.deinit();
00415                 return NULL;
00416             }
00417 
00418             static FlashIAPBlockDevice bd(start_address, size);
00419             flash.deinit();
00420             return &bd;
00421         }
00422     }
00423 
00424     //Non default configuration start_address = 0
00425     start_address = flash_end_address - size;
00426     aligned_start_address = align_down(start_address, flash.get_sector_size(start_address));
00427     if (start_address != aligned_start_address) {
00428         tr_error("KV Config: Internal block device start address is not aligned. Consider changing the size parameter");
00429         flash.deinit();
00430         return NULL;
00431     }
00432 
00433     flash.deinit();
00434 
00435     if (aligned_start_address < flash_first_writable_sector_address) {
00436         tr_error("KV Config: Internal block device start address overlapped ROM address ");
00437         return NULL;
00438     }
00439     static FlashIAPBlockDevice bd(aligned_start_address, size);
00440     return &bd;
00441 
00442 #else
00443     return NULL;
00444 #endif
00445 }
00446 
00447 BlockDevice *_get_blockdevice_SPIF(bd_addr_t start_address, bd_size_t size)
00448 {
00449 #if COMPONENT_SPIF
00450 
00451     bd_addr_t aligned_end_address;
00452     bd_addr_t aligned_start_address;
00453 
00454     static SPIFBlockDevice bd(
00455         MBED_CONF_SPIF_DRIVER_SPI_MOSI,
00456         MBED_CONF_SPIF_DRIVER_SPI_MISO,
00457         MBED_CONF_SPIF_DRIVER_SPI_CLK,
00458         MBED_CONF_SPIF_DRIVER_SPI_CS,
00459         MBED_CONF_SPIF_DRIVER_SPI_FREQ
00460     );
00461 
00462     if (bd.init() != MBED_SUCCESS) {
00463         tr_error("KV Config: SPIFBlockDevice init fail");
00464         return NULL;
00465     }
00466 
00467     if (start_address == 0 && size == 0) {
00468         return &bd;
00469     }
00470 
00471     //If address and size were specified use SlicingBlockDevice to get the correct block device size and start address.
00472     if (_get_addresses(&bd, start_address, size, &aligned_start_address, &aligned_end_address) != 0) {
00473         tr_error("KV Config: Fail to get addresses for SlicingBlockDevice.");
00474         return NULL;
00475     }
00476 
00477     static SlicingBlockDevice sbd(&bd, aligned_start_address, aligned_end_address);
00478     return &sbd;
00479 
00480 #else
00481     return NULL;
00482 #endif
00483 }
00484 
00485 BlockDevice *_get_blockdevice_QSPIF(bd_addr_t start_address, bd_size_t size)
00486 {
00487 #if COMPONENT_QSPIF
00488 
00489     bd_addr_t aligned_end_address;
00490     bd_addr_t aligned_start_address;
00491 
00492     static QSPIFBlockDevice bd(
00493         MBED_CONF_QSPIF_QSPI_IO0,
00494         MBED_CONF_QSPIF_QSPI_IO1,
00495         MBED_CONF_QSPIF_QSPI_IO2,
00496         MBED_CONF_QSPIF_QSPI_IO3,
00497         MBED_CONF_QSPIF_QSPI_SCK,
00498         MBED_CONF_QSPIF_QSPI_CSN,
00499         QSPIF_POLARITY_MODE_0,
00500         MBED_CONF_QSPIF_QSPI_FREQ
00501     );
00502 
00503     if (bd.init() != MBED_SUCCESS) {
00504         tr_error("KV Config: QSPIFBlockDevice init fail");
00505         return NULL;
00506     }
00507 
00508     if (start_address == 0 && size == 0) {
00509         return &bd;
00510     }
00511 
00512     //If address and size were specified use SlicingBlockDevice to get the correct block device size and start address.
00513     if (_get_addresses(&bd, start_address, size, &aligned_start_address, &aligned_end_address) != 0) {
00514         tr_error("KV Config: Fail to get addresses for SlicingBlockDevice.");
00515         return NULL;
00516     }
00517 
00518     static SlicingBlockDevice sbd(&bd, aligned_start_address, aligned_end_address);
00519     return &sbd;
00520 
00521 #else
00522     return NULL;
00523 #endif
00524 }
00525 
00526 BlockDevice *_get_blockdevice_DATAFLASH(bd_addr_t start_address, bd_size_t size)
00527 {
00528 #if COMPONENT_DATAFLASH
00529 
00530     bd_addr_t aligned_end_address;
00531     bd_addr_t aligned_start_address;
00532 
00533     static DataFlashBlockDevice bd(
00534         MBED_CONF_DATAFLASH_SPI_MOSI,
00535         MBED_CONF_DATAFLASH_SPI_MISO,
00536         MBED_CONF_DATAFLASH_SPI_CLK,
00537         MBED_CONF_DATAFLASH_SPI_CS
00538     );
00539 
00540     if (bd.init() != MBED_SUCCESS) {
00541         tr_error("KV Config: DataFlashBlockDevice init fail");
00542         return NULL;
00543     }
00544 
00545     if (start_address == 0 && size == 0) {
00546         return &bd;
00547     }
00548 
00549     //If address and size were specified use SlicingBlockDevice to get the correct block device size and start address.
00550     if (_get_addresses(&bd, start_address, size, &aligned_start_address, &aligned_end_address) != 0) {
00551         tr_error("KV Config: Fail to get addresses for SlicingBlockDevice.");
00552         return NULL;
00553     }
00554 
00555     static SlicingBlockDevice sbd(&bd, aligned_start_address, aligned_end_address);
00556     return &sbd;
00557 
00558 
00559 #else
00560     return NULL;
00561 #endif
00562 }
00563 
00564 BlockDevice *_get_blockdevice_SD(bd_addr_t start_address, bd_size_t size)
00565 {
00566 #if COMPONENT_SD
00567 
00568     bd_addr_t aligned_end_address;
00569     bd_addr_t aligned_start_address;
00570 
00571 #if (STATIC_PINMAP_READY)
00572     static SDBlockDevice bd(
00573         static_spi_pinmap,
00574         MBED_CONF_SD_SPI_CS
00575     );
00576 #else
00577     static SDBlockDevice bd(
00578         MBED_CONF_SD_SPI_MOSI,
00579         MBED_CONF_SD_SPI_MISO,
00580         MBED_CONF_SD_SPI_CLK,
00581         MBED_CONF_SD_SPI_CS
00582     );
00583 #endif
00584 
00585     if (bd.init() != MBED_SUCCESS) {
00586         tr_error("KV Config: SDBlockDevice init fail");
00587         return NULL;
00588     }
00589 
00590     if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "TDB_EXTERNAL_NO_RBP") == 0 ||
00591             strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "TDB_EXTERNAL") == 0) {
00592         //In TDBStore profile, we have a constraint of 4GByte
00593         if (start_address == 0 && size == 0  && bd.size() < (uint32_t)(-1)) {
00594             return &bd;
00595         }
00596 
00597         //If the size of external storage is bigger than 4G we need to slice it.
00598         size = size != 0 ? size : align_down(bd.size(), bd.get_erase_size(bd.size() - 1));
00599 
00600         if (_get_addresses(&bd, start_address, size, &aligned_start_address, &aligned_end_address) != 0) {
00601             tr_error("KV Config: Fail to get addresses for SlicingBlockDevice.");
00602             return NULL;
00603         }
00604 
00605         if (aligned_end_address - aligned_start_address != (uint32_t)(aligned_end_address - aligned_start_address)) {
00606             aligned_end_address = aligned_start_address + (uint32_t)(-1);//Support up to 4G only
00607         }
00608     } else {
00609         //For all other KVStore profiles beside TDBStore we take the entire external memory space.
00610         if (start_address == 0 && size == 0) {
00611             return &bd;
00612         }
00613 
00614         if (_get_addresses(&bd, start_address, size, &aligned_start_address, &aligned_end_address) != 0) {
00615             tr_error("KV Config: Fail to get addresses for SlicingBlockDevice.");
00616             return NULL;
00617         }
00618     }
00619 
00620     aligned_end_address = align_down(aligned_end_address, bd.get_erase_size(aligned_end_address));
00621     static SlicingBlockDevice sbd(&bd, aligned_start_address, aligned_end_address);
00622     return &sbd;
00623 
00624 #else
00625     return NULL;
00626 #endif
00627 }
00628 
00629 BlockDevice *_get_blockdevice_default(bd_addr_t start_address, bd_size_t size)
00630 {
00631 #if COMPONENT_QSPIF
00632     return _get_blockdevice_QSPIF(start_address, size);
00633 #elif COMPONENT_SPIF
00634     return _get_blockdevice_SPIF(start_address, size);
00635 #elif COMPONENT_DATAFLASH
00636     return _get_blockdevice_DATAFLASH(start_address, size);
00637 #elif COMPONENT_SD
00638     return _get_blockdevice_SD(start_address, size);
00639 #else
00640     tr_error("KV Config: No default component define in target.json for this target.");
00641     return NULL;
00642 #endif
00643 }
00644 
00645 /* Same logic as _get_blockdevice_SD() except block device replaced with from
00646  * get_other_blockdevice() */
00647 BlockDevice *_get_blockdevice_other(bd_addr_t start_address, bd_size_t size)
00648 {
00649     bd_addr_t aligned_end_address;
00650     bd_addr_t aligned_start_address;
00651 
00652     BlockDevice *bd = get_other_blockdevice();
00653     if (bd == NULL) {
00654         tr_error("KV Config: \"other\" block device init fail");
00655         return NULL;
00656     }
00657 
00658     if (bd->init() != MBED_SUCCESS) {
00659         tr_error("KV Config: SDBlockDevice init fail");
00660         return NULL;
00661     }
00662 
00663     if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "TDB_EXTERNAL_NO_RBP") == 0 ||
00664             strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "TDB_EXTERNAL") == 0) {
00665         //In TDBStore profile, we have a constraint of 4GByte
00666         if (start_address == 0 && size == 0  && bd->size() < (uint32_t)(-1)) {
00667             return bd;
00668         }
00669 
00670         //If the size of external storage is bigger than 4G we need to slice it.
00671         size = size != 0 ? size : align_down(bd->size(), bd->get_erase_size(bd->size() - 1));
00672 
00673         if (_get_addresses(bd, start_address, size, &aligned_start_address, &aligned_end_address) != 0) {
00674             tr_error("KV Config: Fail to get addresses for SlicingBlockDevice.");
00675             return NULL;
00676         }
00677 
00678         if (aligned_end_address - aligned_start_address != (uint32_t)(aligned_end_address - aligned_start_address)) {
00679             aligned_end_address = aligned_start_address + (uint32_t)(-1);//Support up to 4G only
00680         }
00681     } else {
00682         //For all other KVStore profiles beside TDBStore we take the entire external memory space.
00683         if (start_address == 0 && size == 0) {
00684             return bd;
00685         }
00686 
00687         if (_get_addresses(bd, start_address, size, &aligned_start_address, &aligned_end_address) != 0) {
00688             tr_error("KV Config: Fail to get addresses for SlicingBlockDevice.");
00689             return NULL;
00690         }
00691     }
00692 
00693     aligned_end_address = align_down(aligned_end_address, bd->get_erase_size(aligned_end_address));
00694     static SlicingBlockDevice sbd(bd, aligned_start_address, aligned_end_address);
00695     return &sbd;
00696 }
00697 
00698 MBED_WEAK BlockDevice *get_other_blockdevice()
00699 {
00700     return NULL;
00701 }
00702 
00703 int _storage_config_TDB_INTERNAL()
00704 {
00705 #if COMPONENT_FLASHIAP
00706     bd_size_t internal_size = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_SIZE;
00707     bd_addr_t internal_start_address = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_BASE_ADDRESS;
00708     int ret;
00709 
00710     if (internal_size == 0 && internal_start_address == 0) {
00711         //Calculate the block device size and start address in case default values are used.
00712         ret = _get_flashiap_bd_default_addresses_tdb_internal(&internal_start_address, &internal_size);
00713         if (ret != MBED_SUCCESS) {
00714             return ret;
00715         }
00716     }
00717 
00718     //Get internal memory FLASHIAP block device.
00719     kvstore_config.internal_bd = GET_BLOCKDEVICE(INTERNAL_BLOCKDEVICE_NAME, internal_start_address, internal_size);
00720     if (kvstore_config.internal_bd == NULL) {
00721         tr_error("KV Config: Fail to get internal BlockDevice.");
00722         return MBED_ERROR_FAILED_OPERATION;
00723     }
00724 
00725 
00726     ret = kvstore_config.internal_bd->init();
00727     if (ret != MBED_SUCCESS) {
00728         tr_error("KV Config: Fail to init internal BlockDevice.");
00729         return MBED_ERROR_FAILED_OPERATION;
00730     }
00731 
00732     //Check that internal flash has 2 or more sectors
00733     if (_calculate_blocksize_match_tdbstore(kvstore_config.internal_bd) != MBED_SUCCESS) {
00734         tr_error("KV Config: Can not create TDBStore with less then 2 sector.");
00735         return MBED_ERROR_INVALID_ARGUMENT;
00736     }
00737 
00738     //Deinitialize internal block device and TDB will reinitialize and take control on it.
00739     ret = kvstore_config.internal_bd->deinit();
00740     if (ret != MBED_SUCCESS) {
00741         tr_error("KV Config: Fail to deinit internal BlockDevice.");
00742         return MBED_ERROR_FAILED_OPERATION;
00743     }
00744 
00745     //Create a TDBStore in the internal FLASHIAP block device.
00746     static TDBStore tdb_internal(kvstore_config.internal_bd);
00747     kvstore_config.internal_store = &tdb_internal;
00748 
00749     ret = kvstore_config.internal_store->init();
00750     if (ret != MBED_SUCCESS) {
00751         tr_error("KV Config: Fail to init internal TDBStore.");
00752         return ret;
00753     }
00754     kvstore_config.kvstore_main_instance =
00755         kvstore_config.internal_store;
00756 
00757     //Masking flag - Actually used to remove any KVStore flag which is not supported
00758     //in the chosen KVStore profile.
00759     kvstore_config.flags_mask = ~(KVStore::REQUIRE_CONFIDENTIALITY_FLAG |
00760                                   KVStore::REQUIRE_REPLAY_PROTECTION_FLAG);
00761 
00762     //Initialize kv_map and add the configuration struct to KVStore map.
00763     KVMap &kv_map = KVMap::get_instance();
00764     ret = kv_map.init();
00765     if (MBED_SUCCESS != ret) {
00766         tr_error("KV Config: Fail to init KVStore global API.");
00767         return ret;
00768     }
00769 
00770     ret = kv_map.attach(STR(MBED_CONF_STORAGE_DEFAULT_KV), &kvstore_config);
00771     if (MBED_SUCCESS != ret) {
00772         tr_error("KV Config: Fail to attach KVStore main instance to KVStore global API.");
00773         return ret;
00774     }
00775     return MBED_SUCCESS;
00776 #else
00777     return MBED_ERROR_UNSUPPORTED;
00778 #endif
00779 
00780 }
00781 
00782 int _storage_config_TDB_EXTERNAL()
00783 {
00784 #if !SECURESTORE_ENABLED
00785     return MBED_ERROR_UNSUPPORTED;
00786 #endif
00787 
00788 #ifdef MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS
00789 
00790     bd_size_t internal_rbp_size = MBED_CONF_STORAGE_TDB_EXTERNAL_RBP_INTERNAL_SIZE;
00791     bd_addr_t internal_start_address = MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS;
00792 
00793     //Get the default address and size for internal rbp TDBStore
00794     if (internal_rbp_size == 0 && internal_start_address == 0) {
00795         //Calculate the block device size and start address in case default values are used.
00796         if (_get_flashiap_bd_default_addresses_rbp(&internal_start_address, &internal_rbp_size) != MBED_SUCCESS) {
00797             return MBED_ERROR_FAILED_OPERATION;
00798         }
00799     }
00800 
00801     //Create internal FLASHIAP block device
00802     kvstore_config.internal_bd = GET_BLOCKDEVICE(INTERNAL_BLOCKDEVICE_NAME, internal_start_address, internal_rbp_size);
00803     if (kvstore_config.internal_bd == NULL) {
00804         tr_error("KV Config: Fail to get internal BlockDevice.");
00805         return MBED_ERROR_FAILED_OPERATION ;
00806     }
00807 
00808     int ret = kvstore_config.internal_bd->init();
00809     if (ret != MBED_SUCCESS) {
00810         tr_error("KV Config: Fail to init internal BlockDevice.");
00811         return MBED_ERROR_FAILED_OPERATION ;
00812     }
00813 
00814     //Check if TDBStore has at least 2 sector.
00815     if (_calculate_blocksize_match_tdbstore(kvstore_config.internal_bd) != MBED_SUCCESS) {
00816         tr_error("KV Config: Can not create TDBStore with less then 2 sector.");
00817         return MBED_ERROR_INVALID_ARGUMENT;
00818     }
00819 
00820     //Create internal TDBStore
00821     static TDBStore tdb_internal(kvstore_config.internal_bd);
00822     kvstore_config.internal_store = &tdb_internal;
00823 
00824     ret = kvstore_config.internal_store->init();
00825     if (ret != MBED_SUCCESS) {
00826         tr_error("KV Config: Fail to init internal TDBStore.");
00827         return ret;
00828     }
00829 
00830     bd_size_t size = MBED_CONF_STORAGE_TDB_EXTERNAL_EXTERNAL_SIZE;
00831     bd_addr_t address = MBED_CONF_STORAGE_TDB_EXTERNAL_EXTERNAL_BASE_ADDRESS;
00832 
00833     //Get external BlockDevice for TDBStore
00834     BlockDevice *bd = GET_BLOCKDEVICE(MBED_CONF_STORAGE_TDB_EXTERNAL_BLOCKDEVICE, address, size);
00835     if (bd == NULL) {
00836         tr_error("KV Config: Fail to get external BlockDevice.");
00837         return MBED_ERROR_FAILED_OPERATION ;
00838     }
00839 
00840     //TDBStore needs a block device base on flash. So if this is non-flash type block device,
00841     //add FlashSimBlockDevice on top of it.
00842     if (bd->get_erase_value() == -1) {
00843         //TDBStore needs FlashSimBlockDevice when working with non-flash type block device
00844         if (bd->init() != MBED_SUCCESS) {
00845             tr_error("KV Config: Fail to init external BlockDevice.");
00846             return MBED_ERROR_FAILED_OPERATION ;
00847         }
00848 
00849         static FlashSimBlockDevice flash_bd(bd);
00850         kvstore_config.external_bd = &flash_bd;
00851     } else {
00852         kvstore_config.external_bd = bd;
00853     }
00854 
00855     kvstore_config.flags_mask = ~(0);
00856 
00857     return _storage_config_tdb_external_common();
00858 #else
00859     return MBED_ERROR_CONFIG_UNSUPPORTED;
00860 #endif
00861 }
00862 
00863 int _storage_config_TDB_EXTERNAL_NO_RBP()
00864 {
00865 #if !SECURESTORE_ENABLED
00866     return MBED_ERROR_UNSUPPORTED;
00867 #endif
00868 
00869 #ifdef MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_EXTERNAL_BASE_ADDRESS
00870     bd_size_t size = MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_EXTERNAL_SIZE;
00871     bd_addr_t address = MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_EXTERNAL_BASE_ADDRESS;
00872 
00873     //Get external block device
00874     BlockDevice *bd = GET_BLOCKDEVICE(MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_BLOCKDEVICE, address, size);
00875     if (bd == NULL) {
00876         tr_error("KV Config: Fail to get external BlockDevice.");
00877         return MBED_ERROR_FAILED_OPERATION ;
00878     }
00879 
00880     //TDBStore needs a block device base on flash. So if this is non-flash type block device,
00881     //add FlashSimBlockDevice on top of the SDBlockDevice
00882     if (bd->get_erase_value() == -1) {
00883         //TDBStore needs FlashSimBlockDevice when working with non-flash type block device
00884         if (bd->init() != MBED_SUCCESS) {
00885             tr_error("KV Config: Fail to init external BlockDevice.");
00886             return MBED_ERROR_FAILED_OPERATION ;
00887         }
00888 
00889         static FlashSimBlockDevice flash_bd(bd);
00890         kvstore_config.external_bd = &flash_bd;
00891     } else {
00892         kvstore_config.external_bd = bd;
00893     }
00894 
00895     //Masking flag - Actually used to remove any KVStore flag which is not supported
00896     //in the chosen KVStore profile.
00897     kvstore_config.flags_mask = ~(KVStore::REQUIRE_REPLAY_PROTECTION_FLAG);
00898 
00899     return _storage_config_tdb_external_common();
00900 #else
00901     return MBED_ERROR_CONFIG_UNSUPPORTED;
00902 #endif
00903 }
00904 
00905 int _storage_config_tdb_external_common()
00906 {
00907 #if SECURESTORE_ENABLED
00908     //Initialize external block device
00909     int ret = kvstore_config.external_bd->init();
00910     if (ret != MBED_SUCCESS) {
00911         tr_error("KV Config: Fail to init external BlockDevice.");
00912         return MBED_ERROR_FAILED_OPERATION ;
00913     }
00914 
00915     //Check that there is at least 2 sector for the external TDBStore
00916     if (_calculate_blocksize_match_tdbstore(kvstore_config.external_bd) != MBED_SUCCESS) {
00917         tr_error("KV Config: Can not create TDBStore with less then 2 sector.");
00918         return MBED_ERROR_INVALID_SIZE;
00919     }
00920 
00921     //Create external TDBStore
00922     static TDBStore tdb_external(kvstore_config.external_bd);
00923     kvstore_config.external_store = &tdb_external;
00924 
00925     //Create SecureStore and initialize it
00926     static SecureStore secst(kvstore_config.external_store, kvstore_config.internal_store);
00927 
00928     ret = secst.init();
00929     if (ret != MBED_SUCCESS) {
00930         tr_error("KV Config: Fail to init SecureStore.");
00931         return ret ;
00932     }
00933 
00934     kvstore_config.kvstore_main_instance = &secst;
00935 
00936     //Init kv_map and add the configuration struct to KVStore map.
00937     KVMap &kv_map = KVMap::get_instance();
00938     ret = kv_map.init();
00939     if (MBED_SUCCESS != ret) {
00940         tr_error("KV Config: Fail to init KVStore global API");
00941         return ret;
00942     }
00943 
00944     ret = kv_map.attach(STR(MBED_CONF_STORAGE_DEFAULT_KV), &kvstore_config);
00945     if (MBED_SUCCESS != ret) {
00946         tr_error("KV Config: Fail to attach KvStore main instance to KVStore global API");
00947         return ret;
00948     }
00949 
00950     return MBED_SUCCESS;
00951 #else
00952     return MBED_ERROR_UNSUPPORTED;
00953 #endif
00954 }
00955 
00956 int _storage_config_FILESYSTEM()
00957 {
00958 #if !SECURESTORE_ENABLED
00959     return MBED_ERROR_UNSUPPORTED;
00960 #endif
00961 
00962 #ifdef MBED_CONF_STORAGE_FILESYSTEM_INTERNAL_BASE_ADDRESS
00963     filesystemstore_folder_path = STR(MBED_CONF_STORAGE_FILESYSTEM_FOLDER_PATH);
00964 
00965     bd_size_t internal_rbp_size = MBED_CONF_STORAGE_FILESYSTEM_RBP_INTERNAL_SIZE;
00966     bd_addr_t internal_start_address = MBED_CONF_STORAGE_FILESYSTEM_INTERNAL_BASE_ADDRESS;
00967 
00968     //Get the default address and size for internal rbp TDBStore
00969     if (internal_rbp_size == 0 && internal_start_address == 0) {
00970         //Calculate the block device size and start address in case default values are used.
00971         if (_get_flashiap_bd_default_addresses_rbp(&internal_start_address, &internal_rbp_size) != MBED_SUCCESS) {
00972             return MBED_ERROR_FAILED_OPERATION;
00973         }
00974     }
00975 
00976     //Get internal FLASHIAP block device
00977     kvstore_config.internal_bd = GET_BLOCKDEVICE(INTERNAL_BLOCKDEVICE_NAME, internal_start_address, internal_rbp_size);
00978     if (kvstore_config.internal_bd == NULL) {
00979         tr_error("KV Config: Fail to get internal BlockDevice ");
00980         return MBED_ERROR_FAILED_OPERATION ;
00981     }
00982 
00983     int ret = kvstore_config.internal_bd->init();
00984     if (ret != MBED_SUCCESS) {
00985         tr_error("KV Config: Fail to init internal BlockDevice ");
00986         return MBED_ERROR_FAILED_OPERATION ;
00987     }
00988 
00989     //Check that internal flash has 2 or more sectors
00990     if (_calculate_blocksize_match_tdbstore(kvstore_config.internal_bd) != MBED_SUCCESS) {
00991         tr_error("KV Config: Can not create TDBStore with less then 2 sector.");
00992         return MBED_ERROR_INVALID_ARGUMENT;
00993     }
00994 
00995     //Deinitialize internal block device and TDB will reinitialize and take control on it.
00996     ret = kvstore_config.internal_bd->deinit();
00997     if (ret != MBED_SUCCESS) {
00998         tr_error("KV Config: Fail to deinit internal BlockDevice.");
00999         return MBED_ERROR_FAILED_OPERATION;
01000     }
01001 
01002     //Create internal TDBStore for rbp
01003     static TDBStore tdb_internal(kvstore_config.internal_bd);
01004     kvstore_config.internal_store = &tdb_internal;
01005 
01006     ret = kvstore_config.internal_store->init();
01007     if (ret != MBED_SUCCESS) {
01008         tr_error("KV Config: Fail to init internal TDBStore");
01009         return ret;
01010     }
01011 
01012     bd_size_t size = MBED_CONF_STORAGE_FILESYSTEM_EXTERNAL_SIZE;
01013     bd_addr_t address = MBED_CONF_STORAGE_FILESYSTEM_EXTERNAL_BASE_ADDRESS;
01014     const char *mount_point = STR(MBED_CONF_STORAGE_FILESYSTEM_MOUNT_POINT);
01015 
01016     //Get external block device for FileSystem.
01017     kvstore_config.external_bd = GET_BLOCKDEVICE(MBED_CONF_STORAGE_FILESYSTEM_BLOCKDEVICE, address, size);
01018     if (kvstore_config.external_bd == NULL) {
01019         tr_error("KV Config: Fail to get external BlockDevice ");
01020         return MBED_ERROR_FAILED_OPERATION ;
01021     }
01022 
01023     ret = kvstore_config.external_bd->init();
01024     if (MBED_SUCCESS != ret) {
01025         tr_error("KV Config: Fail to init external BlockDevice ");
01026         return MBED_ERROR_FAILED_OPERATION ;
01027     }
01028 
01029     //Get FileSystem. Can be FAT, LITTLE or default. in case of default, the type will be decided base on the default
01030     //component block device configured in the system. The priority is:
01031     //QSPI -> SPI -> DATAFLASH == LITTLE
01032     //SD == FAT
01033     kvstore_config.external_fs = GET_FILESYSTEM(MBED_CONF_STORAGE_FILESYSTEM_FILESYSTEM, mount_point);
01034     if (kvstore_config.external_fs == NULL) {
01035         tr_error("KV Config: Fail to get FileSystem");
01036         return MBED_ERROR_FAILED_OPERATION ;
01037     }
01038 
01039     kvstore_config.flags_mask = ~(0);
01040 
01041     return _storage_config_filesystem_common();
01042 #else
01043     return MBED_ERROR_CONFIG_UNSUPPORTED;
01044 #endif
01045 }
01046 
01047 int _storage_config_FILESYSTEM_NO_RBP()
01048 {
01049 #if !SECURESTORE_ENABLED
01050     return MBED_ERROR_UNSUPPORTED;
01051 #endif
01052 
01053 #ifdef MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_EXTERNAL_BASE_ADDRESS
01054     filesystemstore_folder_path = STR(MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_FOLDER_PATH);
01055 
01056     bd_size_t size = MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_EXTERNAL_SIZE;
01057     bd_addr_t address = MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_EXTERNAL_BASE_ADDRESS;
01058     const char *mount_point = STR(MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_MOUNT_POINT);
01059 
01060     //Get external block device for FileSystem.
01061     kvstore_config.external_bd = GET_BLOCKDEVICE(MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_BLOCKDEVICE, address, size);
01062     if (kvstore_config.external_bd == NULL) {
01063         tr_error("KV Config: Fail to get external BlockDevice ");
01064         return MBED_ERROR_FAILED_OPERATION ;
01065     }
01066 
01067     int ret = kvstore_config.external_bd->init();
01068     if (MBED_SUCCESS != ret) {
01069         tr_error("KV Config: Fail to init external BlockDevice ");
01070         return MBED_ERROR_FAILED_OPERATION ;
01071     }
01072 
01073     //Get FileSystem. Can be FAT, LITTLE or default. in case of default, the type will be decided base on the default
01074     //component block device configured in the system. The priority is:
01075     //QSPI -> SPI -> DATAFLASH == LITTLE
01076     //SD == FAT
01077     kvstore_config.external_fs = GET_FILESYSTEM(MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_FILESYSTEM, mount_point);
01078     if (kvstore_config.external_fs == NULL) {
01079         tr_error("KV Config: Fail to get FileSystem");
01080         return MBED_ERROR_FAILED_OPERATION ;
01081     }
01082 
01083     //Masking flag - Actually used to remove any KVStore flag which is not supported
01084     //in the chosen KVStore profile.
01085     kvstore_config.flags_mask = ~(KVStore::REQUIRE_REPLAY_PROTECTION_FLAG);
01086 
01087     return _storage_config_filesystem_common();
01088 #else
01089     return MBED_ERROR_CONFIG_UNSUPPORTED;
01090 #endif
01091 }
01092 
01093 int _storage_config_filesystem_common()
01094 {
01095 #if SECURESTORE_ENABLED
01096 
01097     //Mount file system. if it fails, try to reformat
01098     int ret = kvstore_config.external_fs->mount(kvstore_config.external_bd);
01099     if (ret != MBED_SUCCESS) {
01100         ret = kvstore_config.external_fs->reformat(kvstore_config.external_bd);
01101         if (ret != MBED_SUCCESS) {
01102             tr_error("KV Config: Fail to mount FileSystem to %s",
01103                      STR(MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_MOUNT_POINT));
01104             return MBED_ERROR_FAILED_OPERATION ;
01105         }
01106     }
01107 
01108     //Create FileSystemStore
01109     kvstore_config.external_store = _get_file_system_store(kvstore_config.external_fs);
01110     if (kvstore_config.external_store == NULL) {
01111         tr_error("KV Config: Fail to get FileSystemStore");
01112         return MBED_ERROR_FAILED_OPERATION ;
01113     }
01114 
01115     //Create SecureStore and set it as main KVStore
01116     static SecureStore secst(kvstore_config.external_store, kvstore_config.internal_store);
01117 
01118     ret = secst.init();
01119     if (ret != MBED_SUCCESS) {
01120         tr_error("KV Config: Fail to init SecureStore.");
01121         return ret; ;
01122     }
01123 
01124     kvstore_config.kvstore_main_instance = &secst;
01125 
01126     //Init kv_map and add the configuration struct to KVStore map.
01127     KVMap &kv_map = KVMap::get_instance();
01128     ret = kv_map.init();
01129     if (MBED_SUCCESS != ret) {
01130         tr_error("KV Config: Fail to init KVStore global API");
01131         return ret;
01132     }
01133 
01134     ret = kv_map.attach(STR(MBED_CONF_STORAGE_DEFAULT_KV), &kvstore_config);
01135     if (MBED_SUCCESS != ret) {
01136         tr_error("KV Config: Fail to attach KvStore main instance to KVStore global API");
01137         return ret;
01138     }
01139 
01140     return MBED_SUCCESS;
01141 #else
01142     return MBED_ERROR_UNSUPPORTED;
01143 #endif
01144 }
01145 
01146 int _storage_config_default()
01147 {
01148 #if COMPONENT_QSPIF || COMPONENT_SPIF || COMPONENT_DATAFLASH
01149     return _storage_config_TDB_EXTERNAL();
01150 #elif COMPONENT_SD
01151     return _storage_config_FILESYSTEM();
01152 #elif COMPONENT_FLASHIAP
01153     return _storage_config_TDB_INTERNAL();
01154 #else
01155     BlockDevice *bd = get_other_blockdevice();
01156     if (bd) {
01157         if (bd->get_erase_value() != -1) {
01158             return _storage_config_TDB_EXTERNAL();
01159         } else {
01160             return _storage_config_FILESYSTEM();
01161         }
01162     } else {
01163         return MBED_ERROR_UNSUPPORTED;
01164     }
01165 #endif
01166 }
01167 
01168 const char *get_filesystemstore_folder_path()
01169 {
01170     return filesystemstore_folder_path;
01171 }
01172 
01173 MBED_WEAK int kv_init_storage_config()
01174 {
01175 
01176     int ret = MBED_SUCCESS;
01177 
01178     // We currently have no supported configuration without internal storage
01179 #ifndef COMPONENT_FLASHIAP
01180     return MBED_ERROR_UNSUPPORTED;
01181 #endif
01182 
01183     mutex->lock();
01184 
01185     if (is_kv_config_initialize) {
01186         goto exit;
01187     }
01188 
01189     memset(&kvstore_config, 0, sizeof(kvstore_config_t));
01190 
01191     ret = _STORAGE_CONFIG(MBED_CONF_STORAGE_STORAGE_TYPE);
01192 
01193     if (ret == MBED_SUCCESS) {
01194         is_kv_config_initialize = true;
01195     }
01196 
01197 exit:
01198     mutex->unlock();
01199     return ret;
01200 }