Em_EEPROM Functions Not Performed Correctly when EEPROM Data Is Corrupted - KBA228069

Version 6

    Author: BennyJ_71           Version: *A

     

    Translation - Japanese: EEPROM のデータが壊れているときに Em_EEPROM 関連ファンクションが正常に動作しないことについて - KBA228069 - Community Translated (JA)

    Context: PSoC® Creator™ 4.2 project with the Em_EEPROM Component v2_0, v2_10 or v2_20, for PSoC 3, PSoC 4, PSoC 5LP, or PSoC 6 MCU devices.

    ModusToolbox™ IDE project with psoc6sw-1.0 or psoc6sw-1.1 libraries which uses the Emulated EEPROM middleware for PSoC 6 MCU.

    Issue: Data in the Em_EEPROM may be corrupted due to an unexpected reset or power loss while the Em_EEPROM Component performs the write operation. The following functions may work incorrectly when the Em_EEPROM Component is started with corrupted data:

    • Cy_Em_EEPROM_Write()
    • Em_EEPROM_Write()
    • Cy_Em_EEPROM_Erase()
    • Em_EEPROM_Erase()
    • Cy_Em_EEPROM_NumWrites()
    • Em_EEPROM_NumWrites()

    Cause: This issue occurs because the internal Em_EEPROM data is not validated before usage.

    Note: The workaround provided in this article works only when Redundant Copy is disabled. It implements calculation and check of the CRC on the Em_EEPROM data header, which contains the Sequence Number.

    With the workaround code, Em_EEPROM calculates and writes CRC on Write and Erase operations; CRC is checked in the FindLastWrittenRow() function called in the Init() function.

    Fix for this issue along with other improvements is already implemented in the Em_EEPROM middleware v2.0 for PSoC 6 MCU in ModusToolbox and will be implemented in PSoC Creator Em_EEPROM Component v3.0.

    Workaround:

    1. Find the cy_em_eeprom.c file. Depending on the PSoC family and Component version, this file is located in one of the following directories:

     

       PSoC Creator 4.2 and PSoC 3, PSoC 4, or PSoC 5LP:

    • C:\Users\<Username>\Documents\PSoC Creator\4.2\Downloads ( 4.2).cylib\Em_EEPROM_Dynamic_v2_10\API\cy_em_eeprom.c
    • C:\Users\<Username>\Documents\PSoC Creator\4.2\Downloads ( 4.2).cylib\Em_EEPROM_Dynamic_v2_20\API\cy_em_eeprom.c

     

       PSoC Creator 4.2 and  PSoC 6 MCU:

    • C:\Program Files (x86)\Cypress\PDL\3.0.4\middleware\em_eeprom\cy_em_eeprom.c
    • C:\Program Files (x86)\Cypress\PDL\3.1.0\middleware\em_eeprom\cy_em_eeprom.c

     

       ModusToolbox and PSoC 6 MCU:

    • <user_home>\ModusToolbox_1.0\libraries\psoc6sw-1.0\components\psoc6mw\em_eeprom\cy_em_eeprom.c
    • <user_home>\ModusToolbox_1.1\libraries\psoc6sw-1.1\components\psoc6mw\em_eeprom\cy_em_eeprom.c

     

    2. Create a backup for the cy_em_eeprom.c file and modify the code inside as follows.

     

         Note: You must run your our editor software with Administrator rights to modify the cy_em_eeprom.c file for PSoC Creator 4.2 and PSoC 6 MCU.

     

    2.1. Apply the workaround described in KBA227502.

     

    2.2. Modify the Cy_Em_EEPROM_Write() function. Locate lines with the following code:

    /* Write the data to the specified flash row */

    ret = WriteRow(emEepromRowAddr, writeRamBuffer, context);

    tmpRowAddr = emEepromRowAddr;

     

    Insert the following code before the lines that you located in the previous step:

     

    /* Calculate the checksum of a data header if redundant copy is disabled */

    if(0u == context->redundantCopy)

    {

    writeRamBuffer[CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET_U32] = (uint32_t)

    CalcChecksum((uint8_t *) &writeRamBuffer[0],

    CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET);

    }

     

    2.3. Modify the Cy_Em_EEPROM_Erase() function. Locate lines with the following code:

     

    if(0u != context->redundantCopy)

    {

    writeRamBuffer[CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET_U32] = (uint32_t)

    CalcChecksum((uint8_t *) &writeRamBuffer[CY_EM_EEPROM_EEPROM_DATA_OFFSET_U32],

    CY_EM_EEPROM_EEPROM_DATA_LEN);

            }

     

    and insert the following code after the lines that you located in the previous step:

     

    Else

    {

    /* Calculate the checksum of a data header if redundant copy is disabled */

    writeRamBuffer[CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET_U32] = (uint32_t)

    CalcChecksum((uint8_t *) &writeRamBuffer[0],

    CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET);

            }

     

    2.4. Modify the FindLastWrittenRow() function. Locate lines with the following code:

     

    /* Some record in EEPROM was found. Store found sequence

    * number and row address.

    */

    prevSeqNum = seqNum;

    *lastWrRowPtr = emEepromAddr;

     

    and replace the lines that you located in the previous step with following code:

     

    if((*(uint32_t *)(emEepromAddr + CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET)) ==

    ((uint32_t) CalcChecksum((uint8_t *)emEepromAddr,

    CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET)))

    {

    /* Some record in EEPROM was found. Store found sequence

    * number and row address.

    */

    prevSeqNum = seqNum;

    *lastWrRowPtr = emEepromAddr;

    }