
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
EEPROM のデータが壊れているときに Em_EEPROM 関連ファンクションが正常に動作しないことについて - KBA228069 - Community Translated (JA)
Community Translated by MoTa_728816 Version: **
状況:
PSoC® Creator™ 4.2 のプロジェクトで PSoC 3, PSoC 4, PSoC 5LP, PSoC 6 MCU デバイス用に Em_EEPROM コンポーネント v2_0, v2_10, V2_20 を 使用している場合。
ModusToolbox™ IDE プロジェクトで PSoC 6 MCU 用の Emulated EEPROM ミドルウェアを使用する psoc6sw-1.0 または psoc6sw-1.1 ライブラリを使用しているもの。
問題:
Em_EEPROM コンポーネントが書込み処理をしているときに、想定外のリセットや電源喪失によって Em_EEPROM 内のデータが破損している場合があります。このような破損したデータがある状態で Em_EEPROM コンポーネントが起動されると下記の関数が正しく機能しない場合があります。
|
原因: この問題は内部 Em_EEPROM のデータが使用前に検証(validate)されていないことによって発生します。
注意:このドキュメントで紹介されているワークアラウンドは Redundant Copy が無効になっている場合にのみ機能します。この手法はシーケンス番号を含むEm_EEPROM データヘッダーの CRC 計算と検証を実装しています。
このワークアラウンドを使用すると、Em_EEPROM は書込みと消去処理において CRC を計算して書込みを行います; CRC の検証は Init() 関数で呼ばれている FindLastWrittenRow() 関数内で行われます。
この問題の修正は他の改良と合わせて既に、ModusToolbox の PSoC 6 MCU 用 Em_EEPROM ミドルウェアに実装されています、また PSoC Creator の Em_EEPROM Component v3.0 にも実装される予定です。
ワークアラウンド:
- 1. cy_em_eeprom.c ファイルを見つけてください。 PSoC のファミリおよび コンポーネントのバージョンによって、このファイルは以下のディレクトリのどれかに置かれています:
PSoC Creator 4.2 と PSoC 3, PSoC 4, 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 と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 と 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. cy_em_eeprom.c ファイルのバックアップを作成してから、下記のようコードの中を変更してください。
注意: PSoC 4.2 と PSoC 6 MCU の cy_em_eeprom.c ファイルを編集するためにはエディタソフトウェアを管理者権限で実行する必要があります。
2.1 KBA227502 で説明されているワークアラウンドを適用してください。
2.2 Cy_Em_EEPROM_Write() 関数を修正します。下記のコードを特定してください:
/* Write the data to the specified flash row */ ret = WriteRow(emEepromRowAddr, writeRamBuffer, context); tmpRowAddr = emEepromRowAddr; |
上のステップで見つけたコードの直前に下記のコードを挿入してください。
/* 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 Cy_Em_EEPROM_Erase() 関数を修正します。下記のコードを特定してください:
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); } |
上のステップで見つけたコードの直後に下記のコードを挿入してください。
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 FindLastWrittenRow() 関数を修正します。 下記のコードを特定してください:
/* Some record in EEPROM was found. Store found sequence * number and row address. */ prevSeqNum = seqNum; *lastWrRowPtr = emEepromAddr; |
上のステップで見つけたコードを下記のコードと差し替えてください。
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; } |