Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: А кто как организует в своих программах контроль завершённости
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Дон Амброзио
А кто как организует в своих программах контроль завершённости транзакции обновления базы данных во внутренней EEPROM или во внутренней FLASH микроконтроллеров ATmega? И кто как реализует откат назад в случае если обнаруживается, что предыдущая транзакция была прервана(не завершена)..А?
Aesthete Animus
Что-то я плохо понял суть вопроса, не похоже, что на него ожидается ответ. Уж не продолжение ли это "апрельских" тезисов?
Дон Амброзио
Цитата(Aesthete Animus @ Mar 27 2008, 16:52) *
Что-то я плохо понял суть вопроса

И хорошо.. Кто "в теме" - тот поймёт.. А от тех кто не "в теме" мне ответы не нужны
Непомнящий Евгений
В епром использую следующий механизм:
Группа параметров хранится в пакете. Пакет имеет CRC и флаг актуальности.
Для одной и той же группы параметров в епроме выделено место для нескольких пакетов (мимнимум 2).
При записи самый неактуальный пакет перетирается. Если при этом произошла ошибка - то при последующем чтении CRC пакета будет неверное и система будет считать, что тут "пусто"; данные будут прочитаны из последнего актуального пакета. При следующей записи такой неудачный пакет будет затерт новым.
Вот примерно так...
Дон Амброзио
Цитата(Непомнящий Евгений @ Mar 27 2008, 17:12) *
При записи самый неактуальный пакет перетирается. Если при этом произошла ошибка - то при последующем чтении CRC пакета будет неверное и система будет считать, что тут "пусто"; данные будут прочитаны из последнего актуального пакета. При следующей записи такой неудачный пакет будет затерт новым.
Вот примерно так...

А где же тут "откат"? Т.е. возврат к предыдущемц "хорошему" состоянию в случае если произошёл аборт во время записи и запись была сорвана (например, питалово вырубили)?
Непомнящий Евгений
Вот тут:
Цитата
Если при этом произошла ошибка - то при последующем чтении CRC пакета будет неверное и система будет считать, что тут "пусто"; данные будут прочитаны из последнего актуального пакета.
galjoen
Пользую примерно такой-же способ как 'Непомнящий Евгений'. Только у меня не "флаг актуальности", а счётчик (2 байта). У кого он больше, тот пакет и последний. Ещё по теме хочу сказать, что длина пакета в EEPROM д.б. кратна 8 и начинаться он должен с адреса кратного 8. Я к такому выводу пришёл, когда у меня 8 байт в EEPROM объFFились. Видимо в EEPROM всё таки какие-то блоки 8 байтные имеются.
Дон Амброзио
Цитата(galjoen @ Mar 27 2008, 20:45) *
Видимо в EEPROM всё таки какие-то блоки 8 байтные имеются.

Да нет наверное....
Это скорей всего потому у Вас 8-ми байтный блок объFFевился потому что у Вас "пакеты" в EEPROM по 8 байт, т.е. потому что Вы пишите в EEPROM 8-ми байтными блоками
Дон Амброзио
Вот я думаю, что для возможности восстановления повреждённой записи базы данных, разрушенной по причине незавершённости транзакции, вызванной отключением питания нужно хранить каждую запись в 4-х экземплярах. Потому что если хранить в 3-х то не будет возможности восстановить запись методом мажоритарного голосования.

Рассмотрим пример с 3-мя копиями и объяснение почему 3-х копий не хватает.

Допустим мы обновляем запись в базе данных во внутренней FLASH (или EEPROM) микроконтроллера. Одну копию записи успеваем обновить полностью, а вот на середине обновления 2-й копии транзакция прерывается выключением питания.

В результате мы имеем:
1-я копия обновлена полностью
2-я копия обновлена наполовину
3-копия вообще НЕ обновлена

Как быть? Мажоритарным голосованием восстановить не получиться, т.е. у нас нет хотя бы 2-х одинаковых копий записи - все 3 копии различны. А вот если бы у нас было 4 копии, то мы бы смогли "откатить" запись на основании значений записи для 3-й и 4-й записи. А если бы, допустим, транзакция была бы прервана на середине не 2-й , а 3-й копии, то тогда мы смогли бы даже не откатывать запись, а продолжить и завершить транзакцию, взяв данные совпадающих между собой 1-й и 2-й копий
Непомнящий Евгений
Цитата(galjoen @ Mar 27 2008, 20:45) *
Только у меня не "флаг актуальности", а счётчик (2 байта). У кого он больше, тот пакет и последний.

На самом деле достаточно одного бита. Актуальный пакет находится "по переходу". Пример:
Код
Пакеты    П1    П2    П3
Флаг        1    1    0 Актуальный  - П2

Пакеты    П1    П2    П3
Флаг        1    1    1 Актуальный  - П3

Пакеты    П1    П2    П3
Флаг        0    1    1 Актуальный  - П1

и т.д.

В вашем случае получается примерно также, но вместо 1 бита вы храните 2 байта. Однако счетчик вероятно все равно может перескочить через 0 и вы получите тоже, что и у меня...

Цитата(Дон Амброзио @ Mar 28 2008, 06:15) *
Вот я думаю, что для возможности восстановления повреждённой записи базы данных, разрушенной по причине незавершённости транзакции, [...]

У меня (см пример выше) П1, П2 и П3 - это НЕ КОПИИ. Это разные версии информации одного типа. Для верхнего примера П3 - самая младшая версия (из имеющихся), затем П1, затем П2 - актуальная версия. Когда мне придется сохранить информацию в очередной раз, пакет П3 будет затерт. Пусть при этом произошел сбой. Это значит, что я потерял самую старую версию информации (которая мне уже все равно не нужна). При следующем чтении будет прочитан П2, а П3 определен как "пустой".
Для такой схемы нужно как минимум 2 "слота" под однотипный пакет. Чем больше "слотов" тем сильнее "размазывается" ресурс епрома (и тем медленее происходит определение актуального пакета)
blackbit
Не поверите - одним битом. Черным. wink.gif
Сколько не пытались потом выбить прибор на ходу, в момент обновления firmware или базы данных, ни у кого не получилось. Ни у своих, ни у чужих.
Дон Амброзио
Цитата(blackbit @ Mar 28 2008, 09:06) *
Не поверите - одним битом. Черным. wink.gif
Сколько не пытались потом выбить прибор на ходу, в момент обновления firmware или базы данных, ни у кого не получилось. Ни у своих, ни у чужих.


Вероятность "слёта" (т.е. случайного изменения) бита 50% (слетит или не слетит).. biggrin.gif

Так что ИМХО это ненадёжная защита...
Igor26
Цитата
50% (слетит или не слетит)..

Т.е. как у той блондинки.
- Какова вероятность, что вы встретите динозавра на улице?
-50 на 50. Или всречу, или нет.

Заливаем в ЕЕПРОМ данные хоть блоками по 1, хоть по 256 байт. Затем дожидаемся подтверждения, что данный блок успешно "лег" в ЕЕПРОМ. После этого шлем следующий блок данных. Если в течении нескольких итераций блок данных не попадает адресату, то значит нелады с получателем.
Всё. Тревожная ситуация.
Какой смысл дальше "орать" в пустоту?
Далее понятно.
Kirill Frolov
Цитата(galjoen @ Mar 27 2008, 20:45) *
Пользую примерно такой-же способ как 'Непомнящий Евгений'. Только у меня не "флаг актуальности", а счётчик (2 байта). У кого он больше, тот пакет и последний. Ещё по теме хочу сказать, что длина пакета в EEPROM д.б. кратна 8 и начинаться он должен с адреса кратного 8. Я к такому выводу пришёл, когда у меня 8 байт в EEPROM объFFились. Видимо в EEPROM всё таки какие-то блоки 8 байтные имеются.


У меня тоже счётчик. Надо сказать с ним есть непределённость определённая... Вобщем или кодов для счёта будет БОЛЬШЕ числа страниц flash для перезаписи. Или нельзя сказать чётко какая последняя. С битом -- это по-моему бред. Как там последнюю найти? Только если не удалять сразу неактуальные записи. Я вот не удаляю, стираю только при записи. А дописываю как есть по кругу (есть пул flash-страниц для циклической перезаписи). Да, когда у меня было всего 2 страницы в другом приборе, там было 2 БИТА. Ибо по 1 биту нифига непонятно кто последний в таком случае. А так есть серия номеров последовательно с разрывом (зацикленность опускаем), соответственно тот что перед разрывом -- последний. Поэтому номеров и БОЛЬШЕ должно быть чем страниц.

Да, про неопределённость. Это когда разрывов в нумерации больше одного. Тут хоть по rand() выбирай нужный блок...
Непомнящий Евгений
Цитата(Kirill Frolov @ Mar 28 2008, 22:56) *
С битом -- это по-моему бред. Как там последнюю найти? Только если не удалять сразу неактуальные записи.


см разобранный пример выше. Записи никогда не удаляю. Самая старая просто перетирается, когда надо записать новую.
Kirill Frolov
Цитата(Непомнящий Евгений @ Mar 29 2008, 11:47) *
см разобранный пример выше. Записи никогда не удаляю. Самая старая просто перетирается, когда надо записать новую.


5 раз смотрел, ничего не понял. Я знаю, что для кодировании информации выбора одного из N надо минимум log2(N)+1 битов. А тут ерунда какая-то. Напиши какие значения этого бита у 9 последовательных записей. (т.е. чистый флеш, записали раз, записали два...) Сколько кстати блоков флеша? Не больше 8-и? Если это работает, значит старые записи таки переписываются, хотя бы этот бит сбрасывается.
_Pasha
Чистая эмпирика:
1. Блоки данных с CRC16 в конце прекрасно самосинхронизируются при фиксированной длине блока.
Таким образом, достаточно отследить последний правильный кадр методом скользящего CRC.
2. При overlapping-записи в память никаких проблем не наблюдается, если длина записываемого блока нечетная (ессно, при четном размере свободного пространства памяти smile.gif, и наоборот ). Ой, поправлюсь - если размер памяти не кратен длине блока.
Судите сами - последний блок никогда не уложится в верхнюю границу, и не надо никаких дополнительных условий для того, чтобы продолжить сканировать память сначала.
Может, несколько тормознуто (всегда полное сканирование), зато без признаков искусственного интеллекта. Девайс никогда не захватит весь мир. biggrin.gif
Непомнящий Евгений
Цитата(Kirill Frolov @ Mar 29 2008, 13:06) *
Напиши какие значения этого бита у 9 последовательных записей. (т.е. чистый флеш, записали раз, записали два...) Сколько кстати блоков флеша? Не больше 8-и? Если это работает, значит старые записи таки переписываются, хотя бы этот бит сбрасывается.

Блоков ("слотов") - теоретически сколько угодно. Я обычно делаю не больше 5.

Пример (обозначение: ПS(F), где S - номер слота, F - флаг. П2(1) - пакет во втором слоте, флаг = 1)
Код
0. Начальное состояние: пусто - все слоты пусты (т.е. у каждого неверная CRC)
1. Пишем 1-й пакет: П1(1) пусто .....
2. Пишем 2-й пакет П1(1) П2(1) пусто .......
...
9. Пишем 9-й пакет: П1(1) П2(1) ......... П8(1) П9(1)
10. Пишем 10-й пакет:  П1(0) П2(1) ......... П8(1) П9(1)
11. Пишем 11-й пакет:  П1(0) П2(0) П3(1) ......... П8(1) П9(1)
...
18. Пишем 18-й пакет: П1(0) П2(0) .... П8(0) П9(0)
19. Пишем 19-й пакет: П1(1) П2(0) ..... П9(0)
и т.д.

Чтобы определить актуальный пакет, ищем первый переход 0-1 или 1-0.
Если нашли - то пакет слева от перехода и будет актуальным (случай 10 - актуален П1, 11 - П2, 19 - П1)
Если не нашли - актуален последний пакет (случаи 1-9, 18).

PS Насчет теории информации - лень доказывать, но интуитивно - для этого примера у тебя есть 9 информационных бит (частично зависимых между собой), а не 1. Причем не совсем бит - флаг может быть 1, 0 или НЕВЕРЕН (у пакета с неправильной CRC).
Т.е. получается соответствие:
1 НЕВЕРЕН ... НЕВЕРЕН = 1-й пакет
...
1 1 1 1 .. 1 = последний пакет
0 0 1 ... 1 = 2-й пакет
и т.д.
Дон Амброзио
Цитата(Igor26 @ Mar 28 2008, 12:31) *
Затем дожидаемся подтверждения, что данный блок успешно "лег" в ЕЕПРОМ.
От кого? От кого "дожидаемся подтверждения"?


Цитата(Kirill Frolov @ Mar 29 2008, 14:06) *
5 раз смотрел, ничего не понял.

Аналогично.. Галиматья какая-то
oran-be
А я делаю очень просто - при закатывании данных к ней пришивается поле с подписью. В этом поле хранится информация о версии и СРС32 всего блока данных - на всякий случай но, если честно, то пользоватся ей еще не пользовался. Это блок хранится в определенном месте.
Смеда данных происходит по следующему алгоритму.
1. Отправляется команда о смене данных. Контроллер на нее затирает заголовок текущих данных.
2. отправляются данные пакетами ( у меня по 128 байт - не хотелось использовать двухбайтный счетчик) При получении 4 пакетов образуется консенсус страницы и контроллер пишет ее и заодно верифицирует ( я еще заодно проверяю на идентичность - а вдруг ее не надо писать).
3. После успешной верификации отправляется новая подпись, которую контроллер пишет на известное место.
В случае облома в любом месте будет известно, что типа данных во флеше нет, либо они не валидны..
Дон Амброзио
Цитата(oran-be @ Mar 30 2008, 18:13) *
В случае облома в любом месте будет известно, что типа данных во флеше нет, либо они не валидны..

А как же откат?
Непомнящий Евгений
Цитата(Дон Амброзио @ Mar 30 2008, 17:00) *
Аналогично.. Галиматья какая-то

07.gif мгм. С учетом разобранного выше примера что именно кажется тебе галиматьей?
Дон Амброзио
Цитата(Непомнящий Евгений @ Mar 31 2008, 07:28) *
07.gif мгм. С учетом разобранного выше примера что именно кажется тебе галиматьей?

Извините пожалуйста... Просто я не очень разобрался как у Вас это всё работает
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.