Зачем ставить внешнюю IC памяти или SD карту если в микроконтроллере осталось много свободной Flash памяти!  Микроконтроллеры семейства STM32H снабжены двумя независимыми банками Flash памяти и это очень удобно. В одном банке можно расположить программный код, а в другом временные перезаписываемые данные.   Как сделать из внутренней Flash подобие EEPROM сравнительно неплохо написано в этом апноуте от ST. Но с некоторого уровня комплексности встроенного ПО хранить данные в именованных файлах удобнее чем в жёстких структурах. Файлы упрощают реюзинг, облегчают поддержку преемственности версий, апгрейды и даунгрейды. Файлы освобождают от хлопот с планированием размещения во флэш и разруливанием конфликтов размещения, особенно если приложение модульное и модули разрабатываются отдельно.  В такой файловой системе можно хранить разные версии наборов параметров устройства, сертификаты и ключи к разным облачным сервисам, диагностические или аварийные дампы, временные файлы при распаковке, стандартные ресурсы, такие как шрифты и пиктограммы для HMI или скрипты и стили WEB страниц и проч. Здесь представлена линейная файловая система относящаяся к классу журналируемых. Такие файловые системы известны давно.  Быстротой они не блещут, потому эффективны на сравнительно небольших объемах памяти. Но им присуще крайне малая потребность в ОЗУ, малый размер кода и сравнительная простота. При этом по своей природе линейные файловые системы обеспечивают равномерный износ Flash и им не нужен дополнительный программный слой FTL, как например для FAT на базе NAND.  Это продолжение развития открытого проекта платы контроллера резервного питания BACKPMAN v2.0.  Вот тут и тут написано как началась разработка BACKPMAN v2.0.  Движение идет по пути наращивания функциональности. Поэтому представленный здесь следующий проект с пафосным названием Example2 является продолжением проекта Example1 с некоторым рефакторингом и c демонстрацией линейной файловой системы STfs (не расшифровывается, просто префикс в сорсах).   Выше упомянул апноут от ST. На самом деле там все довольно угловато. Главная функция записи там может записывать только 2-х байтными словами сопровождаемыми тэгом под называемым виртуальный адрес. Что делать если надо сохранять структуры или не выровненные блоки неясно. Как вариант - просто записывать все это во Flash по фиксированным адресам, макросам обеспечивая бесконфликтную упаковку. Потом чуть усложнить и организовать циклический сдвиг всего по сектору при перезаписи, чтобы выровнять износ Flash. Тут появляются зачатки API. И естественным образом мысль приходит к файловой абстракции. Один шаг остается до реализации API имитирующего обычную файловую систему.  Источником вдохновения послужила файловая система из среды Keil для SPI Flash. Но там все аскетично и нет поддержки RTOS. В предыдущих статьях было описано портирование Azure RTOS, и STfs  использует сервисы этой RTOS. Как любая файловая система STfs не предоставляет жесткого детерминизма.  Поэтому чтобы внедрить ее в среду задач с жестким реальным временем приходится использовать RTOS. Однако количество сервисов требующихся файловой системе от RTOS невелико, и портирование её на другую операционку не должно вызывать проблем. Особенностью семейства STM32H является наличие механизма контроля и исправления целостности блоков внутренней Flash памяти и разбивка Flash на стираемые секторы сравнительно большого размера. Конкретно у STM32H753VIH цельные блоки имеют размер 32 байта, а минимальные стираемые секторы 128 Кбайт. Т.е. можно записывать за одну итерацию во Flash только блоками по 32 байта называемыми Flash word, не больше и не меньше, только один раз в одно место после последнего стирания, но стирать можно только блоками по 128 Кбайт. Если попытаться повторно записать что-то во Flash, даже если это будет один байт и он просто поменяет один бит с 1 на 0, то 32-байтный блок, на который придется такая запись, будет с высокой вероятностью обозначен системой как сбойный и последующее чтение в границах этого блока вызовет ошибку доступа к шине и вызов исключения BusFault, которое нарушит ход выполнения программы. И такое поведение никак отключить нельзя. Т.е. после некорректной записи всего в один байт в системе станет недоступным блок Flash памяти размером в 32 байта и его невозможно будет читать ни внутренней программой, ни с помощью отладочного адаптера, пока не будет стерт весь сектор128 Кбайт содержащий этот блок.  Указанные ограничения препятствует использованию файловых систем типа SPIFFS или  littlefs. Требуется более специфичный подход.  Технология проста. В секторы памяти размером 128 Кб последовательно записываются данные файлов. Каждый раз при открытии файлов на запись, фиксации данных и закрытии этих файлов создаются дескрипторы и записываются в тот же сектор. Данные файлов пишутся от нижней границы сектора вверх, а дескрипторы пишутся от верхней границы сектора вниз, как показано на рисунке ниже     Когда данные и дескрипторы сходятся в одной точке запись переносится в следующий сектор Flash.  Ниже описание структуры дескриптора: Дескриптор имеет размер 64 байта и состоит из двух половин по 32 байта. Это позволяет записывать дескрипторы всегда выровненными по границе 32-байтного Flash word и ровно соответствующего размера. Дескриптор создается всегда, когда записывается имя файла и закрывается файл. Но если требуется надежно зафиксировать данные файла, а закрывать его ещё долго не придётся, то вызывают функцию STfs_flush , и в этом случае также будет создан дескриптор. Т.е. дескриптор окончательно валидирует данные и они не будут потеряны после выключения питания.  При удалении файлов ничего не стирается, но только в дескрипторы файлов записывается тэг удаленных. Когда в секторе остаются только удаленные файла он автоматически стирается. Если сектора полностью заполнены и в них остались вперемешку удаленные и актуальные файлы, то существует функция дефрагментации, которая переносит и дефрагментирует актуальные файлы в один или группу секторов, стирая освободившиеся сектора.    32-битная линейная многозадачная для среды Azure RTOS адаптированная под 32-батное Flash word  Размер и количество секторов произвольное. Назначается через массив секторов на этапе компиляции  Длина имени файла не более 31 символа и не менее 1 Количество дисков произвольное.  Поддержки директорий нет, поддержки даты создания нет (но можно добавить). Есть поддержка поиска файлов по имени, по шаблону, по порядку создания. Количество одновременно открытых файлов на чтение произвольное. Определяется на этапе компиляции. Количество одновременно открытых файлов на запись не должно превышать количества секторов. Нельзя одновременно открывать файлы на запись и на чтение. Как видно есть некие ограничения по сравнению с той же FAT32, но с другой стороны все что надо для встраиваемого софта малых систем все есть.  Название функции Описание STfs_init Инициализация файловой системы. Инициализирует драйвер Flash, проверяет целостность, форматирует если целостность нарушена STfs_find Поиск файла на виртуальном диске по строковому шаблону и получение сведений о файле STfs_find_first_file Поиск самого раннего файла на виртуальном  диске и получение сведений о файле STfs_find_next_file Продолжение поиска файлов от ранних к поздним STfs_open Открытие файла на запись или чтение STfs_rename Переименование файла STfs_read Чтение данных из файла STfs_write Запись данных в файл STfs_setpos Установка позиции чтения из файла от его начала STfs_len Получение размера файла STfs_close Закрытие файла STfs_delete Удаление файла STfs_flush Фиксация записанных данных во Flash STfs_free_space Получение информации о количестве свободного пространства на виртуальном диске  STfs_format Форматирование виртуального диска. Физически просто стирание всех секторов STfs_check Проверка целостности файловой системы на виртуальном диске и получение информации о системе   STfs_defrag Дефрагментация файловой системы  STfs_free_task_cbls Освобождение захваченных задачей RTOS ресурсов у файловой системы.  Тестировать на реальном железе логику файловой системы слишком долго и неудобно.Поэтому была написана программа симулятор на C++ под Windows 10.Программа включает те же исходники STfs что и рабочая версия для микроконтроллера, только слой драйвера Flash памяти был заменен на эмуляцию в оперативной памяти компьютера. Но при этом эмулятор строго проверяет все ограничения по  размеру и выравниванию записываемых данных и чистоте целевой области записи. Был создана функция тестовой записи и считывания файлов с регулярной проверкой целостности и дефрагментацией по необходимости. Все записи, считывания  производятся на основе генератора случайных чисел. Каждый 10-й файл не удаляется для имитации фрагментации. Если дефрагментация не удаётся, то чтобы не прерывать тест производится выборочное удаление более старших файлов. Симулятор легко проводит миллион и больше итераций, что на обычной Flash уже вызвало бы неминуемые проблемы износа. Однако такое количество итераций оправдано при поиске глубоко закопанных ошибок логики файловой системы и это сильно помогло при отладке.Симулятор накапливает лог в котором можно просмотреть всю историю прохождения тестов.  Симулятор написан в среде Embarcadero RAD Studio 11 Alexandria.  Но легко скомпилируется и на более ранних версиях, поскольку использует только минимальный набор стандартных компонентов.  Подойдет триальная версия. Сначала об износе. Как уже писал выше выравнивание износа присуще линейным FS и это показала симуляция случайного потока записей, удалений и дефрагментаций .  Вот результат после 100 тыс. итераций теста: Номер сектора  Количество стираний 0 2961  1 3442  2 3541  3 3941  4 4386  5 3653  6 3798  7 3166  Как видно цифры одного порядка. При том что предельный жизненный цикл у Flash очень размыт то более точного совпадения цифр и не требуется. Надо напомнить что в STM32H работает механизм исправления одиночных ошибок Flash и предупреждения о двойных ошибках. Т.е. пользователь имеет дополнительную возможность проактивно среагировать на износ в своем прикладном коде.  Теперь цифры измеренные на реальном микроконтроллере STM32H753VIH после 200 итераций Тип операции Минимальное время, мкс Максимальное время, мкс Стирание сектора 855691 930729 Открытие файла на запись 179 768 Время записи файла размером 10 Кбайт 27100 30742 Время чтения файла размером 10 Кбайт 25 203 Проверка целостности файловой системы 189 8983 Скорость записи в файл колеблется в пределах 325...369 Кбайт в секунду. Это типичная цифра для NOR памяти и тут лучшего ожидать не приходится.  Но надо отметить неплохую детерминированность.  Ложку дёгтя вносит время стирания сектора. А значит дефрагментация может затянуться до 8 сек. Это надо учитывать.  Но чтение будет идти со скоростью не менее 40 Мбайт в секунду. И этого более чем достаточно.  Все проекты хранятся здесь.