Загрузчик размещается в начале основной FLASH-памяти микроконтроллера и занимает две страницы по 4 кБ, то есть 8 кБ. Это необходимо учитывать при линковке основной (загружаемой) программы. Она должна начинаться с адреса 0x8002000 и занимать до 0x1E000 (122880) байт.
DFU (Device Firmware Upgrade) – механизм обновления встроенного программного обеспечения устройств, поддерживающих USB. Он определяет порядок взаимодействия хоста и устройства при передаче новой версии прошивки и позволяет обновлять ее без подключения внешнего программатора.
Во время обновления устройство временно прекращает выполнять свои основные функции и переходит в режим программирования памяти. Например, устройство, которое в обычном режиме работает как измерительный прибор, на время обновления предоставляет хосту интерфейс для записи новой прошивки.
DFU определяет набор USB-дескрипторов, управляющих запросов и состояний, необходимых для обновления. Хост передает образ прошивки блоками, а устройство записывает их в энергонезависимую память. Упрощенная схема сеанса DFU представлена на рисунке 1.
Для реализации стороны хоста можно использовать утилиту dfu-util, она позволяет обнаруживать подключенные устройства, передавать в них образы прошивок, а также считывать содержимое памяти.
Рисунок 1 – Упрощенная схема сеанса DFU
2. Описание проекта
Структура проекта:
source/ – основные исходные и заголовочные файлы загрузчика, включая конфигурационные;
library/ – Библиотеки CMSIS и SPL (версия 1.5.0 от 01.07.2025), некоторые файлы изменены – это необходимо учитывать при переносе проекта или замене библиотеки;
fw/ – образы загрузчика в формате BIN и HEX, а также бинарный файл прошивки для мигания светодиодом PB7;
tb/ – скрипты и утилиты для тестирования;
MDR32FxQI_dfu_uv5/ – проект для IDE Keil uVision 5;
MDR32FxQI_dfu_IAR/ – проект для IDE IAR Embedded Workbench for ARM;
MDR32FxQI_dfu_eclipse/ – проект для IDE Eclipse Embedded CDT.
Загрузчик размещается в начале основной FLASH-памяти и занимает две страницы. Для микроконтроллера К1986ВЕ92x размер страницы составляет 4 кБ, поэтому под загрузчик отводится 8 кБ. Основная программа должна начинаться с 0x08002000 и занимать не более 0x1E000 байт (120 кБ). Ограничений на использование RAM загрузчик не накладывает.
При расширении функциональности размер загрузчика может увеличиться. В этом случае под него необходимо выделить целое число страниц FLASH-памяти, достаточное для размещения образа, а затем скорректировать начальный адрес и доступный размер области основной программы.
Архив с загрузчиком содержит исходные файлы и три проекта для следующих сред разработки:
Таблица 1 – Проекты для различных сред разработки
Среда разработки
Каталог проекта
Keil µVision 5
MDR32FxQI_dfu_uv5/
IAR Embedded Workbench for Arm
MDR32FxQI_dfu_IAR/
Eclipse Embedded CDT
MDR32FxQI_dfu_eclipse/
Перед открытием проекта необходимо распаковать архив с сохранением структуры каталогов. Папки source/ и library/ используются проектами совместно, поэтому переносить только каталог выбранной среды разработки отдельно от остальных файлов не следует.
3. Механизм работы загрузчика
При запуске загрузчик переходит в режим обновления прошивки, если выполняется хотя бы одно из следующих условий:
в основной FLASH-памяти отсутствует программа (проверяется корректность указателя стека и вектора сброса);
на выводе DFU_BTN_PIN порта DFU_BTN_PORT, заданного в файле dfu_config.h (по умолчанию PB6), установлен логический уровень, соответствующий режиму работы загрузчика;
установлен программный флаг перехода в режим загрузчика (специальное значение в заранее выбранной ячейке SRAM или регистре BKP.
Механизм хранения и обработки флага зависит от особенностей конечного устройства, поэтому функция is_bootloader_flag_set в файле source/main.c реализована как заглушка. Для использования этого способа необходимо самостоятельно выбрать место хранения и значение флага, а также реализовать его проверку в загрузчике.
Если ни одно из перечисленных выше условий не выполнено, начинает выполняться основная программа.
Для индикации состояния загрузчика используется светодиод (по умолчанию PB7), который задается в файле source/dfu_config.h. После конфигурирования устройства хостом светодиод горит постоянно, сигнализируя о готовности загрузчика к работе. Если питание подано, но устройство не сконфигурировано, светодиод мигает с частотой 1 Гц.
Опрос вывода входа в режим загрузчика и светодиодная индикация необязательны. Их можно изменить или удалить из проекта.
4. Настройка загрузчика
Параметры загрузчика задаются в файле source/dfu_config.h и представлены в таблице 2. Изменения вступают в силу после повторной сборки проекта.
Таблица 2 – Параметры загрузчика
Параметр
Назначение
BOOTLOADER_VERSION_MAJOR
Старшая часть номера версии загрузчика
BOOTLOADER_VERSION_MINOR
Младшая часть номера версии загрузчика
DFU_VID
Идентификатор производителя
DFU_PID
Идентификатор устройства
FINISH_BY_METHOD
0
Загрузчик переходит из состояния DFU_STATE_MANIFEST_SYNC в DFU_STATE_IDLE и ожидает следующих команд. Утилита dfu-util инициирует сброс USB только при наличии ключа -R
1
Загрузчик переходит из состояния DFU_STATE_MANIFEST_SYNC в DFU_STATE_MANIFEST_WAIT_RESET. Утилита dfu-util обнаруживает это состояние и инициирует сброс USB независимо от наличия ключа -R
CAN_WRITE_FW
0
Запись запрещена
1
Запись разрешена
CAN_READ_FW
0
Чтение запрещено
1
Чтение разрешено
DFU_BTN_PORT
DFU_BTN_PIN
DFU_BTN_PCLK
Вывод, опрашиваемый для входа в режим DFU
DFU_BTN_STATE_FOR_DFU
Логический уровень на выводе, при котором активируется режим DFU
DFU_LED_PORT
DFU_LED_PIN
DFU_LED_PCLK
Вывод, к которому подключен светодиод
DFU_LED_ACTIVE_STATE
Логический уровень включения светодиода
DFU_SUPPORT_FOR_INFORMATIONAL_EEPROM
0
Доступна только основная память (Internal FLASH)
1
Доступна основная (Internal FLASH) и информационная память (Internal EEPROM)
BOOTLOADER_SIZE
Размер области FLASH-памяти, выделенной под загрузчик
При объявлении SKIP_EEPROM_CALIB_INFO_PROTECTION в source/MDR32FxQI_config.h отключается реализованная в SPL программная защита сектора A информационной памяти от стирания. В результате становится доступна перезапись всей информационной памяти.
Сохранность заводских настроек в этом случае должен обеспечить пользователь.
Стирание FLASH-памяти выполняется постранично, поэтому запись даже одного байта в страницу, содержащую калибровочные значения, приведет к их удалению при стирании этой страницы. Перед записью необходимо считать заводские калибровочные значения в файл, объединить их с данными, которые нужно записать в информационную память.
Готовый бинарный файл загрузчика собран со следующими параметрами: source/dfu_config.h
Для корректной работы программы, загружаемой через DFU-загрузчик необходимо настроить проект так, чтобы код размещался в области памяти, не пересекающейся с загрузчиком.
Если настройки расположения загрузчика в памяти не менялись, то основная (загружаемая) программа должна размещаться следующим образом:
Начальный адрес FLASH: 0x08002000;
Размер области основной программы: 0x1E000.
Настройка проекта в Keil uVision 5:
1. Необходимо открыть свойства проекта.
2. Перейти во вкладку «Target».
3. В области IROM1 указать следующие значения (рисунок 2):
Start – 0x8002000
Size – 0x1E000
Область IRAM1 изменять не нужно.
Рисунок 2 – Свойства проекта, вкладка «Target»
4. Во вкладке «Linker» необходимо установить галочку «Use Memory Layout from Target Dialog» (рисунок 3), чтобы компоновщик использовал параметры, заданные во вкладке «Target».
Рисунок 3 – Свойства проекта, вкладка «Linker»
5. Для загрузки прошивки через DFU-загрузчик, она должна быть в бинарном формате. Файл HEX или ELF необходимо предварительно преобразовать в BIN. Чтобы это происходило автоматически после каждой сборки проекта, надо открыть вкладку «User», в разделе «After Build/Rebuild» установить галочку «Run #1» и напротив нее в поле «User Command» ввести команду fromelf.exe --bin --output="@L.bin" "!L" (рисунок 4).
Рисунок 4 – Свойства проекта, вкладка «User»
6. Далее необходимо собрать проект. После сборки в папке проекта будет создан файл прошивки в формате BIN.
Настройка проекта в Eclipse IDE for Embedded C/C++ Developers:
Создание и базовая настройка проекта описаны в статье Установка IDE Eclipse.
1. Необходимо открыть используемый проектом скрипт компоновщика.
Путь к нему указывается в настройках проекта C/C++ Build -> Settings -> GNU Arm Cross C Linker -> General.
В разделе MEMORY надо задать для области FLASH следующие параметры:
2. Для автоматического создания BIN-файла после сборки проекта требуется открыть настройки проекта «C/C++ Build -> Settings -> Build Steps» и в «Post-build steps» добавить команду arm-none-eabi-objcopy -O binary "${BuildArtifactFileName}" "${BuildArtifactFileBaseName}.bin" (рисунок 2). Рисунок 2 – Настройка автоматического создания BIN-файла
3. После применения настроек требуется выбрать в меню «Project» и нажать «Clean».
В открывшемся окне надо выбрать проект и установить галочки, как на рисунке 3. Рисунок 3 – Очистка результатов предыдущей сборки проекта и повторная сборка
После нажатия на кнопку «Clean» начнется очистка и новая сборка проекта. После окончания сборки в папке со сборкой появится файл прошивки с расширением .bin.
1. Необходимо открыть настройки проекта, выбрать раздел «Linker» и открыть вкладку «Config». Затем установить галочку «Override default» и нажать кнопку «Edit» (рисунок 2). Рисунок 2 – Настройка конфигурации компоновщика
2. В открывшемся окне во вкладке Vector Table в поле .intvec start необходимо указать адрес 0x08002000 (рисунок 3). Рисунок 3 – Настройка начального адреса таблицы векторов
Затем перейти во вкладку «Memory Regions» и задать для области ROM следующие значения (рисунок 4):
Start – 0x08002000;
End – (0x08000000+0x0001E000-1).
Рисунок 4 – Настройка области памяти основной программы
Параметры области RAM изменять необязательно. После внесения изменений необходимо нажать «Save» и сохранить файл конфигурации компоновщика.
3. Для автоматического создания файла прошивки в формате BIN необходимо выбрать раздел «Output Converter», установить галочку «Generate additional output» и в выпадающем списке «Output format» выбрать «Raw binary» (рисунок 5). Рисунок 5 – Настройка автоматического создания бинарного файла прошивки
4. После сохранения настроек необходимо выполнить повторную сборку проекта (перед этим желательно очистить результаты предыдущей сборки). Файл прошивки с расширением .bin будет создан в подкаталоге Exe выбранной конфигурации сборки, например Debug/Exe.
6. Подготовка к работе с DFU-загрузчиком
При подключении устройства в режиме загрузчика к компьютеру под управлением Windows ему автоматически должен назначиться стандартный драйвер WinUSB. Устройство должно появиться в диспетчере устройств (рисунок 6). Рисунок 6 – Диспетчер устройств
При необходимости драйвер WinUSB можно заменить на libusbK с помощью программы Zadig. Ее можно скачать с сайта https://zadig.akeo.ie/. Программу нужно запустить с правами администратора. В меню «Options» требуется выбрать пункт «List All Devices», после чего отобразятся все устройства, подключенные к ПК. В списке устройств необходимо выбрать Milandr <название_микроконтроллера> in DFU mode, далее выбрать драйвер libusbK и нажать кнопку «Replace Driver» (рисунок 7). По завершении установки драйвера программа отобразит окно с соответствующим сообщением.
Рисунок 7 – Смена драйвера в Zadig
При выборе драйвера следует учитывать, что WinUSB не позволяет инициировать программный сброс на шине USB. Если после обновления прошивки требуется сброс, следует использовать драйвер libusbK.
Для чтения и программирования памяти можно использовать утилиту dfu-util.
7. Работа с dfu-util
Обнаружение устройств в режиме DFU
Для вывода списка подключенных к компьютеру устройств в режиме DFU используется команда:
dfu-util -l
Пример вывода:
dfu-util 0.11
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
Found DFU: [1209:2e05] ver=0100, devnum=9, cfg=1, intf=0, path="1-1", alt=1, name="Internal EEPROM", serial="00000001"
Found DFU: [1209:2e05] ver=0100, devnum=9, cfg=1, intf=0, path="1-1", alt=0, name="Internal FLASH", serial="00000001"
При DFU_SUPPORT_FOR_INFORMATIONAL_EEPROM = 1 в выводе dfu-util отображаются два DFU-интерфейса, они относятся к одному устройству и предоставляют доступ к определенной области памяти:
alt=0, Internal FLASH – основная память;
alt=1, Internal EEPROM – информационная память.
Программирование FLASH-памяти:
Для записи файла example.bin в основную память микроконтроллера, надо выполнить команду:
dfu-util -a 0 -D example.bin
Параметр -a 0 выбирает интерфейс DFU по его alt-номеру, в данному случае используется Internal FLASH.
Пример вывода:
dfu-util 0.11
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
Warning: Invalid DFU suffix signature
A valid DFU suffix will be required in a future dfu-util release
Opening DFU capable USB device...
Device ID 1209:2e05
Device DFU version 0110
Claiming USB DFU Interface...
Setting Alternate Interface #0 ...
Determining device status...
DFU state(2) = dfuIDLE, status(0) = No error condition is present
DFU mode device DFU version 0110
Device returned transfer size 1024
Copying data from PC to DFU device
Download [=========================] 100% 122880 bytes
Download done.
DFU state(6) = dfuMANIFEST-SYNC, status(0) = No error condition is present
DFU state(6) = dfuMANIFEST-SYNC, status(0) = No error condition is present
DFU state(2) = dfuIDLE, status(0) = No error condition is present
Done!
Чтение FLASH-памяти:
Команда:
dfu-util -a 0 -U flash.bin
Вывод:
dfu-util 0.11
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
Opening DFU capable USB device...
Device ID 1209:2e05
Device DFU version 0110
Claiming USB DFU Interface...
Setting Alternate Interface #0 ...
Determining device status...
DFU state(2) = dfuIDLE, status(0) = No error condition is present
DFU mode device DFU version 0110
Device returned transfer size 1024
Copying data from DFU device to PC
Upload [=========================] 100% 122880 bytes
Upload done.
Received a total of 122880 bytes
Контактная информация
Сайт:
https://support.milandr.ru
E-mail:
support@milandr.ru
Телефон:
+7 495 221-13-55
Вся представленная в настоящей статье информация предназначена для демонстрации возможностей продукции компании АО «ПКК Миландр» и оказания технической помощи в ее освоении. Компания «Миландр» не возражает против частичного или полного использования данной информации в проектах потребителей без каких-либо дополнительных гарантий и обязательств со стороны компании «Миландр». В случае обнаружения неточностей или ошибок в представленной информации необходимо написать на support@milandr.ru