Как обеспечить целостность данных в EEPROM памяти и FLASH памяти с постраничным стиранием?
============================================================================================

 Добрый день!  

  

Возникла проблема с обеспечением целостности данных при хранении данных в памяти с постраничным стиранием.  

Память AT45DB321.  

  

В частности есть устройство, которое имеет много сохраненных в памяти структур данных. Эти структуры никак не связаны друг с другом, они могут в произвольном порядке изменяться с сервера, добавляться новые, деактивироваться старые.  

И вот тут я задумался о том как быть с потенциально возможной ситуацией:  

- прилетело уведомление что нужно заменить структуру STRUCT\_N, которая находиться посереди страницы памяти MEM\_PAGE\_X,  

- я запускаю процесс перезаписи страницы (либо путем вычитки страницы в ОЗУ и заменой нужных мне данных, либо внутренними средствами микросхемы),  

- в процессе перезаписи произошел сбой питания, оно пропало (либо после стирания, либо когда данные начали грузиться в память),  

- после восстановления питания у меня получается ситуация что кроме текущей редактируемой структуры у меня пострадали еще структуры, находящиеся на той же странице что и редактируемая структура. Да, я не получил от девайса ответа что редактируемая структура была изменена и я повторю данную операцию. Но как быть с остальными данными?  

  

Проблема осложняется тем, что сервер абсолютно не владеет информацией о фрагментации памяти, на каких страницах какие структуры хранятся и т.е. я понятия не имею какие именно структуры я потерял совместно с редактируемой структурой.  

  

Посоветуйте, пожалуйста, какие меры можно предпринять чтобы избежать подобного?  

  

Один из вариантов, который я вижу (не самое интересное как по мне решение):  

- формировать на сервере прямо блоки данных (с контрольными суммами),  

- при каких-либо изменениях сначала редактируются данные на сервере, пересчитывается контрольная сумма,  

- после этого отправляется команда модификации на девайс и в ответе должна прийти контрольная сумма блока памяти девайса,  

- если совпало - то все ОК, если не совпало - грузим полный блок кода с сервера на девайс.  

  

Однако при это получается слишком сильная связь сервер-девайс, т.е. если я перешел на другую структуру памяти или другую микросхему с другим размером страницы-блока, то мне нужно и на сервере вносить изменения в алгоритм работы.  

  

Хотя с другой стороны это упростит задачу периодического контроля целостности данных, т.е. раз в N-й промежуток времени сервер просит дать ему контрольные суммы памяти и сверяет со своими данными.  

Стоит ли заморачиваться с этим? 

*А нужна ли вам вообще EEPROM при наличии коннекта к серверу?*  

У вас есть два варианта - решить проблему аппаратно, навесив конденсатор и сделав контроль внешнего питания.  

  

Или написав хитрую систему хранения по типу журналируемой фс, которая будет при старте проверять структуру блоков и, используя сквозную контрольную сумму, выявлять блок, который был недозаписан. Понятно, что развозить это все на протокол коммуникации с сервером - никуда не годная идея, устройство должно следить за своей памятью само. 

 Обверните структуры в "пакеты". Длинна структуры у вас не меняется, изменяется только содержимое. Тогда делаете примерно такой пакет:  

[МАРКЕР\_НАЧАЛА\_СТРУКТУРЫ][ДЛИННА\_СТРУКТУРЫ][ДАННЫЕ\_СТРУКТУРЫ][CRC-8\_СТРУКТУРЫ][МАРКЕР\_КОНЦА\_СТРУКТУРЫ]  

  

Изменяться у вас будет только [ДАННЫЕ\_СТРУКТУРЫ] и [CRC-8\_СТРУКТУРЫ].   

Как результат сможете легко пробежать по всей памяти, найти все структуры, сравнить crc, обнаружить битые и решать что с этим делать т.к. сможете только предсказать что вот тут явно что то не так.  

Как минус избыточный объем данных за счет маркеров, длинны и crc. Но это можно оптимизировать исходя из ваших реалий, скажем если структуры не особо длинные то [МАРКЕР\_НАЧАЛА\_СТРУКТУРЫ][ДЛИННА\_СТРУКТУРЫ] можно объединить в 1 байт вместо 2х(2-3 или 4 бита отдать под маркер а остальное под длинну).  

  

Это с ходу что в голову пришло. 

 Ваша проблема в одном : "- в процессе перезаписи произошел сбой питания, оно пропало".  

Это вопрос чисто аппаратный на уровне правильности выбранной структуры проектируемого изделия.  

Если разработчик железа не предусмотрел возможности "сообщить" ПО о проблемах с питанием и/или не  

принял мер защиты от пропадания питания на стадии проектирования, то ваши попытки исправить это   

программно вряд ли будут успешны. 

 Плюсую за решение проблемы на аппаратном уровне, в зависимости от максимальной длительности процесса перезаписи подобрать буферный источник питания.