Кремень КД Реклама
Кремень КМ Реклама

STM32 без бубна и танцев

jmz
Идет загрузка
Загрузка
21.12.2023
21726
37
Техничка

Подпишитесь на автора

Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых статьях.

Отписаться от уведомлений вы всегда сможете в профиле автора.

41

Простая установка Marlin на отладочную плату STM32

Путаница с загрузчиками

Историко-технический экскурс, во время которого разберемся, что такое загрузчик, зачем он нужен и какое отношение он имеет к Marlin и STM32.

Arduino

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

В 2009 году компания leaflabs пыталась выпускать свою линейку Arduino-подобных плат на базе STM32. Для совместимости с Arduino был разработан набор библиотек libmaple и специальный загрузчик, аналогичный используемому в Arduino. Какого-то заметного успеха эта инициатива не имела, и в 2015 проект libmaple был закрыт.

Marlin загрузчик от leaflabs никогда не использовал и не поддерживал.

STM32

У микроконтроллеров STM32 есть встроенный загрузчик, который позволяет заливать прошивку без использования программатора / отладчика. Находится встроенный загрузчик в нестираемом ПЗУ микроконтроллера, и он не может быть поврежден или удален без физического повреждения чипа.

Для активации этого загрузчика используется специальная нога BOOT0. В зависимости от поданного на неё сигнала при включении или перезагрузке управление передается или в пользовательскую прошивку (низкий уровень сигнала) или во встроенный загрузчик (высокий уровень).

Встроенный загрузчик позволяет залить прошивку используя UART или USB подключение. Последний вариант доступен только на микроконтроллерах линейки STM32F4 и новее.

Marlin

В декабре 2018 года в Marlin появилась поддержка платы MKS Robin с её проприетарным загрузчиком, позволявшим обновлять прошивку из зашифрованного файла на SD карте. Загрузчик MKS, располагается в начале флеш памяти и с точки зрения микроконтроллера является пользовательской прошивкой. Прошивка для MKS Robin должна была собираться используя нестандартное расположение во флеш памяти.

Возможность обновлять прошивку с SD карты оказалась решающим фактором, и уже весной 2019 года на рынке появилась BTT SKR Mini v1.1 – первая коммерческая плата управления 3D принтером на STM32, сделанная специально под Marlin 2.0. Загрузчик у неё был, разумеется, свой собственный, но общий принцип работы от этого не поменялся.

Все представленные на рынке платы управления 3D принтерами на STM32 используют загрузчики "от производителя", позволяющие обновлять прошивку с SD карты. Размер такого загрузчика зависит от его функционала и кривизны рук разработчика и варьируется от 8 до 64 килобайт. Когда в обсуждении упоминается слетевший загрузчик – речь идет именно о нём.

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

Если же, по каким-то причинам ST-Link отсутствует, то всегда остается возможность прошивки отладочной платы через встроенный загрузчик.

Таким образом, когда, применительно к STM32, используется слово "загрузчик", его значение зависит от контекста. На плате управления 3D принтером – это загрузчик "от производителя платы", записанный в начале флеш памяти и позволяющий обновлять прошивку с SD карты. На отладочной плате – это встроенный загрузчик, живущий в своем собственном ПЗУ и не занимающий места во флеш памяти.

Выбор отладочной платы

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

Отладочные платы от STMicroelectronics серий Nucleo и Discovery отлично документированы и поставляются со встроенным ST-Link отладчиком, но стоят заметно дороже альтернатив из поднебесной.

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

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

STM32 без бубна и танцев

Подключение и заливка прошивки

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

Самым удобным и универсальным способом будет использование отладчика ST-Link. Про альтернативные отладчики J-Link, Black Magic Probe и CMSIS-DAP я писать не буду, поскольку они не могут соперничать по распространённости с китайскими ST-Link, а если у вас вдруг есть такой отладчик, то ничего для вас нового я не напишу.

Второе место по удобству и первое по экономности занимает прошивка через USB, с использованием DFU (device firmware upgrade). Не так удобно, как прошивка через ST-Link, поскольку требует перезагрузки микроконтроллера и запуска встроенного загрузчика, но позволяет обойтись без дополнительных трат на ST-Link или USB-UART адаптер. К сожалению, этот способ доступен не только лишь всем и обладателям отладочных плат на F103 остается лишь грустно вздыхать.

Ещё одним универсальным способом будет прошивка через UART с использованием USB-UART адаптера (FT232R, CH340 и им подобные). Так же требует перезагрузки микроконтроллера и запуска встроенного загрузчика, но за то работает для всех STM32 микроконтроллеров.

В статьях по прошивке STM32 можно встретить названия программ ST-LINK utility, Flash loader demonstrator и DfuSe используемых для заливки прошивки через ST-Link, UART и USB. Они по-прежнему доступны для скачивания на сайте производителя, но там же можно заменить, что все три уже не рекомендуются для использования и заменены универсальной STM32CubeProgrammer.

Скачиваем и устанавливаем STM32CubeProgrammer, подключаем отладочную плату выбранным способом и проверяем, что драйвера на USB устройство установились. При подключении по UART и USB не забываем подключить ногу BOOT0 к 3V3.

STM32 без бубна и танцев

После этого запускаем STM32CubeProgrammer, выбираем нужный тип подключения и нажимаем кнопку "Connect". Если ничего не напутали с проводами, то через несколько секунд программа отрапортует об успешном подключении и покажет информацию об используемом микроконтроллере.

STM32 без бубна и танцев

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

Желающие могут сделать копию демонстрационной прошивки. Для этого в поле "Size" нужно указать размер флеш памяти микроконтроллера (для STM32F103ZE это 524288 или 0x80000), нажать на кнопку "Read" и дождаться окончания чтения данных и сохранить прошивку, выбрав пункт "Save As" в выпадающем меню.

STM32 без бубна и танцевПроцесс чтения прошивки из микроконтроллера не быстрый, особенно через UART, поэтому ждать желающих сделать резервную копию мы не будем и сразу перейдем к сборке Marlin. STM32CubeProgrammer закрываем, больше он нам не понадобится.

Сборка Marlin

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

В конфигурации Marlin есть специальный тип платы для работы с нестандартным железом, его мы и будем использовать. Для этого в Configuration.h прописываем

#define MOTHERBOARD BOARD_CUSTOM

Распиновка для данного типа платы берётся из отсутствующего файла Marlin\src\pins\pins_custom.h Отсутствует этот файл не случайно, а для предотвращения его перезаписи при обновлении кода.

Поскольку у нас не настоящий 3D принтер, а голая отладочная плата, то для создания минимально работающей конфигурации нужно определить 4 ноги микроконтроллера:

  • Нога, к которой подключен светодиод, который своим миганием будет показывать, что прошивка успешно запустилась.
  • Нога, с которой будет считываться состояние "концевиков", одна на всех. Я буду использовать одну из ног, к которым подключены пользовательские кнопки на отладочной плате. Это совершенно не обязательно, но так можно будет проверить, что состояние концевиков корректно считывается и продемонстрировать хоть какой-то работающий функционал.
  • Нога, на которую будут выдаваться управляющие сигналы для шаговых двигателей, нагревателей и вентилятора, тоже одна на всех. В моем случае это будет нога, на которой висит второй диод.
  • Нога, с которой будут считываться показания датчиков температуры. Так же одна на всех. Здесь выбор довольно ограничен, это должна быть не любая нога, а одна из тех, что могут работать как вход АЦП (ADC). Какие ноги для этого могут быть использованы можно найти в документации на микроконтроллер и в коде framework-arduinoststm32. В моем случае PA0, к которой на обеих платах подключена пользовательская кнопка.

STM32F103ZE и UART

Создаём файл Marlin\src\pins\pins_custom.h и заполняем его минимально необходимыми настройками

#define LED_PIN             PC0
#define DUMMY_IN            PF11
#define DUMMY_OUT           PD3
#define DUMMY_ADC           PA0
// Limit Switches
#define X_MIN_PIN           DUMMY_IN
#define Y_MIN_PIN           DUMMY_IN
#define Z_MIN_PIN           DUMMY_IN
// Steppers
#define X_STEP_PIN          DUMMY_OUT
#define X_DIR_PIN           DUMMY_OUT
#define X_ENABLE_PIN        DUMMY_OUT
#define Y_STEP_PIN          DUMMY_OUT
#define Y_DIR_PIN           DUMMY_OUT
#define Y_ENABLE_PIN        DUMMY_OUT
#define Z_STEP_PIN          DUMMY_OUT
#define Z_DIR_PIN           DUMMY_OUT
#define Z_ENABLE_PIN        DUMMY_OUT
#define E0_STEP_PIN         DUMMY_OUT
#define E0_DIR_PIN          DUMMY_OUT
#define E0_ENABLE_PIN       DUMMY_OUT
// Temperature Sensors
#define TEMP_0_PIN          DUMMY_ADC
#define TEMP_BED_PIN        DUMMY_ADC
// Heaters / Fans
#define HEATER_0_PIN        DUMMY_OUT
#define HEATER_BED_PIN      DUMMY_OUT
#define FAN0_PIN            DUMMY_OUT

Для сборки прошивок под плату BOARD_CUSTOM нужно использовать отсутствующее окружение [env:custom]. Для этого создаем файл ini\custom.ini и в файле platformio.ini в разделе [platformio] добавляем новый файл к параметру extra_configs. В том же разделе указываем, под какое окружение нужно производить сборку

STM32 без бубна и танцев

В файле ini\custom.ini создаем новое окружение для сборки под STM32F103ZE. Специального описания для платы Euse M3 DEMO нет, поэтому будет использоваться базовый вариант для этого микроконтроллера. Весь ассортимент доступных плат можно посмотреть в каталоге .platformio\platforms\ststm32\boards

[env:custom]
extends           = common_stm32
board             = genericSTM32F103ZE
build_flags       = ${common_stm32.build_flags}
upload_protocol   = serial

Это конфигурация для прошивки через UART. Если прошивка будет осуществляться чере ST-Link, то нужно указать это в параметрах загрузки.

upload_protocol   = stlink

Загрузчика, кроме встроенного, в отладочных платах нет, прошивка записывается стандартно, в начало флеш памяти, поэтому никакие дополнительные параметры не требуются. Прошивка всегда осуществляется через UART1 (PA9 и PA10), поэтому в Configuration.h укажем тот же порт.

#define SERIAL_PORT 1

На отладочной плате нет ни датчиков температуры, ни обвязки для них, и попытка считать значения температуры c АЦП может выдать чрезмерно высокие значения, что приведет к аварийной остановке прошивки. Что бы избежать этого поменяем типы датчиков хотенда и стола на 998, такой "датчик" всегда рапортует температуру в 25 градусов.

#define TEMP_SENSOR_0 998
#define TEMP_SENSOR_BED 998

Так же поменяем подтяжку концевиков, так как в описании плату для кнопок указано "Active high"

#define ENDSTOPPULLDOWNS

Если этого не сделать, то нажатие на кнопку не будет менять состояние концевиков.

Теперь можно переходить к сборке и заливке прошивки. Подключаем ногу BOOT0 к 3V3 с помощью джампера или соответствующей кнопки и перезагружаем плату.В PlatformIO нажимаем на кнопку "Upload" на расположенной внизу экрана "Status Bar" и терпеливо ждем окончания процесса.

STM32 без бубна и танцевSTM32 без бубна и танцев

Прошивка собрана, залита и весело мигает светодиодом.

STM32 без бубна и танцев

Возвращаем BOOT0 на землю, подключаемся к COM порту любимым терминалом и перезагружаем плату. Marlin загружается и снова начинает весело мигать. Командой M119 и кнопкой на плате проверяем работоспособность концевиков.

STM32 без бубна и танцев

Всё работает, но функциональности и  зрелищности как-то маловато. Добавим возможность подключаться по USB, поддержку SD карт и TFT экран, раз уж на плате под него отдельный разъём выделен.

В Configuration.h пропишем

#define SERIAL_PORT_2 -1
#define LCD_LANGUAGE ru
#define SDSUPPORT
#define TFT_GENERIC
#define TFT_INTERFACE_FSMC
#define TFT_RES_480x320
#define TFT_COLOR_UI
#define TFT_ROTATION TFT_ROTATE_270
#define TOUCH_SCREEN

Стоит напомнить, что использование виртуального COM порта (создаваемого при подключении платы по USB) для отладки прошивки подходит очень плохо. При каждой перезагрузке микроконтроллера соединение прерывается, а большинство (или даже все) программ-терминалов не умеют автоматически переподключаться при пропадании устройства. Оптимальным вариантом для отладки является внешний USB-UART адаптер, который позволит поддерживать устойчивое подключение и избежать потери данных от прошивки.

Ноги для подключения экрана определяются методом вдумчивого сравнения надписей на модуле экрана с распиновкой платы. SD карта на плате подключена с SDIO интерфейсу микроконтроллера, что так же надо указать в pins_custom.h

#define TFT_CS_PIN          PG12
#define TFT_RS_PIN          PG0
#define TFT_BACKLIGHT_PIN   PB0
#define TFT_RESET_PIN       PC5
#define TOUCH_INT_PIN       PF10
#define TOUCH_CS_PIN        PB2
#define TOUCH_MISO_PIN      PF8
#define TOUCH_MOSI_PIN      PF9
#define TOUCH_SCK_PIN       PB1
#ifndef SDCARD_CONNECTION
  #define SDCARD_CONNECTION              ONBOARD
  #define ONBOARD_SDIO                            // Use SDIO for onboard SD
#endif

У framework-arduinoststm32 модульная структура, и по-умолчанию модули для работы с SDIO и FSMC не подключаются. Подключить их можно добавив два параметра для сборки

build_flags       = ${common_stm32.build_flags}
                    -DHAL_SD_MODULE_ENABLED
                    -DHAL_SRAM_MODULE_ENABLED

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

#define EEPROM_SETTINGS

На обратной стороне платы Euse M3 DEMO есть место под установку микросхемы EEPROM, но сама микросхема не распаяна, поэтому для хранения настроек будем использовать флеш память микроконтроллера. Ресурс у флеш памяти микроконтроллера меньше, чем у EEPROM (10 тысяч циклов записи против 4 миллионов), но для хранения настроек его вполне достаточно. Для этого в pins_custom.h добавим соответствующий параметр

#define FLASH_EEPROM_EMULATION

Итоговая конфигурация для сборки под STM32F103ZE

ini/custom.ini

[env:custom]
extends           = common_stm32
board             = genericSTM32F103ZE
build_flags       = ${common_stm32.build_flags}
                    -DHAL_SD_MODULE_ENABLED
                    -DHAL_SRAM_MODULE_ENABLED
upload_protocol   = serial

pins_custom.h без DUMMY части, она осталась без изменений

#pragma once
#define DEFAULT_MACHINE_NAME "STM32F103ZET6"
#define FLASH_EEPROM_EMULATION
#define LED_PIN             PD3
#define DUMMY_IN            PF11
#define DUMMY_OUT           PC0
#define DUMMY_ADC           PA0
#define TFT_CS_PIN          PG12
#define TFT_RS_PIN          PG0
#define TFT_BACKLIGHT_PIN   PB0
#define TFT_RESET_PIN       PC5
#define TOUCH_INT_PIN       PF10
#define TOUCH_CS_PIN        PB2
#define TOUCH_MISO_PIN      PF8
#define TOUCH_MOSI_PIN      PF9
#define TOUCH_SCK_PIN       PB1
// Onboard SD support
#ifndef SDCARD_CONNECTION
  #define SDCARD_CONNECTION              ONBOARD
  #define ONBOARD_SDIO                            // Use SDIO for onboard SD
#endif

STM32F407ZE и DFU

Теперь перейдём к сборке прошивки под STM32F407ZE. Для этой платы есть собственное описание, в котором сразу включена поддержка SDIO, поэтому параметров для сборки понадобится меньше.

[env:custom]
extends           = common_stm32
board             = black_f407ze
build_flags       = ${common_stm32.build_flags}
                    -DHAL_SRAM_MODULE_ENABLED
upload_protocol   = dfu

Кнопки на плате работают в режиме "Active low", а экран для этой платы меньше и по-другому расположен. В Configuration.h нужно поправить соответствующие параметры

#define ENDSTOPPULLUPS
#define TFT_RES_320x240
#define TFT_ROTATION TFT_ROTATE_90

Так же у STM32F4 есть 4 килобайта RAM с питанием от установленной на плате батарейки. Эту память Marlin умеет использовать для хранения настроек, чем мы немедленно и воспользуемся

#define SRAM_EEPROM_EMULATION

Итоговый pins_custom.h без DUMMY части, она осталась без изменений

#pragma once
#define DEFAULT_MACHINE_NAME "STM32F407ZET6"
#define SRAM_EEPROM_EMULATION
#define LED_PIN             PF10
#define DUMMY_IN            PE4
#define DUMMY_OUT           PF9
#define DUMMY_ADC           PA0
#define TFT_CS_PIN          PG12
#define TFT_RS_PIN          PF12
#define TFT_BACKLIGHT_PIN   PB15
#define TOUCH_INT_PIN       PB1
#define TOUCH_CS_PIN        PC13
#define TOUCH_MISO_PIN      PB2
#define TOUCH_MOSI_PIN      PF11
#define TOUCH_SCK_PIN       PB0
// Onboard SD support
#ifndef SDCARD_CONNECTION
  #define SDCARD_CONNECTION              ONBOARD
  #define ONBOARD_SDIO                            // Use SDIO for onboard SD
#endif

Дальше всё аналогично предыдущей плате – BOOT0 к 3V3, перезагрузка и заливка прошивки. Как и в прошлом примере, не забываем возвращать BOOT0 на землю, когда не требуется обновление прошивки.

Прошивка через ST-Link немного проще, для неё не требуются манипуляции с BOOT0 и ручная перезагрузка.

STM32 без бубна и танцев

TL;DR

  • Marlin на отладочные платы STM32 ставится легко и быстро.
  • PlatformIO умеет прошивать отладочные STM32 используя ST-Link, UART или USB.
  • ST-Link – это удобно, но не обязательно. А для STM32F4 достаточно USB кабеля.

Подпишитесь на автора

Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых статьях.

Отписаться от уведомлений вы всегда сможете в профиле автора.

41
Комментарии к статье