FatFS - могу ли я создать несколько мест поиска? - PullRequest
0 голосов
/ 23 мая 2019

У меня есть рабочая интеграция FatFS в моем приложении C ++, работающем на платформе Cortex M4.

Мое приложение состоит из регистрации данных в формате данных, называемом MDF .

На стороне реализации я записываю данные (в заданный файл) в виде пакетов буферов;Количество буферов зависит от того, насколько быстро я получаю данные: пакет журнала одного буфера.,,делать другие вещи.,,пакет журнала из пяти буферов.,,делать другие вещи.,,и т.д.

Существует также заголовок, который составляет 24 байта и содержит количество байтов данных.На ПК я бы просто сохранил заголовок в конце измерения, но это встроенный продукт, который можно отключить в любой момент времени.Если я не сохраняю заголовок периодически, файл становится «поврежденным».

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

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

I am с использованием f_cache_fptr, поэтомуf_lseek не слишком медленный, но я бы хотел избежать необходимости часто звонить f_lseek.

ВОПРОС

Возможно ли как-то иметь 2 запроса?местоположения, так что мне не нужно вызывать f_seek для пинг-понга между местоположением заголовка и местоположением данных?

Я открыт для изменения FatFS.

Проблема на низком уровне проще, поскольку заголовок разделяет только один сектор 512 байт с данными: 24 байта заголовка, за которыми следуют 488 байтов данных.

Ответы [ 2 ]

3 голосов
/ 23 мая 2019

Можно ли как-то иметь 2 местоположения поиска, чтобы мне не нужно было вызывать f_seek для пинг-понга между местоположением заголовка и местоположением данных?

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

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

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

Но зачем гадить с внутренностями FatFS?Это будет по крайней мере немного рискованно.Пока вы все равно должны добавить функцию, как насчет простой реализации FRESULT my_f_write_at_beginning(FIL* fp, const void* buff, UINT btw, UINT* bw) поверх существующих функций ?Он может сохранить текущую позицию, выполнить поиск в начале файла, выполнить запись (возможно, гарантируя, что записано полное число указанных байтов), а затем выполнить поиск в исходной позиции.

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

0 голосов
/ 24 мая 2019

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

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

Вернее; вам нужно сохранить буфер и верхний колонтитул (нижний колонтитул?) и обновить запись каталога, чтобы отразить новый размер файла, и обновить таблицу размещения файлов, чтобы учесть выделенные сектора; и вам нужно написать по крайней мере в 3 совершенно отдельных секторах «атомарно», чтобы все было согласованно, если сбой питания произошел в неподходящее время.

Это не совсем возможно на большинстве аппаратных средств.

Однако есть способ сделать это «несколько безопасно». В частности:

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

  • создать совершенно новую копию данных файла в предварительно выделенных кластерах (скопировать старые данные, затем добавить новые данные и заголовок). Если во время выполнения этого (или сразу после этого момента) происходит сбой питания, тогда риск такой же, как и раньше, - только некоторые потерянные кластеры (игнорируемые).

  • атомарное обновление записи каталога; изменение как размера файла, так и «номера начального кластера» с одной и той же атомарной (односекторной) записью. Если после этого момента происходит сбой питания, существует риск того, что потерянные кластеры будут такими же (где старая версия данных файла была вместо новой версии данных файла).

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

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

Конечно, для того, чтобы все это работало, вам нужна гарантия того, что односекторные записи являются атомарными; и вы не можете использовать FAT12 (где запись в таблице размещения файлов может быть разделена границей сектора).

...