Я работаю на устройстве, которое использует библиотеку Microchip MDDFS для хранения данных на SD-карту. Регистратор будет регистрировать данные с максимальной скоростью 1 запись (56 байт) каждую минуту. Проблема в том, что устройство может потерять питание в любое время, возможно, в середине последовательности записи. Мне интересно, как лучше защитить мои данные от коррупции. Я обнаружил, что если файл открыт при отключении питания, все данные, которые были записаны в файл после последнего закрытия файла, теряются. Я не знаю, верно ли то же самое, если мощность теряется в середине последовательности записи.
Поскольку процедура записи происходит не очень часто, я могу открыть файл, записать данные, а затем закрыть файл, каждый раз, когда данные регистрируются. Повредит ли этот подход SD-карте со временем?
Другим подходом может быть сохранение файла открытым, но после каждых 10 или 50 операций записи я могу закрыть файл, а затем снова открыть его.
Я мог бы также буферизовать данные в памяти, а затем иногда сбрасывать данные, возможно, после килобайта или около того.
Последней идеей, которую я имел, было то, что в моей схеме я мог добавить большой конденсатор, который обеспечивал бы питание моей карты Pic / SD достаточно долго после отключения питания, чтобы быстро закрыть файл. Проблема этого подхода заключается в том, что время, необходимое для закрытия файла и / или сохранения данных, очень противоречиво. Насколько я понимаю, это время может сильно зависеть от текущего места на флэш-странице, в которой находится файл.
В любом случае, что бы вы предложили, ребята?
Ответы:
Когда вы записываете данные в файл, может произойти несколько вещей. Я собираюсь описать последовательность, которая должна произойти, чтобы данные были безопасными, а не обязательно библиотечными вызовами.
Когда вы пишете и добавляете в конец файла (обычный режим записи), вы считываете последний блок файла в память, модифицируете его данными записи, а затем записываете весь блок обратно на SD-карту. , Если блок заполнен, то в таблице размещения файлов (FAT) должен быть найден новый блок. После нахождения нового блока необходимо обновить FAT, что является циклом чтения-изменения-записи. Если мы закончили с файлом, то нам нужно обновить атрибуты файла (например, длину файла) в корневом каталоге, что вызовет еще один цикл чтения-изменения-записи.
Минимизация вашего времени записи
Убедитесь, что файл уже содержит ваши данные, когда вы пишете сектор. Если вы начинаете с большого файла и перезаписываете данные вместо добавления данных, данные будут в безопасности, как только закончится запись в сектор SD-карты. Таким образом вы можете исключить от одного до двух циклов чтения-изменения-записи. Мой стартовый код будет записывать 0 в файл с приращением сектора до тех пор, пока SD-карта не будет заполнена, а затем перематывать назад в начало файла.
Сделайте размер ваших записей данных таким, чтобы целое число записей вписывалось в сектор. Я бы увеличил ваши записи до 64 байтов. Хотя это менее эффективно, это избавит вас от необходимости чтения-изменения-записи двух секторов.
Создайте вариант функции FSwrite, которая позволяет записывать целые сектора. Если вы сохраняете весь сектор в SRAM, то ваш цикл переходит от «чтение-изменение-запись» к «изменение-запись»
Поддерживайте питание PIC и SD как можно дольше
Большие конденсаторы хороши. 470 мкФ должно дать вам более чем достаточно энергии для завершения цикла записи.
Убедитесь, что ваш источник питания не будет высасывать энергию из резервного конденсатора! Добавьте диод при необходимости.
Знай, когда у тебя нет власти
источник
Одна проблема, еще не упомянутая с SD-картами (или MMC, CompactFlash и т. Д.), Заключается в том, что хотя SD-карта может отображаться на хосте как простая коллекция из 512-байтовых секторов, которые могут быть прочитаны и записаны в произвольном порядке, устройства флэш-памяти обычно храните 528-байтовые страницы в группах по 32 КБ, если не больше каждой, и единственные поддерживаемые операции - это либо запись на пустую страницу, либо удаление всей группы. Чтобы справиться с этим ограничением, контроллер на SD-карте будет хранить таблицу, которая позволит сопоставить любой логический сектор с любой физической страницей. Когда делается запрос на запись сектора, контроллер найдет пустую страницу где-то на чипе и обновит отображение новым адресом рассматриваемого сектора. Если пустых страниц становится мало, или в другое время,
Значение этого заключается в том, что процесс записи в конкретный логический сектор может потребовать перетасовки данных из многих логических секторов. Если что-то пойдет не так в этом процессе, это может привести к повреждению любого произвольного сектора - не только сектора, который попросили записать карту. Хороший контроллер SD-карты должен быть спроектирован так, чтобы выполнять операции перетасовки данных таким образом, чтобы в случае потери питания во время перестановки данных он мог выяснить, какие части операции были выполнены, а какие - нет, и следовательно, сможете правильно завершить операцию. К сожалению, я понятия не имею, как можно определить, будет ли SD-карта за 5 долларов, купленная в магазине со скидкой, полезной в этом отношении.
Чтобы быть уверенным, даже если SD-карта абсолютно идеальна с точки зрения обеспечения того, что каждая операция записи, о которой было сообщено, что она была завершена, фактически переживет сбой питания (т. Е. Гарантирует, что при выполнении всех операций записи было бы вызвано завершено, достаточно выполнено, чтобы карта завершила операцию при повторном включении питания), что не означает, что операционная система хоста не будет иметь проблем, если она выполнит некоторые, но не все записи данных, которые она намеревается. Тем не менее, важно иметь в виду, что, если SD-карта не может удержать конец своей «сделки», в программном обеспечении на стороне хоста ничего нельзя сделать, чтобы предотвратить потерю данных из-за сбоя питания.
источник
Я бы также предложил использовать какую-то контрольную сумму для проверки правильности данных на SD всякий раз, когда их нужно прочитать.
источник
Возможно, этот суперконденсатор в Sparkfun решит проблему.
источник
Как и в случае с любой инженерной проблемой, вам нужно будет найти здесь компромиссы.
Важно ли вообще потерять данные? Тогда я бы сделал выше. Вы потерпите больше ущерба, чем испортите карту. Возможно, вы захотите провести своего рода стресс-тест, чтобы определить, сколько раз вы могли выполнить эту операцию, прежде чем карта будет повреждена. Если вы круты с тем временем, которое потребовалось до того, как карта стала непригодной для использования, и, кажется, это приемлемый промежуток времени до замены карты, я бы пошел по этому пути.
источник
Если вы хотите просто хранить данные, вам не нужна файловая система. Операция записи будет выполнена непосредственно через SPI, выбрав адрес блока. тем самым вы минимизируете время записи и риск повреждения данных.
Даже в случае потери питания и неудачи вы потеряете только одну запись (что может быть приемлемо в некоторых системах).
источник