Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FXAS21002 FXOS8700Q
storage-helper.cpp
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2016-2018 ARM Ltd. 00003 // 00004 // SPDX-License-Identifier: Apache-2.0 00005 // 00006 // Licensed under the Apache License, Version 2.0 (the "License"); 00007 // you may not use this file except in compliance with the License. 00008 // You may obtain a copy of the License at 00009 // 00010 // http://www.apache.org/licenses/LICENSE-2.0 00011 // 00012 // Unless required by applicable law or agreed to in writing, software 00013 // distributed under the License is distributed on an "AS IS" BASIS, 00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 // See the License for the specific language governing permissions and 00016 // limitations under the License. 00017 // ---------------------------------------------------------------------------- 00018 00019 #include "storage-helper/storage-helper.h" 00020 #include "mbed_trace.h" 00021 00022 #define TRACE_GROUP "SMCS" 00023 00024 StorageHelper::StorageHelper(BlockDevice *bd, FileSystem *fs) 00025 : _bd(bd), _fs(fs), fs1(NULL), fs2(NULL), part1(NULL), part2(NULL) 00026 { 00027 } 00028 00029 int StorageHelper::init() { 00030 static bool init_done = false; 00031 int status = 0; 00032 00033 if(!init_done) { 00034 if (_bd) { 00035 status = _bd->init(); 00036 00037 if (status != BD_ERROR_OK) { 00038 tr_warn("bd->init() failed with %d", status); 00039 return -1; 00040 } 00041 00042 #if (MCC_PLATFORM_PARTITION_MODE == 1) 00043 // store partition size 00044 mcc_platform_storage_size = _bd->size(); 00045 tr_debug("init() - BlockDevice init OK, bd->size() = %llu", mcc_platform_storage_size); 00046 #else 00047 tr_debug("init() - BlockDevice init OK, bd->size() = %llu", _bd->size()); 00048 #endif 00049 00050 } 00051 00052 #if (MCC_PLATFORM_PARTITION_MODE == 1) 00053 #if (NUMBER_OF_PARTITIONS > 0) 00054 status = init_and_mount_partition(&fs1, &part1, PRIMARY_PARTITION_NUMBER, ((const char*) MOUNT_POINT_PRIMARY+1)); 00055 if (status != 0) { 00056 #if (MCC_PLATFORM_AUTO_PARTITION == 1) 00057 status = create_partitions(); 00058 if (status != 0) { 00059 return status; 00060 } 00061 #else 00062 tr_warn("primary partition init failed"); 00063 return status; 00064 #endif 00065 } 00066 00067 #if (NUMBER_OF_PARTITIONS == 2) 00068 status = init_and_mount_partition(&fs2, &part2, SECONDARY_PARTITION_NUMBER, ((const char*) MOUNT_POINT_SECONDARY+1)); 00069 if (status != 0) { 00070 #if (MCC_PLATFORM_AUTO_PARTITION == 1) 00071 status = create_partitions(); 00072 if (status != 0) { 00073 return status; 00074 } 00075 #else 00076 tr_warn("secondary partition init failed"); 00077 return status; 00078 #endif 00079 } 00080 #endif // (NUMBER_OF_PARTITIONS == 2) 00081 #if (NUMBER_OF_PARTITIONS > 2) 00082 #error "Invalid number of partitions!!!" 00083 #endif 00084 #endif // (NUMBER_OF_PARTITIONS > 0) 00085 #else // Else for #if (MCC_PLATFORM_PARTITION_MODE == 1) 00086 00087 fs1 = _fs; 00088 part1 = _bd; /* required for mcc_platform_reformat_storage */ 00089 status = test_filesystem(fs1, _bd); 00090 if (status != 0) { 00091 tr_info("Formatting..."); 00092 status = reformat_partition(fs1, _bd); 00093 if (status != 0) { 00094 tr_warn("Formatting failed with 0x%X", status); 00095 return status; 00096 } 00097 } 00098 #endif // MCC_PLATFORM_PARTITION_MODE 00099 init_done = true; 00100 } 00101 else { 00102 tr_debug("init already done"); 00103 } 00104 00105 return status; 00106 } 00107 00108 int StorageHelper::sotp_init(void) 00109 { 00110 int status = FCC_STATUS_SUCCESS; 00111 // Include this only for Developer mode and a device which doesn't have in-built TRNG support. 00112 #if MBED_CONF_DEVICE_MANAGEMENT_DEVELOPER_MODE == 1 00113 #ifdef PAL_USER_DEFINED_CONFIGURATION 00114 #if !PAL_USE_HW_TRNG 00115 status = fcc_entropy_set(MBED_CLOUD_DEV_ENTROPY, FCC_ENTROPY_SIZE); 00116 00117 if (status != FCC_STATUS_SUCCESS && status != FCC_STATUS_ENTROPY_ERROR) { 00118 tr_error("fcc_entropy_set failed with status %d", status); 00119 fcc_finalize(); 00120 return status; 00121 } 00122 #endif // PAL_USE_HW_TRNG = 0 00123 /* Include this only for Developer mode. The application will use fixed RoT to simplify user-experience with the application. 00124 * With this change the application be reflashed/SOTP can be erased safely without invalidating the application credentials. 00125 */ 00126 status = fcc_rot_set(MBED_CLOUD_DEV_ROT, FCC_ROT_SIZE); 00127 00128 if (status != FCC_STATUS_SUCCESS && status != FCC_STATUS_ROT_ERROR) { 00129 tr_error("fcc_rot_set failed with status %d", status); 00130 fcc_finalize(); 00131 } else { 00132 // We can return SUCCESS here as preexisting RoT/Entropy is expected flow. 00133 tr_info("Using hardcoded Root of Trust, not suitable for production use"); 00134 status = FCC_STATUS_SUCCESS; 00135 } 00136 #endif // PAL_USER_DEFINED_CONFIGURATION 00137 #endif // #if MBED_CONF_DEVICE_MANAGEMENT_DEVELOPER_MODE == 1 00138 return status; 00139 } 00140 00141 00142 int StorageHelper::reformat_storage(void) { 00143 int status = -1; 00144 00145 if (_bd) { 00146 #if (NUMBER_OF_PARTITIONS > 0) 00147 status = reformat_partition(fs1, part1); 00148 if (status != 0) { 00149 tr_warn("Formatting primary partition failed with 0x%X", status); 00150 return status; 00151 } 00152 #if (NUMBER_OF_PARTITIONS == 2) 00153 status = reformat_partition(fs2, part2); 00154 if (status != 0) { 00155 tr_warn("Formatting secondary partition failed with 0x%X", status); 00156 return status; 00157 } 00158 #endif 00159 #if (NUMBER_OF_PARTITIONS > 2) 00160 #error "Invalid number of partitions!!!" 00161 #endif 00162 #endif 00163 00164 #if NUMBER_OF_PARTITIONS == 0 00165 status = StorageHelper::format(_fs, _bd); 00166 #endif 00167 } 00168 00169 tr_info("Storage reformatted (%d)", status); 00170 00171 return status; 00172 } 00173 00174 int StorageHelper::format(FileSystem *fs, BlockDevice *bd) { 00175 if (!fs || !bd) return -1; 00176 00177 int status; 00178 00179 status = bd->init(); 00180 if (status != 0) { 00181 return status; 00182 } 00183 00184 status = fs->mount(bd); 00185 // might fail because already mounted, so ignore 00186 00187 status = fs->reformat(bd); 00188 if (status != 0) { 00189 if (bd->erase(0, bd->size()) == 0) { 00190 if (fs->reformat(bd) == 0) { 00191 status = 0; 00192 printf("The storage reformatted successfully.\n"); 00193 } 00194 } 00195 } 00196 00197 return status; 00198 } 00199 00200 #if (MCC_PLATFORM_PARTITION_MODE == 1) 00201 // bd must be initialized before calling this function. 00202 int StorageHelper::init_and_mount_partition(FileSystem **fs, BlockDevice** part, int number_of_partition, const char* mount_point) { 00203 int status; 00204 00205 // Init fs only once. 00206 if (&(**fs) == NULL) { 00207 if (&(**part) == NULL) { 00208 *part = new MBRBlockDevice(_bd, number_of_partition); 00209 } 00210 status = (**part).init(); 00211 if (status != 0) { 00212 (**part).deinit(); 00213 tr_warn("Init of partition %d fail", number_of_partition); 00214 return status; 00215 } 00216 /* This next change mean that filesystem will be FAT. */ 00217 *fs = new FATFileSystem(mount_point, &(**part)); /* this also mount fs. */ 00218 } 00219 // re-init and format. 00220 else { 00221 status = (**part).init(); 00222 if (status != 0) { 00223 (**part).deinit(); 00224 tr_warn("Init of partition %d fail", number_of_partition); 00225 return status; 00226 } 00227 00228 tr_debug("Formatting partition %d ...", number_of_partition); 00229 status = reformat_partition(&(**fs), &(**part)); 00230 if (status != 0) { 00231 tr_warn("Formatting partition %d failed with 0x%X", number_of_partition, status); 00232 return status; 00233 } 00234 } 00235 00236 status = test_filesystem(&(**fs), &(**part)); 00237 if (status != 0) { 00238 tr_debug("Formatting partition %d ...", number_of_partition); 00239 status = reformat_partition(&(**fs), &(**part)); 00240 if (status != 0) { 00241 tr_warn("Formatting partition %d failed with 0x%X", number_of_partition, status); 00242 return status; 00243 } 00244 } 00245 00246 return status; 00247 } 00248 #endif 00249 00250 int StorageHelper::reformat_partition(FileSystem *fs, BlockDevice* part) { 00251 return fs->reformat(part); 00252 } 00253 00254 /* help function for testing filesystem availbility by umount and 00255 * mount filesystem again. 00256 * */ 00257 int StorageHelper::test_filesystem(FileSystem *fs, BlockDevice* part) { 00258 // unmount 00259 int status = fs->unmount(); 00260 if (status != 0) { 00261 tr_info("test_filesystem() - unmount fail %d", status); 00262 // should be OK, maybe not mounted... 00263 } 00264 // mount again 00265 status = fs->mount(part); 00266 if (status != 0) { 00267 tr_info("test_filesystem() - mount fail %d", status); 00268 return -1; 00269 } 00270 return status; 00271 } 00272 00273 // create partitions, initialize and mount partitions 00274 #if ((MCC_PLATFORM_PARTITION_MODE == 1) && (MCC_PLATFORM_AUTO_PARTITION == 1)) 00275 int StorageHelper::create_partitions(void) { 00276 int status; 00277 00278 #if (NUMBER_OF_PARTITIONS > 0) 00279 if (mcc_platform_storage_size < PRIMARY_PARTITION_SIZE) { 00280 tr_error("create_partitions PRIMARY_PARTITION_SIZE too large!!! Storage's size is %" PRIu64 \ 00281 " and PRIMARY_PARTITION_SIZE is %" PRIu64, 00282 (uint64_t)mcc_platform_storage_size, (uint64_t)PRIMARY_PARTITION_SIZE); 00283 assert(0); 00284 } 00285 00286 status = MBRBlockDevice::partition(_bd, PRIMARY_PARTITION_NUMBER, 0x83, PRIMARY_PARTITION_START, PRIMARY_PARTITION_START + PRIMARY_PARTITION_SIZE); 00287 tr_debug("Creating primary partition ..."); 00288 if (status != 0) { 00289 tr_warn("Creating primary partition failed 0x%X", status); 00290 return status; 00291 } 00292 tr_debug("Created primary partition"); 00293 00294 // init and format partition 1 00295 status = init_and_mount_partition(&fs1, &part1, PRIMARY_PARTITION_NUMBER, ((const char*) MOUNT_POINT_PRIMARY+1)); 00296 if (status != 0) { 00297 return status; 00298 } 00299 tr_debug("Mounted primary partition"); 00300 00301 #if (NUMBER_OF_PARTITIONS == 2) 00302 // use cast (uint64_t) for fixing compile warning. 00303 if (mcc_platform_storage_size < ((uint64_t)PRIMARY_PARTITION_SIZE + (uint64_t)SECONDARY_PARTITION_SIZE)) { 00304 tr_error("create_partitions (PRIMARY_PARTITION_SIZE+SECONDARY_PARTITION_SIZE) too large!!! Storage's size is %" PRIu64 \ 00305 " and (PRIMARY_PARTITION_SIZE+SECONDARY_PARTITION_SIZE) %" PRIu64, 00306 (uint64_t)mcc_platform_storage_size, (uint64_t)(PRIMARY_PARTITION_SIZE+SECONDARY_PARTITION_SIZE)); 00307 assert(0); 00308 } 00309 00310 // use cast (uint64_t) for fixing compile warning. 00311 status = MBRBlockDevice::partition(_bd, SECONDARY_PARTITION_NUMBER, 0x83, SECONDARY_PARTITION_START, (uint64_t) SECONDARY_PARTITION_START + (uint64_t) SECONDARY_PARTITION_SIZE); 00312 tr_debug("Creating secondary partition ..."); 00313 if (status != 0) { 00314 tr_warn("Creating secondary partition failed 0x%X", status); 00315 return status; 00316 } 00317 tr_debug("Created secondary partition"); 00318 00319 // init and format partition 2 00320 status = init_and_mount_partition(&fs2, &part2, SECONDARY_PARTITION_NUMBER, ((const char*) MOUNT_POINT_SECONDARY+1)); 00321 if (status != 0) { 00322 return status; 00323 } 00324 tr_debug("Mounted secondary partition"); 00325 #endif 00326 #if (NUMBER_OF_PARTITIONS > 2) 00327 #error "Invalid number of partitions!!!" 00328 #endif 00329 #endif // (NUMBER_OF_PARTITIONS > 0) 00330 return status; 00331 } 00332 #endif // ((MCC_PLATFORM_PARTITION_MODE == 1) && (MCC_PLATFORM_AUTO_PARTITION == 1))
Generated on Tue Jul 12 2022 20:21:03 by
