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
pal_plat_internalFlash_FlashOverFilesystem.c
00001 /******************************************************************************* 00002 * Copyright 2016, 2017 ARM Ltd. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may 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, 00012 * WITHOUT 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 #include "pal.h" 00017 #include "pal_plat_internalFlash.h" 00018 00019 #if (PAL_USE_INTERNAL_FLASH) 00020 00021 #if PAL_SIMULATOR_FLASH_OVER_FILE_SYSTEM 00022 00023 #include <stdio.h> // for snprintf 00024 #include <stdlib.h> 00025 #include <string.h> 00026 00027 #define TRACE_GROUP "PAL" 00028 00029 #define BITS_ALIGNED_TO_32 0x3 00030 00031 PAL_PRIVATE palFileDescriptor_t g_fd = 0; 00032 00033 //////////////////////////END GLOBALS SECTION //////////////////////////// 00034 00035 00036 //////////////////////////START PRIVATE SECTION//////////////////////////// 00037 // Verify that the alignment to sector size 00038 // Parameters : 00039 // @param[in] address - Address to verify. 00040 // @param[in] size - Size to write 00041 // Return : None. 00042 PAL_PRIVATE bool pal_isAlignedToSector(uint32_t address, size_t size) 00043 { 00044 uint32_t currentSectorSize = pal_internalFlashGetSectorSize(address); 00045 if ((size % currentSectorSize) || (address % currentSectorSize)) 00046 { 00047 return false; 00048 } 00049 else 00050 { 00051 return true; 00052 } 00053 } 00054 00055 00056 // Get path of the simulated flash file 00057 // Parameters : 00058 // @param[out] path - output buffer 00059 // Return : PAL_SUCCESS if the combined mount point and flash directory are under the maximum path limit 00060 PAL_PRIVATE palStatus_t pal_getFlashSimulationFilePath(char* path) 00061 { 00062 char root[PAL_MAX_FILE_AND_FOLDER_LENGTH]; 00063 00064 palStatus_t status = PAL_SUCCESS; 00065 00066 status = pal_fsGetMountPoint(PAL_FS_PARTITION_SECONDARY, PAL_MAX_FILE_AND_FOLDER_LENGTH, root); 00067 if (PAL_SUCCESS == status) 00068 { 00069 size_t written; 00070 if (SIMULATE_FLASH_DIR[0] != 0) 00071 { 00072 written = snprintf(path, PAL_MAX_FILE_AND_FOLDER_LENGTH, "%s/%s", root, SIMULATE_FLASH_DIR); 00073 } 00074 else { 00075 written = snprintf(path, PAL_MAX_FILE_AND_FOLDER_LENGTH, "%s", root); 00076 } 00077 00078 // verify, if the mount point and SIMULATE_FLASH_DIR fit to the hard coded maximum. 00079 if (written >= PAL_MAX_FILE_AND_FOLDER_LENGTH) 00080 { 00081 status = PAL_ERR_INVALID_ARGUMENT ; 00082 } 00083 } 00084 00085 return status; 00086 } 00087 00088 // Get path and filename of the simulated flash file 00089 // Parameters : 00090 // @param[out] path - output buffer 00091 // Return : PAL_SUCCESS if the combined filenames are under the maximum path limit 00092 PAL_PRIVATE palStatus_t pal_getFlashSimulationFilePathAndName(char* path) 00093 { 00094 char root[PAL_MAX_FILE_AND_FOLDER_LENGTH]; 00095 00096 palStatus_t status = PAL_ERR_FS_INVALID_FILE_NAME; 00097 00098 if (SIMULATE_FLASH_FILE_NAME[0] == '/') 00099 { 00100 status = pal_fsGetMountPoint(PAL_FS_PARTITION_SECONDARY, PAL_MAX_FILE_AND_FOLDER_LENGTH, root); 00101 if (PAL_SUCCESS == status) 00102 { 00103 // the SIMULATE_FLASH_FILE_NAME is specified to contain also the SIMULATE_FLASH_DIR -directory 00104 // and it will begin with a '/' char, so this needs separate implementation from pal_getFlashSimulationFileDir() 00105 int written = snprintf(path, PAL_MAX_FILE_AND_FOLDER_LENGTH, "%s%s", root, SIMULATE_FLASH_FILE_NAME); 00106 if (written >= PAL_MAX_FILE_AND_FOLDER_LENGTH) 00107 { 00108 status = PAL_ERR_INVALID_ARGUMENT ; 00109 } 00110 } 00111 } 00112 00113 return status; 00114 } 00115 00116 // Check whether area file exists. Create it if not. 00117 // Parameters : 00118 // @param[in] 00119 // Return : None. 00120 // Note - If file does not exist create and fill with 0xFF this simulate erased flash 00121 PAL_PRIVATE palStatus_t pal_verifyAndCreateFlashFile(void) 00122 { 00123 uint32_t index; 00124 uint8_t writeBuffer[SIMULATE_FLASH_PAGE_SIZE] = {0}; 00125 char buffer[PAL_MAX_FILE_AND_FOLDER_LENGTH] = {0}; 00126 palStatus_t ret = PAL_SUCCESS; 00127 size_t numOfBytes = 0; 00128 palSotpAreaData_t areaData_1, areaData_2; 00129 00130 pal_internalFlashGetAreaInfo(0, &areaData_1); 00131 pal_internalFlashGetAreaInfo(1, &areaData_2); 00132 00133 ret = pal_getFlashSimulationFilePathAndName(buffer); 00134 if (PAL_SUCCESS == ret) 00135 { 00136 ret = pal_fsFopen(buffer, PAL_FS_FLAG_READWRITEEXCLUSIVE, &g_fd); 00137 if (PAL_ERR_FS_NAME_ALREADY_EXIST == ret) 00138 { 00139 return PAL_SUCCESS; //file exist nothing else to do 00140 } 00141 else if (PAL_SUCCESS == ret) 00142 { 00143 memset(writeBuffer, PAL_INT_FLASH_BLANK_VAL, SIMULATE_FLASH_PAGE_SIZE); 00144 for (index = 0; index < (areaData_1.size + areaData_2.size) / SIMULATE_FLASH_PAGE_SIZE; index++) 00145 { 00146 ret = pal_fsFwrite(&g_fd, (void *)writeBuffer, SIMULATE_FLASH_PAGE_SIZE, &numOfBytes); 00147 if (PAL_SUCCESS != ret) 00148 { 00149 break; 00150 } 00151 } 00152 pal_fsFclose(&g_fd); 00153 } 00154 } 00155 return ret; 00156 } 00157 00158 00159 //////////////////////////END PRIVATE SECTION//////////////////////////// 00160 00161 00162 size_t pal_plat_internalFlashGetPageSize(void) 00163 { 00164 size_t ret = SIMULATE_FLASH_PAGE_SIZE; 00165 return ret; 00166 } 00167 00168 size_t pal_plat_internalFlashGetSectorSize(uint32_t address) 00169 { 00170 00171 size_t ret = SIMULATE_FLASH_SECTOR_SIZE; 00172 return ret; 00173 } 00174 00175 palStatus_t pal_plat_internalFlashInit(void) 00176 { 00177 palStatus_t ret = PAL_SUCCESS; 00178 00179 char buffer[PAL_MAX_FILE_AND_FOLDER_LENGTH]; 00180 00181 ret = pal_getFlashSimulationFilePath(buffer); 00182 00183 if (PAL_SUCCESS == ret) 00184 { 00185 ret = pal_fsMkDir(buffer); //Create Directory 00186 if ((PAL_ERR_FS_NAME_ALREADY_EXIST == ret)) 00187 { 00188 ret = PAL_SUCCESS; 00189 } 00190 00191 if (PAL_SUCCESS == ret) 00192 { 00193 // Create file too, which verifies that the access rights on 00194 // the filesystem are correct and it has enough space for simulation 00195 // file. 00196 ret = pal_verifyAndCreateFlashFile(); 00197 } 00198 } 00199 00200 return ret; 00201 } 00202 00203 00204 palStatus_t pal_plat_internalFlashDeInit(void) 00205 { 00206 palStatus_t ret = PAL_SUCCESS; 00207 return ret; 00208 } 00209 00210 palStatus_t pal_plat_internalFlashRead(const size_t size, const uint32_t address, uint32_t * buffer) 00211 { 00212 palStatus_t ret = PAL_SUCCESS; 00213 00214 PAL_VALIDATE_CONDITION_WITH_ERROR ((buffer == NULL), PAL_ERR_INTERNAL_FLASH_NULL_PTR_RECEIVED) 00215 PAL_VALIDATE_CONDITION_WITH_ERROR ((size == 0),PAL_ERR_INTERNAL_FLASH_WRONG_SIZE) 00216 00217 size_t numberOfBytesRead = 0; 00218 char fileBuffer[PAL_MAX_FILE_AND_FOLDER_LENGTH]; 00219 00220 ret = pal_getFlashSimulationFilePathAndName(fileBuffer); 00221 if (PAL_SUCCESS == ret) 00222 { 00223 // XXX: why not keep the file open all the time? There is init() & deinit() 00224 // to allow that. The code even uses a global file handle for the temporary 00225 // operations. 00226 ret = pal_fsFopen(fileBuffer, PAL_FS_FLAG_READONLY, &g_fd); 00227 if (PAL_SUCCESS == ret) 00228 { 00229 ret = pal_fsFseek(&g_fd, address, PAL_FS_OFFSET_SEEKSET); 00230 if (PAL_SUCCESS == ret) 00231 { 00232 ret = pal_fsFread(&g_fd, buffer, size, &numberOfBytesRead); 00233 } 00234 pal_fsFclose(&g_fd); 00235 } 00236 } 00237 00238 return ret; 00239 } 00240 00241 00242 palStatus_t pal_plat_internalFlashErase(uint32_t address, size_t size) 00243 { 00244 palStatus_t ret = PAL_SUCCESS; 00245 00246 PAL_VALIDATE_CONDITION_WITH_ERROR ((size == 0),PAL_ERR_INTERNAL_FLASH_WRONG_SIZE) 00247 PAL_VALIDATE_ARG_RLZ ((address & BITS_ALIGNED_TO_32),PAL_ERR_INTERNAL_FLASH_BUFFER_ADDRESS_NOT_ALIGNED)//Address not aligned to 32 bit 00248 PAL_VALIDATE_ARG_RLZ ((!pal_isAlignedToSector(address,size)),PAL_ERR_INTERNAL_FLASH_SECTOR_NOT_ALIGNED)//not aligned to sector 00249 00250 char fileBuffer[PAL_MAX_FILE_AND_FOLDER_LENGTH]; 00251 size_t numOfBytes = 0, index = 0; 00252 uint8_t writeBuffer[SIMULATE_FLASH_PAGE_SIZE] = {0}; 00253 00254 ret = pal_getFlashSimulationFilePathAndName(fileBuffer); 00255 if (PAL_SUCCESS == ret) 00256 { 00257 ret = pal_fsFopen(fileBuffer, PAL_FS_FLAG_READWRITE, &g_fd); 00258 if (PAL_SUCCESS == ret) 00259 { 00260 ret = pal_fsFseek(&g_fd, address, PAL_FS_OFFSET_SEEKSET); 00261 if (PAL_SUCCESS == ret) 00262 { 00263 memset(writeBuffer, PAL_INT_FLASH_BLANK_VAL, SIMULATE_FLASH_PAGE_SIZE); 00264 for (index = 0; index < size / SIMULATE_FLASH_PAGE_SIZE; index++) 00265 { 00266 ret = pal_fsFwrite(&g_fd, (void *)writeBuffer, SIMULATE_FLASH_PAGE_SIZE, &numOfBytes); 00267 if (PAL_SUCCESS != ret) 00268 { 00269 break; 00270 } 00271 } 00272 } 00273 pal_fsFclose(&g_fd); 00274 } 00275 } 00276 00277 return ret; 00278 } 00279 00280 00281 palStatus_t pal_plat_internalFlashWrite(const size_t size, const uint32_t address, const uint32_t * buffer) 00282 { 00283 palStatus_t ret = PAL_SUCCESS; 00284 uint32_t pageSize = 0; 00285 00286 PAL_VALIDATE_CONDITION_WITH_ERROR ((buffer == NULL), PAL_ERR_INTERNAL_FLASH_NULL_PTR_RECEIVED) 00287 PAL_VALIDATE_ARG_RLZ ((address & BITS_ALIGNED_TO_32),PAL_ERR_INTERNAL_FLASH_BUFFER_ADDRESS_NOT_ALIGNED)//Address not aligned to 32 bit 00288 PAL_VALIDATE_ARG_RLZ ((size == 0),PAL_ERR_INTERNAL_FLASH_WRONG_SIZE) 00289 00290 pageSize = pal_plat_internalFlashGetPageSize(); 00291 00292 char fileBuffer[PAL_MAX_FILE_AND_FOLDER_LENGTH]; 00293 uint32_t alignmentLeft = 0; 00294 size_t numOfBytes = 0; 00295 00296 ret = pal_getFlashSimulationFilePathAndName(fileBuffer); 00297 if (PAL_SUCCESS == ret) 00298 { 00299 ret = pal_fsFopen(fileBuffer, PAL_FS_FLAG_READWRITE, &g_fd); 00300 if (PAL_SUCCESS == ret) 00301 { 00302 alignmentLeft = size % pageSize; //Keep the leftover to be copied separately 00303 if (size >= pageSize) 00304 { 00305 ret = pal_fsFseek(&g_fd, address, PAL_FS_OFFSET_SEEKSET); 00306 if (PAL_SUCCESS == ret) 00307 { 00308 ret = pal_fsFwrite(&g_fd, (void *)buffer, size - alignmentLeft, &numOfBytes); 00309 } 00310 } 00311 00312 if ((ret == PAL_SUCCESS) && (alignmentLeft != 0)) 00313 { 00314 uint32_t * pageBuffer = (uint32_t *)malloc(pageSize); 00315 if (pageBuffer == NULL) 00316 { 00317 ret = PAL_ERR_NO_MEMORY ; 00318 } 00319 else 00320 { 00321 memset(pageBuffer, 0xFF, pageSize); 00322 memcpy(pageBuffer, (uint8_t*)buffer + (size - alignmentLeft), alignmentLeft); 00323 ret = pal_fsFseek(&g_fd, address + (size - alignmentLeft), PAL_FS_OFFSET_SEEKSET); 00324 if (PAL_SUCCESS == ret) 00325 { 00326 ret = pal_fsFwrite(&g_fd, (void *)pageBuffer, pageSize, &numOfBytes); 00327 } 00328 free(pageBuffer); 00329 } 00330 } 00331 pal_fsFclose(&g_fd); 00332 } 00333 } 00334 00335 return ret; 00336 } 00337 00338 00339 #endif // PAL_SIMULATOR_FLASH_OVER_FILE_SYSTEM 00340 00341 #endif //(PAL_USE_INTERNAL_FLASH)
Generated on Tue Jul 12 2022 20:21:02 by
