Toyomasa Watarai
/
Mbed-example-WS-W27
Mbed Cloud example program for workshop in W27 2018.
Embed:
(wiki syntax)
Show/hide line numbers
pal_internalFlash.c
00001 /* 00002 * Copyright (c) 2016 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 #include "pal.h" 00017 #include "pal_plat_internalFlash.h" 00018 00019 #define BITS_ALIGNED_TO_32 0x3 00020 #define PAL_MAX_PAGE_SIZE 16 00021 00022 PAL_PRIVATE palMutexID_t g_flashMutex = NULLPTR; 00023 00024 00025 size_t pal_internalFlashGetPageSize(void) 00026 { 00027 size_t ret = pal_plat_internalFlashGetPageSize(); 00028 if(ret > PAL_MAX_PAGE_SIZE) 00029 { 00030 ret = PAL_MAX_PAGE_SIZE; 00031 } 00032 return ret; 00033 } 00034 00035 size_t pal_internalFlashGetSectorSize(uint32_t address) 00036 { 00037 size_t ret = pal_plat_internalFlashGetSectorSize(address); 00038 return ret; 00039 } 00040 00041 00042 palStatus_t pal_internalFlashInit(void) 00043 { 00044 palStatus_t ret = PAL_SUCCESS; 00045 if(NULLPTR == g_flashMutex) 00046 { 00047 ret = pal_osMutexCreate(&g_flashMutex); 00048 } 00049 00050 if(PAL_SUCCESS == ret) 00051 { 00052 ret = pal_plat_internalFlashInit(); 00053 } 00054 return ret; 00055 } 00056 00057 palStatus_t pal_internalFlashDeInit(void) 00058 { 00059 palStatus_t ret = PAL_SUCCESS; 00060 if(NULLPTR != g_flashMutex) 00061 { 00062 ret = pal_osMutexDelete(&g_flashMutex); 00063 g_flashMutex = NULLPTR; 00064 } 00065 00066 if(PAL_SUCCESS == ret) 00067 { 00068 ret = pal_plat_internalFlashDeInit(); 00069 } 00070 return ret; 00071 } 00072 00073 palStatus_t pal_internalFlashWrite(const size_t size, const uint32_t address, const uint32_t * buffer) 00074 { 00075 palStatus_t ret = PAL_SUCCESS; 00076 uint32_t pageSize = 0, sectorSize = 0, alignmentLeft = 0; 00077 00078 if (buffer == NULL) 00079 { 00080 return PAL_ERR_INTERNAL_FLASH_NULL_PTR_RECEIVED; 00081 } 00082 else if (address & BITS_ALIGNED_TO_32) 00083 { 00084 return PAL_ERR_INTERNAL_FLASH_BUFFER_ADDRESS_NOT_ALIGNED; 00085 } 00086 else if (size == 0) 00087 { 00088 return PAL_ERR_INTERNAL_FLASH_WRONG_SIZE; 00089 } 00090 00091 pageSize = pal_internalFlashGetPageSize(); 00092 sectorSize = pal_internalFlashGetSectorSize(address); 00093 if ((0 == pageSize) || (sectorSize == 0)) 00094 { 00095 return PAL_ERR_INTERNAL_FLASH_FLASH_ZERO_SIZE; 00096 } 00097 00098 if (address % pageSize) 00099 { 00100 ret = PAL_ERR_INTERNAL_FLASH_ADDRESS_NOT_ALIGNED; 00101 } 00102 else if (((address % sectorSize) + size) > sectorSize) 00103 { 00104 ret = PAL_ERR_INTERNAL_FLASH_CROSSING_SECTORS; 00105 } 00106 else 00107 { 00108 palStatus_t mutexRet = PAL_SUCCESS; 00109 ret = pal_osMutexWait(g_flashMutex, PAL_RTOS_WAIT_FOREVER); 00110 if (ret == PAL_SUCCESS) 00111 { 00112 alignmentLeft = size % pageSize; //Keep the leftover to be copied separately 00113 if (size > pageSize) 00114 { 00115 ret = pal_plat_internalFlashWrite(size - alignmentLeft, address, buffer); 00116 } 00117 00118 if ((ret == PAL_SUCCESS) && (alignmentLeft != 0)) 00119 { 00120 uint32_t * pageBuffer = (uint32_t *)malloc(pageSize); 00121 if (pageBuffer == NULL) 00122 { 00123 ret = PAL_ERR_NO_MEMORY ; 00124 } 00125 else 00126 { 00127 memset(pageBuffer, 0xFF, pageSize); 00128 memcpy(pageBuffer, (uint8_t*)buffer + (size - alignmentLeft), alignmentLeft); 00129 ret = pal_plat_internalFlashWrite(pageSize, address + (size - alignmentLeft), pageBuffer); 00130 free(pageBuffer); 00131 } 00132 } 00133 mutexRet = pal_osMutexRelease(g_flashMutex); 00134 if(PAL_SUCCESS != mutexRet) 00135 { 00136 ret = PAL_ERR_INTERNAL_FLASH_MUTEX_RELEASE_ERROR; 00137 } 00138 } 00139 } 00140 return ret; 00141 } 00142 00143 palStatus_t pal_internalFlashRead(const size_t size, const uint32_t address, uint32_t * buffer) 00144 { 00145 palStatus_t ret = PAL_SUCCESS; 00146 00147 if (buffer == NULL) 00148 { 00149 return PAL_ERR_INTERNAL_FLASH_NULL_PTR_RECEIVED; 00150 } 00151 00152 if (size == 0) 00153 { 00154 return PAL_ERR_INTERNAL_FLASH_WRONG_SIZE; 00155 } 00156 00157 ret = pal_osMutexWait(g_flashMutex, PAL_RTOS_WAIT_FOREVER); 00158 if (PAL_SUCCESS == ret) 00159 { 00160 palStatus_t mutexRet = PAL_SUCCESS; 00161 ret = pal_plat_internalFlashRead(size, address, buffer); 00162 mutexRet = pal_osMutexRelease(g_flashMutex); 00163 if(PAL_SUCCESS != mutexRet) 00164 { 00165 ret = PAL_ERR_INTERNAL_FLASH_MUTEX_RELEASE_ERROR; 00166 } 00167 } 00168 00169 return ret; 00170 } 00171 00172 palStatus_t pal_internalFlashErase(uint32_t address, size_t size) 00173 { 00174 palStatus_t ret = PAL_SUCCESS; 00175 if (size == 0) 00176 { 00177 return PAL_ERR_INTERNAL_FLASH_WRONG_SIZE; 00178 } 00179 00180 if (address & 0x3) 00181 { 00182 return PAL_ERR_INTERNAL_FLASH_BUFFER_ADDRESS_NOT_ALIGNED; 00183 } 00184 00185 ret = pal_osMutexWait(g_flashMutex, PAL_RTOS_WAIT_FOREVER); 00186 if (PAL_SUCCESS == ret) 00187 { 00188 palStatus_t mutexRet = PAL_SUCCESS; 00189 ret = pal_plat_internalFlashErase(address, size); 00190 mutexRet = pal_osMutexRelease(g_flashMutex); 00191 if(PAL_SUCCESS != mutexRet) 00192 { 00193 ret = PAL_ERR_INTERNAL_FLASH_MUTEX_RELEASE_ERROR; 00194 } 00195 } 00196 return ret; 00197 } 00198 00199 palStatus_t pal_internalFlashGetAreaInfo(bool section, palSotpAreaData_t *data) 00200 { 00201 palStatus_t ret = PAL_SUCCESS; 00202 const palSotpAreaData_t internalFlashArea[] = 00203 { 00204 {PAL_INTERNAL_FLASH_SECTION_1_ADDRESS, PAL_INTERNAL_FLASH_SECTION_1_SIZE}, 00205 {PAL_INTERNAL_FLASH_SECTION_2_ADDRESS, PAL_INTERNAL_FLASH_SECTION_2_SIZE} 00206 }; 00207 00208 if(data == NULL) 00209 { 00210 ret = PAL_ERR_INTERNAL_FLASH_NULL_PTR_RECEIVED; 00211 } 00212 else 00213 { 00214 data->address = internalFlashArea[section].address; 00215 data->size = internalFlashArea[section].size; 00216 } 00217 00218 return ret; 00219 } 00220
Generated on Tue Jul 12 2022 16:22:09 by 1.7.2