|
Хранение указателя на конец данных в AT45xx DataFlash, Как лучше организовать? |
|
|
|
Jan 20 2008, 19:22
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Прибор должен сохранять лог измеряемых данных в DataFlash 32Мбит в худшем случае каждые 3 секунды по одной или несколько строк из 16 байт. Работа прибора непрерывная с непредсказуемыми перерывами (может вкл./выкл. в любое время с любой частотой). Батарейного питания на плате нет. Срок жизни прибора лет 10 (может и больше  ). Где лучше хранить указатель на конец данных и как это все получше организовать? Посколько DataFlash не позволяет писать меньше страницы в 512 байт, то планирую кешировать данные в буфере. При кешировании указатель будет в ОЗУ. При сохранении страницы во флеш и при вкл/выкл прибора действия могут быть разными. Придумал два варианта: 1. Сохранять указатель в одной ячейке EEPROM AVR только при выкл. прибора, а при вкл. грузить его в ОЗУ и с ним работать. + простота алгоритма - проблема в случае сбоя записи при выкл.: нужно искать конец данных в 32Мбит DataFlash 2. Сохранять указатель в циклическом буфере ячеек EEPROM не только при выкл. прибора, но и при записи страницы во флеш. Циклический буфер указателей нужен из-за малого ресурса перезаписи у EEPROM. - сложности с организацией циклического буфера указателей + всегда можно будет найти предыдущий указатель и конец данных. Какие есть еще варианты и соображения?
|
|
|
|
|
Jan 20 2008, 20:06
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Давно использую в приборе для архива 45DB021. Тоже все начиналось с кеша в буфере DBшки (по выключению питания сливал его во флеш, пока еще от емкостей жил). Указатель не хранил, а просто при заполнении буфера стирал следующую страницу и писал текущую. При старте искал страницу из 0xFF, потом не из 0xFF и считал ее за начало. Благо командой сравнения буфера и собственно флеша сделать это можно быстро. Но вот незадача - начали поступать рекламации на некоторые приборы, что выключаешь питание, включаешь - нет событий последних (не сливало кеш). Решил вопрос следующим образом. Страница очищается, а затем каждый раз в буфере создается нужная запись (на нужном месте), а остальное заполняется 0xFF и затем делается запись без стирания. Запись происходит из 1 в 0, т.е. новые данные флеш=старые данные and данные в буфере. В результате ресурс ячеек тот-же, что и с кешированием, а запись происходит непосредственно. Теперь нареканий нет  Правда, идея с такой разделенной записью непосредственно в даташите не описана. Я сначала поставил эксперимент, а потом, напуганый коллегами (типа, нет в даташите, не будет работать  ) отыскал в каком-то апноте Atmel'а такой алгоритм. Только нифига не помню в каком. Но точно был.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Jan 20 2008, 20:59
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(Aesthete Animus @ Jan 20 2008, 22:06)  Вот только не уверен, хватит даже в этом случае еепрома на 10 лет. Это я прикинул. Почти крайний случай - запись страницы раз в минуту. Год = 365*24*60=525600 минут. За 10 лет = 5.5 млн.записей / 10^5 (ресурс EEPROM)= 55 раз Буфер из 64 указателей выдерживает такую нагрузку. Только вот сразу проблемы с алгоритмом: - Как менять ячейку (по какому алгоритму) - Как запоминать её (указатель на указатель  ) Просто тупо искать среди них самый последний (по величине)?? Цитата(Rst7 @ Jan 20 2008, 22:06)  Давно использую в приборе для архива 45DB021. ... Правда, идея с такой разделенной записью непосредственно в даташите не описана. Объемы флешки у вас не те. В 2Мбитах можно и каждый раз искать, у меня 32М. А запись в предварительно очищенную страницу нынче штатный режим, я так и собираюсь делать, поскольку время Стирание/Запись 17-40 мс, а просто Запись 3-6 мс. з.ы. Тут еще сообразил, что это в режиме логгера мне нужен только указатель на конец данных, а в режиме буферной/аварийной памяти при пропадении канала связи флешка должна сама быть кольцевым буфером. Т.е. мне еще нужен и указатель на начало данных
|
|
|
|
|
Jan 20 2008, 22:02
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(Alex B._ @ Jan 20 2008, 23:18)  ...(не допускать, чтобы середина записи попадала на границу страницы) - а это потерянный объем...
Второй момент - если уже пошло кольцо ... У меня строки по 16 байт, кратно размеру страницы, проблем тут не вижу. Реализация кольцевого буфера тоже не вызывает вопросов, такое делал, ничего сложного - два указателя, один догоняет другого Вопрос не в этом, а в том, где и как сохранять эти указатели при вкл/выкл прибора и нужно ли их вообще сохранять - может быть проще каждый раз искать границы данных "роясь" во флешке. Цитата(singlskv @ Jan 20 2008, 23:24)  Скорость поиска в 32Мбит всего лишь в 4 раза дольше чем в 2Мбит флешке... Тока при производстве нужно стирать всю флешку... Я понимаю, что можно искать, например, методом "деления отрезка пополам" и кол-во шагов при этом будет не очень большим. НО: это все же ВНЕШНЯЯ SPI флешка, доступ к ней довольно длительный
|
|
|
|
|
Jan 21 2008, 06:25
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата Объемы флешки у вас не те. В 2Мбитах можно и каждый раз искать, у меня 32М. А сколько времени Вы готовы потратить на поиск? Я ж говорю, надо искать коммандой "Main Memory Page to Buffer Compare", это у меня 200мкс. Щас под рукой pdf'а на 32хмегабитную нет, но если данные такие же, то поиск займет 8192 страниц*200мкс=1.6секунды. Если это много, тогда конечно хранить указатели. Цитата Я понимаю, что можно искать, например, методом "деления отрезка пополам" Если будете организовывать кольцевой буфер, то не выстрелит. Потому как дырка может быть в любом месте.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Jan 21 2008, 08:02
|

Знающий
   
Группа: Свой
Сообщений: 943
Регистрация: 6-07-04
Из: Санкт-Петербург
Пользователь №: 274

|
Цитата(Baser @ Jan 21 2008, 01:02)  У меня строки по 16 байт, кратно размеру страницы, проблем тут не вижу. Реализация кольцевого буфера тоже не вызывает вопросов, такое делал, ничего сложного - два указателя, один догоняет другого Вопрос не в этом, а в том, где и как сохранять эти указатели при вкл/выкл прибора и нужно ли их вообще сохранятьвы знаете, что такое связанный список? в каждой записи хранится указатель на предыдущую и указатель на последующую запись. У головы списка указатель на предыдущую равен 0, у хвоста - указатель на следующую равен 0. Таким образом перебором всех записей можно найти первую и последнюю. НО! для реализации лога во флешке такой вариант не надежен - если самые старые записи начали затираться новыми, при сохранении последней записи нужно модифицировать следующую (которая станет головой списка). Если вы при этом рубанется питание, а голова находится в следующем секторе и вы не успели его модифицировать, гарантированное начало списка вы скорей всего не найдете. Поэтому лучше каждой записи присваивать порядковый номер, на единицу больший предыдущей. Диапазон должен быть больше максимального количества записей, чтобы не было двойного переполнения. В этом случае всегда можно найти начало и конец списка при любых конфликтах. Естественно, если требуется удалять записи в середине списка такой метод не прокатит. Опять же, сложно будет организовать чтение произвольной записи, но для лога этого обычно не нужно. Хранить указатели на начало и конец где-то в другом месте не разумно. А поиск действительно делается в течении ~1-2 секунд при включении устройства. У меня еще каждая запись имеет CRC, поэтому чуть дольше. И не стоит закладываться на фиксированный размер записи, сделайте универсальное решение.
|
|
|
|
|
Jan 21 2008, 09:25
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(defunct @ Jan 21 2008, 02:29)  NVRAM (с RTC) ставить нет смысла для одной функции. А чем принципиально отличается сохранение указателя от сохранения порядкового номера записи? Цитата(Rst7 @ Jan 21 2008, 08:25)  А сколько времени Вы готовы потратить на поиск? Я ж говорю, надо искать коммандой "Main Memory Page to Buffer Compare", это у меня 200мкс. Щас под рукой pdf'а на 32хмегабитную нет, но если данные такие же, то поиск займет 8192 страниц*200мкс=1.6секунды. Если это много, тогда конечно хранить указатели. Если будете организовывать кольцевой буфер, то не выстрелит. Потому как дырка может быть в любом месте. Глобально я еще взаимодействие всех функц.блоков модуля при старте не прорабатывал, так что насчет времени поиска ничего сказать не могу. Секунда, наверное, будет не критична. Но непонятно, а как вы предлагаете искать при помощи "Main Memory Page to Buffer Compare"? С чем сравнивать? Методом "деления отрезка пополам" для кольцевого FIFO, конечно, не годится  . Это я для случая фиксированного начала записи говорил. Цитата(Alex B._ @ Jan 21 2008, 10:02)  вы знаете, что такое связанный список? ... Хранить указатели на начало и конец где-то в другом месте не разумно. А поиск действительно делается в течении ~1-2 секунд при включении устройства. Для моего случая связанные списки не нужны. У меня линейная структура записей (FIFO). Никакого перемешивания быть не может. з.ы. нужно прикинуть алгоритм и время поиска. Если уложусь в ~1 сек, то это будет проще чем EEPROM ( ???)
|
|
|
|
|
Jan 21 2008, 09:31
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата для поиска свободного сектора требуется чтение и анализ 12 секторов ( 2^12=4096) Расскажите, как использовать бинарный поиск, если организован кольцевой буфер и дырка (т.е. начало и конец) где-то в середине? Цитата Но непонятно, а как вы предлагаете искать при помощи "Main Memory Page to Buffer Compare"? С чем сравнивать? У вас конец буфера маркируется пустым сектором из одних 0xFF. Т.е. реальная емкость буфера колеблется от (N-2)/sizeof(Record) до (N-1)/sizeof(Record) - как минимум, один сектор всегда пустой. Сравнивать конечно с буфером, заполненым 0xFF
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Jan 21 2008, 11:01
|

Знающий
   
Группа: Свой
Сообщений: 943
Регистрация: 6-07-04
Из: Санкт-Петербург
Пользователь №: 274

|
Цитата(Baser @ Jan 21 2008, 12:25)  А чем принципиально отличается сохранение указателя от сохранения порядкового номера записи? Я ж вам написал: если старые записи затираются новыми, то если использовать связанный список, нужно модифицировать следующую запись, указывать что она первая. Если эта запись находится в другом секторе, но нужно сначала сохранить текущий, а потом считать-изменить-сохранить другой. Есть вероятность что может пропасть питание между сохранением текущего и модификацией следующего сектора. Это все, финиш, начала и конца вы не найдете. Вариант с пустым сектором как маркером конца мне тоже не нравится - потому что придется записи сохранять по границе сектора (ну а запись может быть чуть больше половины сектора - какой овехед получается) и опять же никто не гарантирует что не пропадет питание... С индексом записи (который в каждой записи и хранится) таких проблем не будет. Когда бы не пропало питание вы всегда сможете найти начало и конец, даже если текущий буфер сектора будет потерян. А алгоритм поиска прост - перебираете все записи, вычисляете CRC, контролируете индексы. Это же сделать надо один раз при включении питания, дальше указатели храняться в ОЗУ
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|