Как писать прошивку для принтеров

iОнлайн

Создание своего скомпилированного образа прошивки (hex файла) для 3Д принтера

Всем привет! На этот раз представляю Вам последнюю статью из трилогии посвященной прошивке 3Д принтеров. Как вы помните, в предыдущих статьях мы рассматривали варианты прошивки принтера с помощью Arduino IDE и исходного кода прошивки, а так же с помощью слайсера Cura и скомпилированного образа прошивки. Вполне логичным продолжением этой истории будет рассказ о том, как создать этот самый файл с образом прошивки (hex файл). Об этом и поговорим.

Прежде чем мы продолжим, предлагаю Вашему вниманию ссылки на предыдущие статьи:

  • Устанавливаем прошивку Marlin на 3D принтер с помощью Arduino IDE
  • Устанавливаем прошивку Marlin на 3D принтер с помощью слайсера Cura или что делать с hex файлом?

Зачем же нужен скомпилированный вариант прошивки? На самом деле, в таком варианте ее удобнее хранить, передавать и прошивать. Вам не нужно ставить и настраивать не всегда стабильно работающую Arduino IDE, искать необходимые библиотеки. кроме того, в таком выде вы точно не отредактируете файл и точно будете знать что в нем содержится. Хранить такие файлы тоже удобно. Обозвал понятно и готово. С исходниками все сложнее. Да и в конце концов, прошивать из файла образа бастрее и ничего лишнего не требуется.

Кстати, данная статья будет полезна не только владельцам 3Д принтеров, но и разработчикам различных программ для различных микроконтроллеров. Это же очень удобно. Разработал схему, разработал прошивку. Все отладил и проверил. Платы заказал, прошивку собрал и ты уже уверен, что не ошибешься при изготовлении устройства. Да и при желании таким образом можно защитить код от кривых ручек чайника 🙂

Но что-то мы удалились от темы. Давайте разберемся, как же создать этот самый hex файл.

Для этого нам понадобится любой скетч (хоть простенький Blynk, хоть сам Marlin) и среда Arduino IDE со всеми необходимыми библиотеками.

Если в общих чартах рассмотреть процесс прошивки с помощью Arduino IDE, то можно выделить следующие этапы:

  1. Мы нажимаем кнопку Загрузка
  2. Arduino IDE проверяет скетч
  3. Arduino IDE Компилирует скетч в соответствии с заданными параметрами (с использованием указанных библиотек и с учетом конфигурации платы, которую вы выбрали)
  4. Arduino IDE Указанным способом загружает скомпилированный скетч в микроконтроллер
  5. Arduino IDE при наличии возможности перезагружает микроконтроллер

Укрупненно процесс работает именно так. Как видно, на одном из этапов Arduino IDE осуществляет компиляцию скетча. При этом среда размещает файл во временном каталоге, а потом записывает в микроконтроллер.

При желании, можно отловит этот файлик и забрать себе, однако это не наш метод, т.к. есть пункт по проще.

Рассмотрим это на примере прошивки для 3Д принтера Anycubic 4max.

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

Среда Arduino IDE с необходимыми библиотеками (подробнее об этом можно прочесть в статье “Устанавливаем прошивку Marlin на 3D принтер с помощью Arduino IDE”

Пускай, корневая папка с исходниками прошивки marlin расположена по пути C:\TEMP\TEST\MARLIN_1.1.9_4MAX_RU\anycubic-4max

Заходим в указанный каталог и двойным кликом открываем файл anycubic-4max.ino

В процессе открытия файла автоматически запустится среда и отобразится содержимое файла anycubic-4max.ino

Теперь необходимо выбрать плату, для которой будет компилироваться прошивка, в моем случае это “Arduino / Genuino Mega or Mega 2560

Необходимо выбрать микроконтроллер (процессор) нашей платы, в моем случае это “ATmega 2560 (Mega 2560)

Все готово. Теперь начнется магия компиляции. Для получения hex файла необходимо выбрать пункт меню “Скетч” -> “Экспорт бинарного файла Ctrl + Alt + S

После этого начнется магия компиляции. Среда осуществит проверку и сборку прошивки в бинарный (hex) файл.

Ждем окончания компиляции.

После завершения процесса, в каталоге со скетчем (в нашем случае это C:\TEMP\TEST\MARLIN_1.1.9_4MAX_RU\anycubic-4max ) появится 2 файла:

anycubic-4max.ino.mega.hex – содержит непосредственно саму скомпилированную прошивку

anycubic-4max.ino.with_bootloader.mega.hex – содержит прошивку + загрузчик

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

Ну вот и все. Как видите, ничего сложного.

Надеюсь, что материал оказался для Вас полезен.

Если вы еще не обзавелись 3Д принтером и думаете какую модель выбрать, могу порекомендовать следующие модели:

Источник

Прошивка для фотополимерного LCD 3D-принтера своими руками. Часть 1

… или как я изобретал собственные велосипеды с преферансами и гейшами на свой вкус — писал с нуля прошивку для фотополимерного принтера. На данный момент прошивка уже вполне работоспособна.

За основу была взята продающаяся на Алиэкспресс плата MKS DLP, для которой производитель дает схему и исходные коды прошивки, которые я отверг в пользу написания всего с нуля.
Статья получается очень уж большой, поэтому я решил разбить ее на две части. В этой части будет предыстория и описание самодельного GUI для сенсорного дисплея. В конце будут ссылки на сам предмет издевательств и на репозитории Гитхаба.

Для лучшего понимания дам очень короткое описание работы фотополимерных LCD 3D-принтеров для тех, кто с ними не знаком:

Предыстория

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

Лет 5 назад я заинтересовался 3D-печатью. Не в профессиональном плане, а просто стало любопытно что же это такое, что она может и как работает. Сначала был приобретен FDM-принтер, один из самых бюджетных на тот момент — Anet A8. И в общем-то мне понравилось, учитывая, что чудес от него я не ждал. На нем я до сих пор иногда печатаю что-то утилитарное — какие-нибудь крепления, подставки, корпуса. А затем мне стало интересно пощупать фотополимерную печать с ее потрясающей детализацией, но тогда фотополимерные принтеры назвать бюджетными было никак нельзя. И вот пару лет назад я все-таки созрел на покупку одного из них — Anycubic Photon S. Уже и цены были не такими высокими, и я смог себе позволить потратить энную сумму просто для удовлетворения любопытства.

Сначала, конечно же, был эффект «вау» — он печатает такие мельчайшие детали, да так аккуратно. Никаких слоев, прыщей и т.п., присущих FDM-принтерам. Область печати, конечно, не ахти — всего примерно 115х65 мм, но фигурки и модельки получаются очень хорошо 🙂 Когда эффект «вау» прошел, я понял, что детализация у него не такая хорошая, какая могла бы быть. После чего я по примеру знакомого его слегка модернизировал. Пришла новая волна «вау» — детализация повысилась в разы. Правда, стали четко видны границы пикселей, но только если рассматривать модель на расстоянии 20-30 см. Кстати, последующая покраска напечатанных моделей оказалась довольно неплохим способом отдохнуть от работы — мозг отдыхает, руки возятся. Результат дарится знакомым как интересный сувенир.

Читайте также:  Postgresql сжатие базы данных 1с

Но по мере освоения принтера я начал замечать недостатки в работе принтера. Нельзя настроить это, сложно изменить то, не работает так как хотелось бы и т.д. В частности, например, мой принтер не умел работать с каталогами на флэшке, не поддерживал кириллические имена файлов, скорость движения платформы в определенных случаях была не той, что бы меня устроила. Я даже дизассемблировал прошивку и начал разбираться с ее внутренностями. Реализовал работу с кириллицей в именах файлов, изменил процесс вывода на интерфейсный экран (ускорил), переделал работу с языками. Но все это было несерьезно, нужно было иметь исходники, чтобы можно было нормально переделать все что хотелось. А исходники никто из производителей почему-то не дает. И вот несколько месяцев назад я узнал, что есть такой набор для фотополимерного принтера от довольно известного в сфере 3D-печати производителя — MKS DLP. В набор входят: сама материнская плата, дисплей засветки с защитным стеклом (5.5″, 2560х1440) и интерфейсный дисплей с сенсорной панелью (3.5″, 480х320). И для этого набора идут открытые исходники и схема — бери и переделывай как угодно! И я приобрел этот набор, рассчитывая изменить в исходниках то, что мне не нравится.

Когда я получил комплект и скачал с гитхаба исходники, приготовившись их слегка модифицировать, у меня случился легкий шок. Ну, во-первых их родная прошивка оказалась в принципе работоспособна, но это и все, что можно сказать о ней хорошего. Недостатков в ней полно и печатать с ней было бы очень не комфортно. Уже на этапе проб родной прошивки у меня начала закрадываться мысль, что модифицировать придется не так уж слегка. А когда я открыл их проект с исходниками… Во-первых, это жуткая мешанина Ардуины и библиотек CMSIS и HAL от ST (плата построена на микроконтроллере STM32F407). Во-вторых, в проект впихнута полная версия Marlin 3D. Кто не знает — Marlin 3D — это проект для управления FDM 3D-принтерами. Он поддерживает работу до 6 шаговыми двигателями, несколькими нагревателями с контролем температуры, кучи концевиков, парсинг G-кода с построением траекторий движения осей и много-много чего еще. Больше 3 МБ исходников. И сюда он был целиком впихнут только ради управления одним шаговым двигателем. Причем это управление было сделано совершенно без заморочек — в текстовой строке формировался G-код движения оси и эта строка передавалась на вход парсера Мерлина. Ну это как если бы взяли целиком автомобиль для того, чтобы использовать одну из его фар для освещения. Вообще создалось впечатление, что производитель взял исходники от своих плат для FDM-принтеров и просто сверху прикостылял код для работы с фотополимерной частью.

Кроме того, там была еще GUI-библиотека в бинарнике, без исходников. И я понял, что проще будет написать свою прошивку с нуля, чем пытаться что-то сделать с родными исходниками.

Итак, что мы имеем:

  • комплект MKS DLP, в который входят: материнская плата, интерфейсный дисплей 3.5″ 480х320 и дисплей засветки 5.5″ 2560х1440
  • родные исходники от производителя
  • схема материнской платы (без названий активных и номиналов пассивных компонентов)

Материнская плата построена на основе микроконтроллера STM32F407. Для управления дисплеем засветки на плате стоит FPGA китайского производителя GW1N-LV4LQ144ES, SDRAM и две микросхемы MIPI-интерфейса SSD2828. Микроконтроллер загоняет в FPGA изображение слоя, FPGA сохраняет его в SDRAM и оттуда рефрешит дисплей через SSD2828. Конфигурацию (прошивку) FPGA производитель, кстати, не предоставляет в исходниках 🙁 Кроме этого, на материнской плате есть:

  • вход питания 12-24 вольта
  • USB A разъем для подключения флэшки/картридера
  • коммутируемые выходы питания для засветки и двух вентиляторов
  • драйвер шагового двигателя A4988 и разъем для подключения двигателя
  • два разъема для подключения концевиков оси Z — верхнего и нижнего
  • разъем для подключения модуля WiFi
  • микросхема FLASH-памяти W25Q64
  • микросхема EEPROM-памяти AT24C16

Интерфейсный дисплей с резистивной тач-панелью подключается плоским 40-пиновым шлейфом. Контроллер дисплея — ILI9488, контроллер тач-панели — HR2046 (аналог TSC2046).

Для инициализации периферии я использовал программу STM32CUBE MX. Но не использовал напрямую полученный из него результат, а вставлял нужные куски в свои исходники. При работе с периферией использовал библиотеки HAL от ST, а там, где нужно было получить максимальную скорость — работал с регистрами напрямую.

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

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

1. Пользовательский интерфейс

Сначала была инициализация дисплея. Тут ничего интересного, стандартная последовательность для контроллера ILI9488. Ее я выдрал из родных исходников, вырезав оттуда код инициализации других видов дисплеев (которые, вероятно, остались там еще от FDM-жизни этих исходников). Дальше я занялся шрифтами.

1.1 Шрифты

В сети множество библиотек работы со шрифтами для микроконтроллеров, но абсолютное большинство из них работают с моноширинными шрифтами, а мне это не очень нравится. Это когда у всех символов одинаковая ширина, что у буквы «ж», что у буквы «i». Когда-то для одного из своих пет-проектов я написал библиотеку пропорциональных шрифтов. В ней для каждого шрифта используются два массива — массив с битовыми данными самих символов и массив с указанием ширины каждого символа. И небольшая структура с параметрами шрифта — указатели на массивы, высота шрифта, количество символов в шрифте:

Казалось бы, такая организация шрифта должна занимать в памяти больше места, чем просто битовый массив моноширинного шрифта, однако это не совсем так. Во-первых, сама моноширинность дает избыток хранящихся данных. Например, если в шрифте высотой 8 и шириной 5 пикселей для буквы «i» было бы достаточно 1 байта (1 бит ширины и 8 бит высоты), то она все равно будет занимать 5 байт данных (5 бит ширины и 8 бит высоты), т.к. ширина фиксирована. Во-вторых, как правило в таких шрифтах делается выравнивание по границам байта каждой строки или каждой колонки, смотря как организованы данные.

Читайте также:  Как настроить принтер на двустороннюю печать автоматически hp

Например, взять тот же шрифт 5х8. Если битовые данные хранятся по строкам, то для каждой строки получается избыток 3 бита. Или 3 байта на символ:

Или шрифт 7х12 с хранением данных по колонкам, тогда получается избыток данных 4 бита на колонку или 3.5 байта на символ:

В моей библиотеке битовые данные непрерывны для символа и выравнивание по границе байта идет только в конце символа.

Плюс есть еще одна небольшая хитрость, позволяющая слегка уменьшить хранимый размер шрифта: символ может не иметь битовых данных, а ссылаться на другой символ с таким же начертанием. К примеру, кириллические буквы «А», «В», «Е», «К» и т.д. могут иметь отсылку на латинские буквы с тем же начертанием. Это делается с помощью указания отрицательного значения ширины соответствующего символа в массиве ширин символов. Если там стоит отрицательное значение, значит изображение этого символа берется из символа в позиции (ширина * -1).

Вот процедура нахождения в массиве данных символа:

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

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

Например, на фото ниже голубой текст и верхняя белая строка отрисованы моей библиотекой, а белая нижняя — стандартной ардуино-подобной библиотекой из родных исходников:

Голубой текст отрисовался в несколько раз быстрее, чем нижняя белая строка.

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

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

1.2 Вывод изображений интерфейса

Для пользовательского интерфейса понадобится выводить на дисплей изображения — фон, иконки, кнопки. Сначала я решил сильно не заморачиваться и хранить все изображения в формате .bmp в 8-мегабайтной флэш-памяти, имеющейся на плате. И даже уже написал для этого процедуру. Файл сохраняется в 16-битном формате (R5 G6 B5) с прямым или обратным порядком строк, и может уже быть напрямую скормленным процедуре отрисовки. Но размер фоновой картинки размером 480х320 выходит более 300 Кбайт. С учетом того, что часть этой флэш-памяти будет отводиться под обновление прошивки, 30 фоновых изображений займут всю память. Вроде и немало, но все же меньше, чем хотелось бы иметь на всякий случай. А ведь должны быть еще кнопки, иконки и т.п. Поэтому было решено преобразовывать изображения в какой-то сжатый формат.

Со сжатием вариантов немного — все более-менее хорошо сжимающие изображения алгоритмы требуют или прилично оперативки (по меркам микроконтроллера) или прилично времени на разжатие. Картинки же должны выводиться, разжимаясь на лету, и желательно чтобы картинка при выводе не уподоблялась ползущему прогресс-бару. Поэтому я остановился на RLE-сжатии — 1 байт кодирует количество повторов, а два следующих за ним — цвет. Для этого так же была написана утилита, преобразующая файлы .bmp в сжатые таким образом изображения. Заголовок состоит всего из 4 байт — по 2 байта на ширину и высоту изображения. В среднем фоновые изображения сжимаются таким способом в 5-7 раз, сильно зависит от размера одноцветных участков (чего и следовало ожидать). Например вот такая картинка сжалась с исходных 307 КБ до 74 КБ:

А вот такая — до 23 КБ с тех же 307:


Да, кстати, дизайнер из меня еще более фиговый, чем программист.

Меня такой результат устроил. Декодирование и вывод изображений происходит очень быстро — примерно 40 миллисекунд на полное фоновое изображение. Так что на таком варианте я и остановился.

И, кстати, переход на режим DMA для вывода данных в дисплей не дал почти никакого ускорения вывода. Дисплей подключен по внешней 16-битной шине данных как внешняя память, но вот его тайминги довольно печальны, что и сводит почти на нет преимущества DMA-вывода перед попиксельным выводом «вручную».

1.3 Основа GUI

Тексты выводятся, картинки рисуются, теперь пора подумать над тем как будет организована основа пользовательского интерфейса.

С тач-панелью все просто — микроконтроллер по прерываниям постоянно опрашивает контроллер тач-панели и усредняет последние 4 полученных результата, переводя их в координаты дисплея. Таким образом в любой момент известно состояние сенсора — нажат он или нет и если нажат, то в каком именно месте. Еще одна прослойка между тач-панелью и основной частью программы — процедура обработки нажатий кнопок, которая уже довольно давно кочует у меня из проекта в проект с небольшими адаптациями под конкретные условия.

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

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

В конечном итоге я пришел к такой схеме: интерфейс состоит из двух основных типов элементов — экранов и кнопок.

Экран — это своего рода полноэкранный контейнер для кнопок. У экрана есть следующие свойства:

  • фоновое изображение
  • цвет фона
  • способ отрисовки фона — заливка фоновым цветом или вывод изображения
  • текст заголовка
  • цвет текста заголовка
  • шрифт текста заголовка
  • указатель на родительский экран (в который нужно вернуться при закрытии этого)
  • массив указателей на кнопки
  • указатель на процедуру обработки событий (вызывается периодически в основном цикле программы)
  • указатель на процедуру отрисовки экрана
Читайте также:  Rapid scada установка на linux

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

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

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

А вот на что не хватило возможностей этой схемы — так это на модальные окна с сообщениями или вопросами (типа MessageBox в Windows API), поэтому для них я сделал отдельный тип экранов. Без фоновых изображений и с размером, определяющимся заголовком или самим сообщением — что окажется больше. Эти сообщения могут быть созданы в четырех вариантах — с кнопками «Да/Нет», с кнопками «Ок/Отмена», с одной кнопкой «Ок» или вообще без кнопок (типа «Подождите, идет загрузка данных. »).

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

1.4 Мультиязычность

Мультиязычность стояла в задачах изначально. Но сначала я пошел по глупому пути — при инициализации всех элементов я присваивал им тексты из той языковой таблицы, которая являлась текущей. Переключение языка означало переинициализацию всех текстовых элементов и когда экранов в интерфейсе стало больше двух, а кнопок и надписей больше 20, я понял, что дальше так жить нельзя. После чего сделал все обращения к текстам через процедуру. Процедуре дается параметром идентификатор текста, а она возвращает указатель на текст в текущем языке:

При изменении языка происходит просто изменение указателя с массива текстов на старом языке на массив с текстами на новом языке:

Все тексты в исходниках — в кодировке UTF-8. С этими кодировками тоже пришлось повозиться. Тексты — в UTF-8, кириллица файлов — в Unicode-16, некоторые строки — в обычном ANSI. Тянуть в прошивку целый набор библиотек для поддержки многобайтовых кодировок не хотелось, поэтому было написано несколько функций для преобразований из кодировки в кодировку и для операций с текстами в разных кодировках, например, добавить к концу строки Unicode16 строку в UTF-8.
Добавление нового языка теперь свелось к созданию таблицы текстов на нем и к изменению значения константы LNG_LANGS_COUNT. Правда, остается вопрос со шрифтами, если в новом языке используются символы помимо кириллицы и латинницы… Сейчас я поддерживаю в исходниках русский и гуглопереведенный английский.

1.5 Хранение изображений и прочих ресурсов

Для хранения больших ресурсов на плате имеется SPI-флэш на 8 мегабайт W25Q64. Изначально я хотел поступить как всегда — задать смещение для каждого ресурса внутри флэши и сохранять их туда как просто бинарные данные. Но потом понял, что проблемы с таким способом мне гарантированно обеспечены как только количество сохраняемых ресурсов перевалит за пару десятков и мне захочется изменить, например, какую-то картинку, которая сохранена шестой по порядку. Если ее размер увеличится, то придется сдвигать адреса всех следующих ресурсов и перезаписывать их заново. Или оставлять после каждого ресурса запасное пространство неизвестного размера — кто его знает как может измениться какой-то из ресурсов. Да в гробу я видал эту возню 🙂 Поэтому я плюнул и организовал на этой флэши файловую систему. К тому времени у меня уже работала файловая система для USB на основе библиотеки FatFS, так что мне было достаточно просто написать отдельные низкоуровневые функции чтения/записи секторов. Одно только меня слегка расстроило — размер стираемого сектора в этой микросхеме аж целых 4 КБ. Это во-первых приводит к тому, что файлы будут занимать место порциями по 4 КБ (записал файл 200 байт — он занял 4 КБ флэши), а во-вторых буфер в структуре каждого файлового указателя будет отъедать те же 4 КБ оперативки, которой в микроконтроллере не так уж много — 192 КБ. Можно было бы, конечно, извратиться и написать низкоуровневые функции так, чтобы они могли писать и читать и меньшими порциями, рапортуя о размере сектора, например, 512 байт. Но это замедлило бы работу с флэш, так что оставил размер сектора 4 КБ. Так что обращение к любому ресурсу осуществляется просто по имени его файла, что оказалось очень удобным. На данный момент, например, количество хранимых ресурсов перевалило уже за 90. И их обновление я сделал максимально простым — обновляемые (или новые) ресурсы записываются на USB-флэшку в определенный каталог, флэшка вставляется в плату, плата перезагружается в сервисный режим (во время включения или перезагрузки нажать и держать правый верхний угол дисплея) и автоматически копирует все найденные в этом каталоге файлы с USB-флэшки в SPI-флэш.

Продолжение следует.

По интерфейсу вышла, пожалуй, самая объемная часть. Если эта статья окажется интересной сообществу, то во вторую часть постараюсь вместить все остальное.

Источник

Поделиться с друзьями
КомпСовет
Adblock
detector