Em_EEPROM Functions Not Performed Correctly when EEPROM Data Is Corrupted - KBA228069
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
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:
|
|
|
|
|
|
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; } |