Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob

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

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

ChaitanyaV_61
Employee
Employee
50 questions asked 25 likes received 25 sign-ins

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;

}

0 Likes
1387 Views
Contributors