Русский
Русский
English
Статистика
Реклама

Полноценная GDB отладка через USB на плате BluePill (STM32F103С8T6)

В данной статье речь пойдет о программировании и полноценной отладке микроконтроллера STM32F103C8T6 через USB.

Однажды, от коллег поступило предложение о участии в IoT проекте. Система предусматривала однопоточный запуск скриптов. Отладка производилась с помощью логов. И тут мне в голову пришла мысль о полноценной удаленной отладке проектов под микроконтроллеры.

Для начала нужно было опробовать все на прототипе. В качестве отладочной платы была выбрана почти всем знакомая BluePill на микроконтроллере STM32F103. Поскольку на данной отладке имеется интерфейс MicroUSB, было принято решение в прототипе использовать именно этот интерфейс. В будущем предполагался переход на UART подключенный к GSM модулю.

Требовалось реализовать загрузчик имеющий несколько функциональных блоков. Задачу на подзадачи и решать их последовательно. Рассмотрим их.

  1. Драйвер интерфейса USB со стороны микроконтроллера.

  2. Код обновления прошивки микроконтроллера с помощью GDB.

  3. GDB сервер.

  4. Вывод отладочных логов.

Обо все по порядку. Для прототипирования был реализован загрузчик (bootloader).

1. Первым был реализован протокол отладочного интерфейса. Т.е. USB. В качестве класса USB-устройств был выбран WinUSB. Для его реализации я использовал воспользовался исходным кодом библиотеки libopencm3. Для этого необходимо описать дескриптор устройства, дескрипторы конфигурации, интерфейса, конечных точек, а так же дескрипторы содержащие стоки "MSFT100" и "WINUSB". Последние два дескриптора требуются для определения устройства как WinUSB. Конфигурация конечных точек (USB-Endpoint) выбрана следующим образом control endpoint 0, bulk out endpoint 1, bulk in endpoint 81, bulk in endpoint 82. Конечная точка с номером ноль присутствует во всех устройствах USB, endpoint 1- применяется для передачи команд в загрузчик микроконтроллера, endpoint 81 - для передачи ответов на команды на компьютер, а 82 - для передачи текстовой информации (логов). Подробнее о USB можно прочитать в публикациях из разряда USB in a NutShell.

2. Требовался код работы с флеш памятью. Вы можете подумать что тут все просто. Это так и не так одновременно. Первая проблема, которая возникла,- невозможность стереть флеш память в обработчике прерывания. Дело в том, что архитектура Cortex M предусматривает два режима работы процессора. Thread и Handler. В первом режиме процессор находится после старта, а так же когда нет активных прерываний. В Handler mode исполняются все обработчики исключений и прерываний. К сожалению, стирание flash-памяти на STM32F103C8T6 в Handler режиме приводит к корректному статусу стирания памяти, но сама память не стирается.

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

Другая проблема является более сложной. Заключается она в том, что при работе с флеш памятью может происходить выполнение обработчика прерывания, той прошивки, которая находится под отладкой. Эта проблема решается несколькими действиями перед стиранием памяти. Первое что требуется сделать,- заблокировать вызов любых обработчиков прерываний, используемых в отлаживаемой прошивке. Или проще говоря тех, которые не используются в Bootloader-e. Но даже в этом случае команда на стирание памяти может поступить в то время, когда один из обработчиков уже выполняется. Для решения этого вопроса и решил воспользоваться пошаговым режимом работы процессора и в таком режиме вывести процессор из всех обработчиков прерываний. После этого флеш-память можно стирать.

3. Требовалось реализовать GDB-сервер. Я воспользовался исходным кодом проекта BlackMagic, для обработки команд приходящих из среды разработки. На самом деле приходящих от приложения arm-none-eabi-gdb. Далее команды транслировались в команды бинарного протокола, который используется для п процессе взаимодействия с микроконтроллером. Нижний уровень GDB-сервера выполнен с использованием библиотеки WinUSB.

4. После того как прототип заработал, я пришел к решению добавить вывод отладочной информации с использованием printf. Для передачи отладочных сообщений использовал endpoint 82. На самом деле 8 - это единица в старшем разряде, указывающая направление передачи данных по шине USB в сторону компьютера (Host-а).

Но таким образом функцией printf можно было пользоваться только в bootloader-е. А как же быть с отлаживаемым приложением? Обычно для взаимодействия с операционной системой используются прерывания/системные вызовы. Так BIOS использова int13, ms-dos int21. Мы же на микроконтроллере воспользуемся системным вызовом, т.е. командой svc. При выполнении данной команды в прошивке, будет вызван обработчик прерывания SVC, находящийся в bootloader-е. Что нам и требовалось сделать.

Bootloader использует 10Kb flash памяти, но зарезервировано 16Kb с целью расширения функционала. Так же используется 4K оперативной памяти. Оперативная память применяется для хранения буферов USB, контекста прерванного процесса, а так же как память стека обработчиков прерываний. Итого. Остается 16Kb из 20Kb оперативной памяти и 48Kb flash памяти. Хотя на самом деле flash-память в контроллере STM32F103C8T6 не 64Kb а 128Kb,- соответственно остается 112Kb.

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

И наконец, - что поддерживается:

  1. Загрузка прошивки на плату с использованием GDB. Т.е. непосредственно из среды программирования/отладки. В моем случае это STM32CubeIDE. Адрес вектора прерываний должен находится по адресу 0x8004000.

  2. Просмотр и изменение памяти.

  3. Просмотр и изменение регистров периферии.

  4. Восемь точек останова.

  5. Режим пошаговой отладки.

  6. Принудительная остановка.

В отлаживаемой прошивке нельзя изменять адрес вектора обработчика прерываний. Нельзя изменять приоритеты прерываний. Приоритет должен быть выше или равен 0x40 по значению. Нельзя запрещать прерывания systick, прерывание usb, и прерывания DebugMon, SvcHandler, а так же всех FaultHandler-s.

Код прототипа проекта доступен по ссылке

Видео работы с платой в среде STM32CubeIDE

Источник: habr.com
К списку статей
Опубликовано: 09.03.2021 18:08:33
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Отладка

Программирование микроконтроллеров

Gdb

Usb

Stm32

Arm

Cortex

Bluepill

Debug

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru