Файловая система во встраиваемых решениях — критическое звено. От её выбора зависят надёжность, детерминированность и задержки всей системы.

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

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

Я протестировал четыре файловые системы на платформе MC80 с внешней OSPI NOR Flash и разработал специализированный драйвер вместо стандартного из FSP — с полноценной поддержкой OSPI и RTOS.

Вот схема подключения OSPI NOR Flash на плате MC80

Остальная информация в статьях :

Что сравниваем


Рассмотрим четыре популярные файловые системы для малых встраиваемых систем — то есть для микроконтроллеров без MMU:

  • FileX совместо с LevelX;

  • LittleFS;

  • YFFS2;

  • STFs;

Небольшая сводка

FileX + LevelX (Azure RTOS)

  • Тип: блочная FAT32; exFAT. LevelX — слой выравнивания износа для NOR/NAND.

  • Плюсы: совместимость с FAT и USB MSD (может работать как USB диск), готовая интеграция с RTOS ThreadX. Есть опция журналирования для защиты от сбоев записи и питания.

  • Минусы: Без LevelX на Flash надежно работать не будет. Но это добавляет задержки. Требует кэша секторов, желательно нескольких.

LittleFS

  • Тип: гибридная блочно-журналируемая для NOR Flash. Особо позиционируется как устойчивая к сбоям записи и питания.

  • Плюсы: Встроенное выравнивагие износа, в RAM нужен только кэш размером с сектор, и два буфера размером со страницу. Быстрая инициализация.Не использует динамическую память.

  • Минусы: Плохо детеминирована. Большие непредсказуемые задержки. Нет интеграции с RTOS. Нет доступа через USB MSD.

YFFS2

  • Тип: журналируемая (log-structured) с поддержкой контроля целостности данных через ECC (Error-Correcting Code). Позиционируется как заточенная для NAND Flash, но отлично работает и с NOR Flash

  • Плюсы: высокая устойчивость к сбоям, быстрая инициализация. ECC для NOR может быть отключен.

  • Минусы: Большое потребление RAM, сильно зависящее от объема NOR Flash и гранулированности страниц. Требует явной периодической дефрагментации. Дефрагментация усложнена стратегиями. Нет интеграции с RTOS. Активно использует динамическую память. В варианте для микроконтроллеров нет доступа через USB MSD.

STfs

  • Тип: журналируемая, пригодна для организации файловой системы прямо во Flash памяти микроконтроллеров в особенности семейства STM32H.

  • Плюсы: устойчивость к сбоям, автоматическое выравнивание износа, высокий детерминизм, работает с Flash с неоднородными размерами секторов, минимальная деградация скорости по сравнению с сырой записью во Flash. Самое низкое потребление RAM. Не использует динамическую память. Простая интеграция с RTOS.

  • Минусы: отсутствуют директории. Требует явной периодической дефрагментации. Дефрагментация выполняться может дольше минуты. Нет доступа через USB MSD.

Драйвер для MX25UM25645GMI

В стандартной поставке FSP для микроконтроллеров семейства RA8 есть обобщённый драйвер для SPI-Flash. Он включает вариант протокола для 8-битного режима. Однако, как оказалось, разработчики не реализовали для этого режима команды стирания. При этом главная проблема, характерная для драйверов из SDK производителей чипов, — отсутствие полноценной поддержки RTOS. Из-за этого такие драйверы обычно уходят в длительные циклы программного опроса сигналов. Подобная реализация неприемлема для систем реального времени, поскольку может приводить к простоям задач всей системы управления на, казалось бы, невинных файловых операциях.

Исходный драйвер был перереботан очень серьезно. Исходники — здесь.

Однако за разочарованием от качества драйверов последовало ещё одно — периферия тоже может подвести. По даташиту MX25UM25645G кажется, что при частоте 200 МГц и 8-битной шине память должна выдавать на чтении около 200 МБ/с. На практике выяснилось, что OSPI-интерфейс в RA8 c DMA вставляет ~10 мкс паузы между 64-байтными пакетами чтения, что резко снижает пропускную способность. Прежде чем признать это ограничением платформы, я реализовал в драйвере три режима чтения: (1) по «ручным» командам OSPI, (2) прямое чтение из отображённого адресного пространства Flash, (3) то же, но через DMA.

Для исследования работы OSPI Flash разработан терминальный модуль, с которым можно работать по USB через любую терминальную программу. Вот этот.

Здесь, помимо OSPI, можно проводить и многие другие тесты. Не забываем, что MC80 — боевая платформа для реальных приложений, а не для лабораторных исследований. Нам важно получать результаты в условиях реальной многозадачности, когда одновременно работают и моторы, и пользовательский интерфейс, и полевые шины.

Результаты тестов чтения 64 Кбайт из Flash с 1-битным протоколом и 60 МГц тактированием:

  • Скорость чтения «ручными» командами: 1 903.005 КБ/с (1 948 678 байт/с)

  • Скорость прямого программного чтения: 6 239.032 КБ/с (6 388 769 байт/с)

  • Скорость прямого чтения по DMA: 5 844.214 КБ/с (5 984 476 байт/с)

Результаты тестов чтения 64 Кбайт из Flash с 8-битным протоколом и 60 МГц тактированием:

  • Скорость чтения «ручными» командами: 2437.166 КБ/с (2495658 байт/с)

  • Скорость прямого программного чтения: 35184.166 КБ/с (36028587 байт/с)

  • Скорость прямого чтения по DMA: 6537.950 КБ/с (6694861 байт/с)

Отсюда видно, что переход с 1-битного на 8-битный протокол при использовании DMA не даёт ощутимого прироста. Нельзя забывать, что в устройстве в это время работают другие каналы DMA и DTC. Прямое программное чтение остаётся более чем вдвое медленнее теоретической скорости при тактировании 60 МГц. Похоже, 8-битное подключение было избыточным — пины можно было бы сэкономить.

Ниже статистика процедуры стирания всей памяти MX25UM25645GMI:

===== Block Erase Results =====
Block erase operation         : SUCCESS
Total blocks erased           : 512 / 512
Total size erased             : 32 MB (33554432 bytes)
Total elapsed time            : 2 minutes 36 seconds (156666 ms)
Overall erase speed           : 209 KB/s

=== Final Statistics ===
Minimum block erase time      : 246 ms
Maximum block erase time      : 355 ms
Average block erase time      : 299 ms
Minimum block erase speed     : 180 KB/s
Maximum block erase speed     : 260 KB/s

О методике тестирования

Тестирование можно организовать по-разному, в зависимости от целевого сценария использования файловой системы; здесь я не претендую на всестороннее покрытие. Кому нужны другие проверки — можно взять проект и настроить тесты под свои задачи.

Я использовал стресс-тест: циклы записи → чтения → стирания для 1000 файлов по 10 Кбайт. Такой профиль близок к моим практическим кейсам (запись телеметрии).
Т.е. 1000 файлов последовательно записывается, потом эта тысяча последовательно читается и потом последовательно стирается. При чтении проверяется целостность файлов. Тестирование каждой следующей файловой системы ведется ни чистую Flash.

Параметры платы: OSPI 8-бит, 60 МГц; частота ядра МК — 240 МГц.

Результаты File-X

FileX в конфигурации с одной таблицей FAT и без журналирования.

Результаты LittleFS

Результаты YFFS2

Результаты STfs

Сводная таблица результатов

Как видно, наилучше справляется с большим количеством файлов YFFS2.
Самая быстрая — STfs. Если запись происходит редко, то STfs — лучший вариант. Если запись происходит часто, то лучше выбрать YFFS2.

Но надо помнить, что STfs показывает высокую скорость только при записи на чистую флеш-память. Форматирование в STfs длится 153 сек. Дефрагментация после удаления записанных 1000 файлов длится 47 сек. Для сравнения форматирование FileX длится 0.5 сек независимо от того сколько мусора оставалось на диске.

А вот LittleFS вызывает тревогу: возможны неожиданные задержки, которые могут стать проблемой. И самая низкая скорость записи. Однозначно применять её мы не будем.

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

Итак, выбор сделан: разбиваем флеш-память на две части. В одной будет FileX, в другой — STfs.

Репозитарий проекта

Да, а GitHub Copilot тут при том, что ни одна строчка кода не была введена вручную. Поэтому лицензия пока MIT.

Комментарии (0)