8-900-374-94-44
[email protected]
Slide Image
Меню

Bootloader stm32: Микроконтроллер STM32 и Bootloader. Пример реализации.

Creating STM32 Arduino framework firmware with bootloader — #7 by sdemen

azarubkin

#1

Hi,

How do I create firmware using STM32 Arduino framework that is usable with bootloader? As far as I understand, I need to tell linker to shift the firmware to higher addresses. How can I do that? Should I just pass some flag to linker, or there’s some option that can be added to platformio.ini? Perhaps any examples?

My MCU is STM32F103CB.

1 Like

azarubkin

#2

I’ve noticed there’s upload_protocol = dfu option that, according to builder\frameworks\arduino\maple\stm32f1.

py sets appropriate linker script to offset the application to 0x8002000 address.

It apparently can be used with any bootloader, including custom. The only requirement is to fit the bootloader code in the freed ROM region. If it doesn’t fit, that file and bootloader script can be edited, though.

1 Like

azarubkin

#3

Does anyone know how to supply custom .ld file path to the linker to avoid editing the files supplied with PlatformIO?
I can put it into variant’s ld subfolder inside Arduino STM32 framework, but what about a subfolder inside a project folder?

azarubkin

March 17, 2018, 1:57pm

#4

Got it.
-Wl,-T./my.ld. The path is relative to project root dir.

azarubkin

#5

When I try to pass custom vector table start address by defining VECT_TAB_ADDR, I get the following error:

TypeError: unhashable type: 'list':
File "C:\.platformio\penv\lib\site-packages\platformio\builder\main.py", line 162:
env.SConscript("$BUILD_SCRIPT")
File "C:\.platformio\packages\tool-scons\script\..\engine\SCons\Script\SConscript.py", line 541:
return _SConscript(self.fs, *files, **subst_kw)
File "C:\.platformio\packages\tool-scons\script\..\engine\SCons\Script\SConscript.py", line 250:
exec _file_ in call_stack[-1].globals
File "C:\.platformio\platforms\ststm32\builder\main.py", line 127:
target_elf = env.BuildProgram()
File "C:\.platformio\packages\tool-scons\script\.
.\engine\SCons\Environment.py", line 224: return self.method(*nargs, **kwargs) File "C:\.platformio\penv\lib\site-packages\platformio\builder\tools\platformio.py", line 67: env.ProcessUnFlags(env.get("BUILD_UNFLAGS")) File "C:\.platformio\packages\tool-scons\script\..\engine\SCons\Environment.py", line 224: return self.method(*nargs, **kwargs) File "C:\.platformio\penv\lib\site-packages\platformio\builder\tools\platformio.py", line 173: all_flags = set(all_flags)

My platformio.ini file’s relevant portion:

build_flags = -Wl,-T./my.ld -v -DVECT_TAB_ADDR=134238208
build_unflags = -DVECT_TAB_ADDR=134217728

Adding a space between -D and VECT_TAB_ADDR doesn’t help.

azarubkin

#6

It was a bug, it’s fixed now for some time already.
No more questions

sdemen

#7

Добрый день…
Я правда на 401 и тоже из Ардуино попытался прыгнуть!
.
Потом в PlatformIO перешёл в Кубе.
Не помогло , похоже вектор прерывания не устанавливается!

Как его настроить?
Начал разбираться в Путоновских скриптах, но я больше С++ иАрдуино… пока не понял…
Спасибо…если прочитаете!

embedded — Совет по написанию кастомного загрузчика для stm32 MCU

Поскольку между B-1 и B-2 нет соединения gpio для активации режима загрузки для B-2, возможно ли, чтобы плата B-2 установила флаг во флэш-памяти за пределами области основного приложения, чтобы проверить его. и использовать его как флаг активации режима загрузки?

Я не уверен, что вы предлагаете, или как ваше предложение решит проблему. В идеале у вас должно быть средство формы B1 для прямого сброса B2 через его линию /RESET, но в противном случае, если он загружен приложением, которое принимает команду сброса или сигнал через RS-485, тогда вы можете затем выдать программный -reset для запуска загрузчика. На устройствах Cortex-M это можно сделать через NVIC.

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

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

Это, конечно, проблема с начальной загрузкой — что делать, если не загружено приложение, принимающее команду сброса, или приложение недействительно/завершено (прерывание программирования). Что ж, перемещенная область приложения будет иметь свою таблицу векторов, включая начальный SP и вектор сброса прямо в начале. В вашем загрузчике, когда получены первые 8 байт образа, вы удерживаете их и не программируете эту область, пока остальная часть образа не будет записана. При программировании вектора сброса последним, если программирование будет прервано, это местоположение не будет действительным адресом. Загрузчик может проверить его (или проверить, находится ли он в состоянии стирания), и, если он недействителен/записан, он может бесконечно ждать обновления или просто выполнить сброс, чтобы повторить опрос обновления. Однако имейте в виду, что здесь есть небольшая ошибка STM32 — большинство частей стирают флэш-память до состояния «все единицы» (0xFF), однако некоторые (части STM32Lxx) стирают до состояния «все нули». Конечно, вы можете просто проверить 0x00000000 или 0xffffffff, поскольку ни один из них не будет действительным начальным адресом, или явно проверить диапазон.

Можно ли записывать поток данных напрямую с входа uart в область флэш-памяти каждого приложения? вот так:

Да, но помните, что на STM32 обычно код выполняется из той же флэш-памяти, которую вы пытаетесь запрограммировать, и что шина останавливается во время записи и стирания флэш-памяти, так что если вы выполняете из флэш-памяти, выполнение останавливается. Для стирания страницы это может быть несколько миллисекунд, а для частей с большими страницами даже несколько сотен миллисекунд. Это может означать, что вы не можете прочитать символы на UART, если вы используете опрос или прерывание.

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

после того, как вы стерли и/или записали данные во флэш-память. XMODEM-1K является подходящим протоколом для этого, и, несмотря на его недостатки, его простота и поддержка в обычных приложениях-эмуляторах терминала делают его хорошим выбором для этого приложения.

Теперь, с учетом всего сказанного, вы можете увеличить флэш-память, доступную для B1, вообще не буферизируя образ для B2 на B1, и просто внедрить двунаправленную сквозную передачу, чтобы вход на UART B1 передавался непосредственно на Выход B1 RS-485 (конечно, также UART, поэтому название вашего порта неоднозначно), а вход B1 RS-485 передается непосредственно на выход UART. Таким образом, B1 станет «прозрачным», и будет казаться, что средство обновления взаимодействует напрямую с B2. Возможно, это намного проще и быстрее, и если загрузчик является «отказоустойчивым», как описано выше, он все равно будет разрешать повторные попытки после прерывания.

Функция сквозного доступа может быть частью приложения B1 или «режимом» загрузчика. Сквозной режим может быть вызван определенной командой загрузки, или приложение может передать команду «режим загрузки» через механизм SRAM, описанный ранее.

В любом случае в идеале у вас должен быть одинаковый код загрузчика на B1 и B2 для простоты и гибкости. Нет причин, по которым этого не должно быть; они оба получают обновления через UART.

STM32: Начало работы с библиотекой загрузчика

Требования
  1. Загрузите и установите stlink_setup.exe и добавьте путь к переменным среды
    C:\Program Files (x86)\STMicroelectronics\STM32 ST-LINK Utility\ST- LINK Утилита
  2. Клонировать репозиторий.
    клон git https://github.com/BuildStormTechnologies/stm32_bootloader_library
Соединения

Загрузчик и приложение используют UART2 (PA2, PA3) для обновления прошивки и печати журналов устройства.

Настройка теста
  1. Откройте командную строку, измените рабочий каталог на клонированный репозиторий.
    компакт-диск stm32_bootloader_library/кли-инструмент
  2. Подключите устройство с помощью USB-to-serial и запишите COM-порт.
  3. Убедитесь, что USB-to-Serial подключен к UART2 Stm32 (PA2 и PA3).
  4. Запустите команду
    stm32UpdateTool-win.exe
    например, stm32UpdateTool-win.exe COM7
  5. Инструмент CLI напечатает поддерживаемые команды, как показано ниже.

 

Тестирование загрузчика

  • Двоичный файл загрузчика доступен в папке .\binaries , и он жестко запрограммирован в инструменте CLI. Для прошивки загрузчика пользователю не нужно указывать путь.
  • Два двоичных файла приложения доступны для тестирования в папке .\binaries . Для прошивки приложения необходимо указать путь к двоичному файлу приложения. CLI также позволяет запускать пользовательское приложение, предоставляя абсолютный путь к приведенным ниже командам.
    • flash all <путь к файлу приложения> Будет прошит загрузчик из .\binaries\bootloader.bin и приложение из указанного пути.
    • flash app <путь к файлу приложения> Это запустит только приложение из указанного пути.
Прошивка загрузчика и приложения
  1. Прошивка загрузчика и приложения с помощью команды flash all, как показано ниже.
    прошить все .\binaries\application_v200.bin
  2. CLI позаботится о перепрошивке загрузчика и приложения один за другим.
  3. После успешного обновления прошивки устройство распечатает номера версий. Обратите внимание на номер версии и схему светодиодов.

Прошить только приложение
  1. В предыдущем разделе мы прошивали загрузчик и приложение v200, на этот раз нужно прошить только приложение.
    флеш-приложение .\binaries\application_v201.bin
  2. После успешного обновления обратите внимание на изменение версии прошивки и схемы светодиодов

Пример пользовательского приложения

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

Карта памяти и настройки компоновщика
Тип Адрес размер Количество секторов Индекс сектора
Загрузчик 0x08000000 14КБ 1 0
Конфигурация загрузчика 0x08004000 16КБ 1 1
Применение 0x08010000 448 КБ 4 4 – 7
Временный раздел загрузки 0x08070000 512 КБ 4 8 – 11
Настройки компоновщика

Приложение находится по адресу 0x08010000, и его необходимо настроить в настройках компоновщика, как показано ниже.

 ПАМЯТЬ
{
  CCMRAM (xrw): ORIGIN = 0x10000000, LENGTH = 64K
  RAM (xrw): ORIGIN = 0x20000000, LENGTH = 128K
  FLASH (rx): ORIGIN = 0x8010000, LENGTH = 448K
} 

 

Включить библиотеки

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

Включить объектный файл

Включить предварительно скомпилированный объектный файл в проект.

Скрипт после сборки

Конечный двоичный файл приложения будет зашифрован с помощью исполняемого скрипта (BS_ENCRYPT.exe). Его необходимо добавить в настройки проекта.

Двоичный файл приложения

Окончательный зашифрованный двоичный файл приложения будет сгенерирован в папке Debug как projectName_release.bin. Этот файл можно использовать для обновлений встроенного ПО Serial/OTA.

Поддерживаемые контроллеры

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

  • СТМ32Ф407
  • СТМ32Ф413
  • СТМ32Ф429

Лицензирование и индивидуальные решения

Бесплатное использование библиотеки ограничено 20 циклами загрузки. Она предназначена только для тестирования и демонстрации.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *