Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_internalFlash_test.c Source File

pal_internalFlash_test.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 
00017 #include "pal.h"
00018 #include "unity.h"
00019 #include "unity_fixture.h"
00020 
00021 #define TRACE_GROUP "PAL"
00022 
00023 TEST_GROUP(pal_internalFlash);
00024 
00025 #define LITTLE_BUFFER_SIZE                  120
00026 #define PRIME_NUMBER_FOR_TESTING            11 //must be 4 times lower then LITTLE_BUFFER_SIZE
00027 #define MAX_BUFFER_SIZE                     0x1000
00028 
00029 palSotpAreaData_t areaOneData;
00030 palSotpAreaData_t areaTwoData;
00031 uint32_t *ReadBuffer = NULL;
00032 uint32_t *compareBuffer = NULL;
00033 uint32_t biggestSectorSize = 0;
00034 
00035 
00036 palStatus_t InternalFlashWriteTest(uint32_t address_offset);
00037 palStatus_t InternalFlashReadTest(uint32_t address_offset);
00038 
00039 TEST_SETUP(pal_internalFlash)
00040 {
00041 
00042 #if PAL_USE_INTERNAL_FLASH
00043 
00044     palStatus_t status = PAL_SUCCESS;
00045     status = pal_internalFlashGetAreaInfo(0, &areaOneData);
00046     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00047     status = pal_internalFlashGetAreaInfo(1, &areaTwoData);
00048     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00049     biggestSectorSize = (PAL_MAX(areaTwoData.size, areaOneData.size));
00050     biggestSectorSize = (PAL_MIN(biggestSectorSize, MAX_BUFFER_SIZE)); //there are sector size 128KB so this limit the buffer to 4KB
00051     ReadBuffer = (uint32_t *)malloc(biggestSectorSize);
00052     TEST_ASSERT_NOT_NULL(ReadBuffer);
00053     compareBuffer = (uint32_t *)malloc(biggestSectorSize);
00054     TEST_ASSERT_NOT_NULL(compareBuffer);
00055     pal_init();
00056 
00057 #endif //PAL_USE_INTERNAL_FLASH
00058 
00059 }
00060 
00061 TEST_TEAR_DOWN(pal_internalFlash)
00062 {
00063 
00064 #if PAL_USE_INTERNAL_FLASH
00065 
00066     if (compareBuffer != NULL)
00067     {
00068         free(compareBuffer);
00069         compareBuffer = NULL;
00070     }
00071 
00072     if (ReadBuffer != NULL)
00073     {
00074         free(ReadBuffer);
00075         ReadBuffer = NULL;
00076     }
00077     pal_destroy();
00078 
00079 #endif //PAL_USE_INTERNAL_FLASH
00080 
00081 }
00082 
00083 
00084 /*! \brief This function checks if the flash needed to be deleted by checking if all bytes in sector are 0xFF */
00085 void SectorDeleteValidity(uint32_t address, size_t size)
00086 {
00087 #if PAL_USE_INTERNAL_FLASH
00088     palStatus_t status = PAL_SUCCESS;
00089     uint32_t index = 0;
00090     memset(ReadBuffer, 0, biggestSectorSize);
00091 
00092     status = pal_internalFlashRead(biggestSectorSize, address, ReadBuffer);
00093     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00094     for(index = 0; index < biggestSectorSize; index++)
00095     {
00096         if(*((uint8_t*)ReadBuffer + index) != 0xFF)
00097         {
00098             status = pal_internalFlashErase(address, size);
00099             TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00100             break;
00101         }
00102 
00103     }
00104 #endif
00105 }
00106 
00107 /*! \brief Basic read write & erase tests
00108  *
00109 ** \test
00110 * | # |    Step                        |   Expected  |
00111 * |---|--------------------------------|-------------|
00112 * | 1 | Check if Sector A and B are erased                               |             |
00113 * | 2 | Read sector A & B and compare them to 0xFF (erased sector)       | PAL_SUCCESS |
00114 * | 3 | Run Write tests See function for more details                    | PAL_SUCCESS |
00115 * | 4 | Run Read tests See function for more details                     | PAL_SUCCESS |
00116 * | 5 | fill sector B with provided Data (full sector write)             | PAL_SUCCESS |
00117 * | 6 | Read full sector and compare                                     | PAL_SUCCESS |
00118 * | 7 | Delete Sector one                                                | PAL_SUCCESS |
00119 * | 8 | Read and verify that sector two in not changed                   | PAL_SUCCESS |
00120 * | 9 | Delete Sector two                                                | PAL_SUCCESS |
00121 * | 10 | read compare both sectors to 0xff (verify erased)               | PAL_SUCCESS |
00122 */
00123 TEST(pal_internalFlash, BasicTest)
00124 {
00125 #if PAL_USE_INTERNAL_FLASH
00126     palStatus_t status = PAL_SUCCESS;
00127     /*1*/
00128     SectorDeleteValidity(areaOneData.address, areaOneData.size);
00129     SectorDeleteValidity(areaTwoData.address, areaTwoData.size);
00130 
00131     memset(compareBuffer, 0xFF, biggestSectorSize);
00132     memset(ReadBuffer, 0, biggestSectorSize);
00133 
00134     /*2*/
00135     DEBUG_PRINT("Read both sectors and compare to 0xFF \n\r");
00136     status = pal_internalFlashRead(biggestSectorSize, areaOneData.address, ReadBuffer);
00137     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00138     TEST_ASSERT_EQUAL_UINT8_ARRAY((uint8_t *)ReadBuffer, (uint8_t *)compareBuffer, biggestSectorSize);
00139 
00140     status = pal_internalFlashRead(biggestSectorSize, areaTwoData.address, ReadBuffer);
00141     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00142     TEST_ASSERT_EQUAL_UINT8_ARRAY((uint8_t *)ReadBuffer, (uint8_t *)compareBuffer, biggestSectorSize);
00143 
00144     /*3*/
00145     status = InternalFlashWriteTest(areaOneData.address);
00146     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00147     /*4*/
00148     status = InternalFlashReadTest(areaOneData.address + 2 * LITTLE_BUFFER_SIZE);
00149     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00150 
00151 
00152     DEBUG_PRINT("---------FULL SECTOR TEST---------\n\r");
00153     for (uint32_t i = 0; i < biggestSectorSize; i++)
00154     {
00155         ((uint8_t *)compareBuffer)[biggestSectorSize - i - 1] = (uint8_t)(i % 256);
00156     }
00157     DEBUG_PRINT("Write data to second sector\n\r");
00158     /*5*/
00159     status = pal_internalFlashWrite(biggestSectorSize, areaTwoData.address, compareBuffer);
00160     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00161 
00162     /*6*/
00163     memset(ReadBuffer, 0, biggestSectorSize);
00164     DEBUG_PRINT("Read and compare from second sector\n\r");
00165     status = pal_internalFlashRead(biggestSectorSize, areaTwoData.address, ReadBuffer);
00166     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00167     TEST_ASSERT_EQUAL_UINT8_ARRAY((uint8_t *)ReadBuffer, (uint8_t *)compareBuffer, biggestSectorSize);
00168 
00169     /*7*/
00170     DEBUG_PRINT("Delete sector one\n\r");
00171    status = pal_internalFlashErase(areaOneData.address, areaOneData.size);
00172    TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00173 
00174    /*8*/
00175     DEBUG_PRINT("Verify that sector 2 was not changed in sector one erasing\n\r");
00176     status = pal_internalFlashRead(biggestSectorSize, areaTwoData.address, ReadBuffer);
00177     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00178     TEST_ASSERT_EQUAL_UINT8_ARRAY((uint8_t *)ReadBuffer, (uint8_t *)compareBuffer, biggestSectorSize);
00179 
00180     /*9*/
00181     DEBUG_PRINT("Delete sector two\n\r");
00182    status = pal_internalFlashErase(areaTwoData.address, areaTwoData.size);
00183    TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00184 
00185    /*10*/
00186    memset(compareBuffer, 0xFF, biggestSectorSize);
00187    DEBUG_PRINT("Read both sectors and compare to 0xFF (verify that erase is done)\n\r");
00188     status = pal_internalFlashRead(biggestSectorSize, areaOneData.address, ReadBuffer);
00189     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00190     TEST_ASSERT_EQUAL_UINT8_ARRAY((uint8_t *)ReadBuffer, (uint8_t *)compareBuffer, biggestSectorSize);
00191 
00192     status = pal_internalFlashRead(biggestSectorSize, areaTwoData.address, ReadBuffer);
00193     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00194     TEST_ASSERT_EQUAL_UINT8_ARRAY((uint8_t *)ReadBuffer, (uint8_t *)compareBuffer, biggestSectorSize);
00195 #else
00196     TEST_IGNORE_MESSAGE("Ignored, PAL_USE_INTERNAL_FLASH no set");
00197 #endif
00198 }
00199 
00200 
00201 
00202 /*! \brief Write tests to internal Flash with different sizes
00203 *
00204 ** \test
00205 * | # |    Step                        |   Expected  |
00206 * |---|--------------------------------|-------------|
00207 * | 1 | Write Data to sector from align address and up to prime number, prime number will never divide in page size     | PAL_SUCCESS |
00208 * | 2 | Read & compare Data up to prime number                                                                          | PAL_SUCCESS |
00209 * | 3 | Write Data from  next align address from the prime number up to buffer size                                     | PAL_SUCCESS |
00210 * | 4 | Read & compare Data from prime number and up to end of buffer                                                   | PAL_SUCCESS |
00211 */
00212 
00213 
00214 palStatus_t InternalFlashWriteTest(uint32_t address_offset)
00215 {
00216 #if PAL_USE_INTERNAL_FLASH
00217     palStatus_t status = PAL_SUCCESS;
00218 
00219     uint32_t alignPage = pal_internalFlashGetPageSize();
00220 
00221     TEST_ASSERT_NOT_EQUAL(alignPage, 0);
00222 
00223     DEBUG_PRINT("---------WRITE TEST---------r\n\r");
00224     memset(compareBuffer, 0xFF, biggestSectorSize);
00225     memset(ReadBuffer, 0, biggestSectorSize);
00226 
00227     for (uint32_t i = 0; i < PRIME_NUMBER_FOR_TESTING; i++)
00228     {
00229         compareBuffer[i] = (uint8_t)(i % 256);
00230     }
00231     /*1*/
00232     DEBUG_PRINT("Write data to First Sector up to PRIME_NUMBER_FOR_TESTINGr\n\r");
00233     status = pal_internalFlashWrite(PRIME_NUMBER_FOR_TESTING, address_offset, compareBuffer);
00234     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00235 
00236     /*2*/
00237     DEBUG_PRINT("Read and compare from first sector\n\r");
00238     status = pal_internalFlashRead(PRIME_NUMBER_FOR_TESTING, address_offset, ReadBuffer);
00239     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00240     TEST_ASSERT_EQUAL_UINT8_ARRAY((uint8_t *)ReadBuffer, (uint8_t *)compareBuffer, PRIME_NUMBER_FOR_TESTING);
00241 
00242     for (uint32_t i = PRIME_NUMBER_FOR_TESTING; i < LITTLE_BUFFER_SIZE / 4 ; i++)
00243     {
00244         compareBuffer[i] = (uint32_t)(i % 256);
00245     }
00246 
00247     /*3*/
00248     uint32_t offset = PRIME_NUMBER_FOR_TESTING - (PRIME_NUMBER_FOR_TESTING % alignPage) + alignPage;
00249     DEBUG_PRINT("Write data to First Sector from PRIME_NUMBER_FOR_TESTING up to LITTLE_BUFFER_SIZE\n\r");
00250     status = pal_internalFlashWrite(LITTLE_BUFFER_SIZE - offset, address_offset + offset, compareBuffer + offset / 4);
00251     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00252 
00253     /*4*/
00254     DEBUG_PRINT("Read and compare from first sector\n\r");
00255     status = pal_internalFlashRead(LITTLE_BUFFER_SIZE - offset, address_offset + offset, ReadBuffer + offset / 4);
00256     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00257     TEST_ASSERT_EQUAL_UINT8_ARRAY((uint8_t *)ReadBuffer + offset, (uint8_t *)compareBuffer + offset, LITTLE_BUFFER_SIZE - offset);
00258 
00259 #else
00260     TEST_IGNORE_MESSAGE("Ignored, PAL_USE_INTERNAL_FLASH no set");
00261 #endif
00262     return PAL_SUCCESS;
00263 }
00264 
00265 
00266 /*! \brief read tests with different sizes
00267  * *
00268 ** \test
00269 * | # |    Step                        |   Expected  |
00270 * |---|--------------------------------|-------------|
00271 * | 1 | Write data to sector                                | PAL_SUCCESS |
00272 * | 2 | Read data in chunks of bytes and compare            | PAL_SUCCESS |
00273 */
00274 
00275 palStatus_t InternalFlashReadTest(uint32_t address_offset)
00276 {
00277 #if PAL_USE_INTERNAL_FLASH
00278     palStatus_t status = PAL_SUCCESS;
00279 
00280     DEBUG_PRINT("---------READ TEST---------r\n\r");
00281     memset(compareBuffer, 0xFF, biggestSectorSize);
00282     memset(ReadBuffer, 0, biggestSectorSize);
00283     for (uint32_t i = 0; i < LITTLE_BUFFER_SIZE / 4; i++)
00284     {
00285         ReadBuffer[i] = (uint32_t)(i % 256);
00286     }
00287     /*1*/
00288     DEBUG_PRINT("Write data to Sector up to LITTLE_BUFFER_SIZE\n\r");
00289     status = pal_internalFlashWrite(LITTLE_BUFFER_SIZE, address_offset, ReadBuffer);
00290     TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00291 
00292     /*2*/
00293     DEBUG_PRINT("Read and compare\n\r");
00294     for (uint32_t i = 0; i < LITTLE_BUFFER_SIZE / 4; i++)
00295     {
00296         uint32_t value = 0;
00297         status = pal_internalFlashRead(1, address_offset + i, &value);
00298         TEST_ASSERT_EQUAL_HEX(status, PAL_SUCCESS);
00299         TEST_ASSERT_EQUAL_HEX(*((uint8_t *)ReadBuffer + i), (uint8_t)value);
00300     }
00301 
00302 #else
00303     TEST_IGNORE_MESSAGE("Ignored, PAL_USE_INTERNAL_FLASH no set");
00304 #endif
00305     return PAL_SUCCESS;
00306 }
00307 
00308 /*! \brief Negative tests to verify validations and errors
00309  *
00310 ** \test
00311 * | # |    Step                        |   Expected  |
00312 * |---|--------------------------------|-------------|
00313 * | 1 | Delete sector with unaligned address                                | PAL_ERR_INTERNAL_FLASH_SECTOR_NOT_ALIGNED |
00314 * | 2 | Write with null ptr has buffer                                      | PAL_ERR_INTERNAL_FLASH_CROSSING_SECTORS |
00315 * | 3 | write with address not align to page size                           | PAL_ERR_INTERNAL_FLASH_ADDRESS_NOT_ALIGNED |
00316 * | 4 | write to unaligned buffer                                           | PAL_ERR_INTERNAL_FLASH_BUFFER_ADDRESS_NOT_ALIGNED |
00317 */
00318 
00319 TEST(pal_internalFlash, NegativeTest)
00320 {
00321 #if PAL_USE_INTERNAL_FLASH && defined(DEBUG)
00322     palStatus_t status = PAL_SUCCESS;
00323     uint8_t alignPage = pal_internalFlashGetPageSize();
00324     uint32_t * ReadBuffer1 = NULL;
00325     TEST_ASSERT_NOT_EQUAL(alignPage, 0);
00326 
00327     /*1*/
00328     status = pal_internalFlashErase(areaOneData.address + 4, areaOneData.size);
00329     TEST_ASSERT_EQUAL_HEX(status, PAL_ERR_INTERNAL_FLASH_SECTOR_NOT_ALIGNED);
00330 
00331     /*2*/
00332     status = pal_internalFlashWrite(areaOneData.size * 2, areaOneData.address, ReadBuffer1);
00333     TEST_ASSERT_EQUAL_HEX(status, PAL_ERR_INTERNAL_FLASH_NULL_PTR_RECEIVED);
00334 
00335     /*3*/
00336     if( pal_internalFlashGetPageSize() > 1)
00337     {//This test only valid if page size is bigger then 1
00338         status = pal_internalFlashWrite(8, (uint32_t)4, (uint32_t*)&ReadBuffer1);
00339         TEST_ASSERT_EQUAL_HEX(status, PAL_ERR_INTERNAL_FLASH_ADDRESS_NOT_ALIGNED);
00340     }
00341 
00342     /*4*/
00343     status = pal_internalFlashWrite(8 , areaOneData.address + alignPage + 1, (uint32_t*)0x11);
00344     TEST_ASSERT_EQUAL_HEX(status, PAL_ERR_INTERNAL_FLASH_BUFFER_ADDRESS_NOT_ALIGNED);
00345 #else
00346     TEST_IGNORE_MESSAGE("Ignored, PAL_USE_INTERNAL_FLASH no set or DEBUG not defined");
00347 #endif
00348 }
00349