Как защитить SD-карту от неожиданных сбоев питания?

18

Я работаю на устройстве, которое использует библиотеку Microchip MDDFS для хранения данных на SD-карту. Регистратор будет регистрировать данные с максимальной скоростью 1 запись (56 байт) каждую минуту. Проблема в том, что устройство может потерять питание в любое время, возможно, в середине последовательности записи. Мне интересно, как лучше защитить мои данные от коррупции. Я обнаружил, что если файл открыт при отключении питания, все данные, которые были записаны в файл после последнего закрытия файла, теряются. Я не знаю, верно ли то же самое, если мощность теряется в середине последовательности записи.

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

Другим подходом может быть сохранение файла открытым, но после каждых 10 или 50 операций записи я могу закрыть файл, а затем снова открыть его.

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

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

В любом случае, что бы вы предложили, ребята?

PICyourBrain
источник
2
Если вы переключились на необработанную флэш-память NAND с минимальной файловой системой, вы могли бы пройти сквозь многие уровни абстракции, которые в настоящее время препятствуют вашей способности совершать небольшие записи, и, вероятно, получить возможность выполнять частичную запись блоков сразу, как только данные станут доступны. У вас также будет защита от замены конечным пользователем карты с другими характеристиками производительности (может быть, даже незначительной для серого рынка) в будущем.
Крис Страттон

Ответы:

16

Когда вы записываете данные в файл, может произойти несколько вещей. Я собираюсь описать последовательность, которая должна произойти, чтобы данные были безопасными, а не обязательно библиотечными вызовами.

Когда вы пишете и добавляете в конец файла (обычный режим записи), вы считываете последний блок файла в память, модифицируете его данными записи, а затем записываете весь блок обратно на SD-карту. , Если блок заполнен, то в таблице размещения файлов (FAT) должен быть найден новый блок. После нахождения нового блока необходимо обновить FAT, что является циклом чтения-изменения-записи. Если мы закончили с файлом, то нам нужно обновить атрибуты файла (например, длину файла) в корневом каталоге, что вызовет еще один цикл чтения-изменения-записи.

Минимизация вашего времени записи

  • Убедитесь, что файл уже содержит ваши данные, когда вы пишете сектор. Если вы начинаете с большого файла и перезаписываете данные вместо добавления данных, данные будут в безопасности, как только закончится запись в сектор SD-карты. Таким образом вы можете исключить от одного до двух циклов чтения-изменения-записи. Мой стартовый код будет записывать 0 в файл с приращением сектора до тех пор, пока SD-карта не будет заполнена, а затем перематывать назад в начало файла.

  • Сделайте размер ваших записей данных таким, чтобы целое число записей вписывалось в сектор. Я бы увеличил ваши записи до 64 байтов. Хотя это менее эффективно, это избавит вас от необходимости чтения-изменения-записи двух секторов.

  • Создайте вариант функции FSwrite, которая позволяет записывать целые сектора. Если вы сохраняете весь сектор в SRAM, то ваш цикл переходит от «чтение-изменение-запись» к «изменение-запись»

Поддерживайте питание PIC и SD как можно дольше

  • Большие конденсаторы хороши. 470 мкФ должно дать вам более чем достаточно энергии для завершения цикла записи.

  • Убедитесь, что ваш источник питания не будет высасывать энергию из резервного конденсатора! Добавьте диод при необходимости.

Знай, когда у тебя нет власти

  • Большая крышка блока питания даст вам 10 мс или больше, чтобы обернуть вещи с SD-картой, но не теряйте удачу. Используйте булавку на своем микроконтроллере, чтобы увидеть, исправен ли ваш источник питания, и не начинайте запись, если ваш источник мертв.
W5VO
источник
Спасибо за информацию. Очень полезно. Я посмотрю, что я могу с этим сделать ...
PICyourBrain
Как вы думаете, сколько времени потребуется, чтобы записать все нули на карту 4 ГБ? Кажется, давно. Кроме того, есть ли у вас примеры кода, которыми вы могли бы поделиться для изменения функции fswrite, чтобы разрешить целые записи во все сектора?
PICyourBrain
Кроме того, если вы записываете все нули в файл. Как вы отслеживаете, где конец ваших фактических данных? Вы только что прочитали все данные в начале и нашли строку нулей?
PICyourBrain
1
Если вы используете FAT16, я считаю, что вы ограничены 2 ГБ. Я считаю, что карта SD / MMC имеет функцию «стирания блоков», которая, по-видимому, не реализована в библиотеке MDDFS. Я использовал проприетарную библиотеку кодов для своего проекта SD-карты, поэтому не могу поделиться примерами кода. Чтобы найти последние данные, вам нужно будет прочитать, пока вы не найдете все 0 в записи данных. Если ваша запись данных может иметь все 0, я бы посоветовал добавить некоторые ненулевые данные или разделитель некоторых типов.
W5VO
6

Одна проблема, еще не упомянутая с SD-картами (или MMC, CompactFlash и т. Д.), Заключается в том, что хотя SD-карта может отображаться на хосте как простая коллекция из 512-байтовых секторов, которые могут быть прочитаны и записаны в произвольном порядке, устройства флэш-памяти обычно храните 528-байтовые страницы в группах по 32 КБ, если не больше каждой, и единственные поддерживаемые операции - это либо запись на пустую страницу, либо удаление всей группы. Чтобы справиться с этим ограничением, контроллер на SD-карте будет хранить таблицу, которая позволит сопоставить любой логический сектор с любой физической страницей. Когда делается запрос на запись сектора, контроллер найдет пустую страницу где-то на чипе и обновит отображение новым адресом рассматриваемого сектора. Если пустых страниц становится мало, или в другое время,

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

Чтобы быть уверенным, даже если SD-карта абсолютно идеальна с точки зрения обеспечения того, что каждая операция записи, о которой было сообщено, что она была завершена, фактически переживет сбой питания (т. Е. Гарантирует, что при выполнении всех операций записи было бы вызвано завершено, достаточно выполнено, чтобы карта завершила операцию при повторном включении питания), что не означает, что операционная система хоста не будет иметь проблем, если она выполнит некоторые, но не все записи данных, которые она намеревается. Тем не менее, важно иметь в виду, что, если SD-карта не может удержать конец своей «сделки», в программном обеспечении на стороне хоста ничего нельзя сделать, чтобы предотвратить потерю данных из-за сбоя питания.

Supercat
источник
Это очень проницательный комментарий.
Фред Бассет
5

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

sybreon
источник
3

Возможно, этот суперконденсатор в Sparkfun решит проблему.

pingswept
источник
2
Он будет хранить память PIC, но у него максимальный ток 10 мкА. Я не думаю, что вы могли бы написать на SD-карту на такой большой ток.
W5VO
1
Концепция хорошая, хотя. Быстрый поиск показал, что Иллинойский конденсатор ( illinoiscapacitor.com ) имеет суперконденсатор до 8 F и способен поддерживать токи до 4 A. Добавление одного из них или батареи даст микро возможность завершить запись и завершить работу хорошо, если основной источник питания вышел из строя.
Фотон
3

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

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

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

Дж. Полфер
источник
1

Если вы хотите просто хранить данные, вам не нужна файловая система. Операция записи будет выполнена непосредственно через SPI, выбрав адрес блока. тем самым вы минимизируете время записи и риск повреждения данных.

Даже в случае потери питания и неудачи вы потеряете только одну запись (что может быть приемлемо в некоторых системах).

mba7
источник