Запись 16-битных данных на SD-карту с частотой 44 кГц

Я использую микроконтроллер STM32F4 с картой microSD. Я захватываю аналоговые данные через DMA.

Я использую двойной буфер, беру по 1280 (10 * 128 - 10 БПФ) выборок за раз. Когда один буфер заполнен, я устанавливаю флаг, а затем просматриваю 128 выборок за раз и выполняю для них вычисление БПФ. Все это работает хорошо.

Данные собираются с нужной скоростью, и расчет БПФ происходит так, как я ожидал. Если я просто позволю программе работать в течение одной секунды, я вижу, что она выполняет БПФ примерно 343 раза (44000/128).

Но проблема в том, что я хотел бы сохранить 64 значения из этого БПФ на SD-карту.

  • Я использую библиотеку толстой файловой системы HCC.
  • В каждом цикле вычисления БПФ я копирую 64 значения в массив.
  • После каждых 10 вычислений я записываю содержимое этого массива в файл и начинаю заново.
  • В массиве хранится 640 значений float_32 (10 * 64).

Это отлично работает для односекундного тестового прогона. Я получаю 22 000 значений, хранящихся на SD-карте.

Но по мере того, как я увеличиваю время, я начинаю терять сэмплы, поскольку для записи на SD-карту требуется больше времени. Мне нужна SD-карта для постоянного хранения более 87 кбит / с (4 байта * 64 * 343 = 87808). Я попытался увеличить размер выборки буфера DMA, а затем количество раз, которое он записывает, но не нашел, что это помогло.

Я использую карту microSD 8 ГБ, класс 4. Я отформатировал SD-карту в соответствии с размером блока распределения FAT32 по умолчанию 2048.

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

Я видел, что у Клиффорда была похожая проблема, и он использовал очередь, Как использовать SD-карту для записи 16-битных данных со скоростью 48 ksamples / s?.


person user3122700    schedule 04.02.2014    source источник
comment
Меня это тоже интересует. Когда я смотрел на это ранее, кажется, что настройка записи в и чтения из сектора занимает много времени. (У меня были большие трудности с получением информации с SD-карты достаточно быстро!) Поскольку FAT не гарантирует, что вы пишете в смежные сектора, кажется, что вам нужно инициализировать каждый сектор в коде файла FAT и не просто предполагать, что вы будете писать в следующий сектор после того, как будет записан предыдущий сектор.   -  person DiBosco    schedule 04.02.2014
comment
Я предполагаю, что если вы просто настроите систему так, чтобы после того, как вы выполнили запись в первый сектор, она могла просто записывать в смежные сектора карты, пока она не будет заполнена, все будет в порядке, потому что это не очень длинный набор - up [время] сообщения SD-карте, в какой сектор будет производиться запись. Это основное ограничение FAT? Можно подумать, что нет, потому что камеры записывают на SD-карты с высокой скоростью и используют FAT.   -  person DiBosco    schedule 04.02.2014
comment
Спасибо за ваши комментарии, но, как уже упоминалось, я использую библиотеку файловой системы HCC Fat, эта библиотека следит за инициализацией сектора. Я связался с HCC, и они сказали, что библиотека способна писать более 3 МБ в секунду, и что это не проблема файловой системы. В настоящее время я думаю, что библиотека способна на это, мне нужно выяснить хорошую систему буферизации / очереди для записи данных на SD-карту.   -  person user3122700    schedule 04.02.2014


Ответы (3)


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

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

Используя очередь RTOS, я предлагаю вам создать очередь сообщений длиной 64*sizeof(float_32), количество сообщений в очереди будет определяться величиной задержки карты, с которой вам нужно справиться; длина 343, например, выдержит остановку карты в 1 секунду и потребует 87 КБ ОЗУ. Затем приложение будет иметь поток с высоким приоритетом, выполняющий БПФ и помещающий данные в очередь, в то время как поток с низким приоритетом берет данные из очереди и записывает в файл.

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

person Clifford    schedule 04.02.2014

Flash очень и очень чувствителен к перезаписи. Запись 3 КБ, а затем следующих 3 КБ может считаться перезаписью первых 4 КБ. В вашем случае нет веской причины, по которой вам все равно нужны такие мелкие записи. Я бы посоветовал записать 16 КБ (32 кадра / запись * 64 сэмпла / фрейм * 4 байта / сэмпл). Вам потребуется 5 или 6 операций записи в секунду, что должно быть в пределах спецификации любой старой SD-карты.

Теперь вполне вероятно, что вы получите еще 1280 семплов во время написания; вам придется иметь дело с этим в другом потоке. Не должно быть проблем, так как запись должна блокироваться без использования ЦП (это низкоуровневая задержка Flash)

person MSalters    schedule 04.02.2014

Наиболее вероятной причиной проблемы может быть способ подключения карты к библиотеке.

SD-карты по протоколу SPI (который, как я предполагаю, используется здесь) могут быть прочитаны или записаны в единицах сектора по 512 байт, некоторые команды SD позволяют осуществлять потоковую передачу (для более быстрого последовательного доступа к секторам). Важным элементом протокола SPI SD-карты являются различные задержки, когда вы должны опросить карту, можете ли вы начать операцию (например, запись данных в сектор).

Вы должны прочитать API библиотеки, чтобы узнать, как может работать процесс ее написания. Вам нужно будет выполнить какое-то обычное действие, которое, в конце концов, опросит карту, чтобы узнать, можно ли продолжить процесс записи. Некоторым картам может потребоваться определенное количество доступов, прежде чем они будут готовы к операции, некоторые другие могут использовать тайм-ауты для переходов между состояниями. Может не получиться, если функция будет вызываться относительно редко (например, один раз в 2-3 миллисекунды), ожидая, что карта будет готова. Вы должны продолжать мучить его, завершено ли оно уже.

Просто из собственного опыта работы с интерфейсом SD.

person Jubatian    schedule 19.05.2017