Эта статья (перевод документации [1]) предоставляет руководство по установке OpenOCD для ESP32 и отладке с помощью GDB.
Замечание: вы можете также отлаживать свой код ESP32 необходимости настраивать JTAG или OpenOCD, если используете idf.py monitor. См. IDF Monitor [3] и описание опции проекта CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME.
ESP32 имеет на борту два мощных ядра Xtensa, позволяющих применять многие программные архитектуры. FreeRTOS, поставляемая вместе с ESP-IDF, способна реализовать многопоточное вытесняющее планирование выполнение кода (multi-core preemptive scheduling), обеспечивая интуитивно-понятный способ написания кода программы.
Обратной стороной упрощения программирования становится усложнение поиска ошибок, связанных с взаимодействием потоков в программе (синхронизацией). Нахождение бага, вызванного двумя потоками, одновременно на двух разных ядрах CPU cores, может занять много времени, когда все, что у вас есть это только операторы printf(). Более эффективный (и во многих случаев быстрый) способ отладки подобных проблем - использование отладчика, подключенного к процессорам через порт отладки.
У компании Espressif есть портированая OpenOCD для поддержки процессора ESP32 и многоядерной FreeRTOS (которая является основой большинства приложений ESP32). Кроме того, были написаны некоторые дополнительные инструменты для предоставления расширенных функций, которые OpenOCD изначально не поддерживает.
В этом документе описывается установка OpenOCD для ESP32 и отладка с помощью GDB под операционными системами Linux, Windows и macOS. За исключением специфики инсталляции операционной системы, программный пользовательский интерфейс и используемые процедуры отладки остаются одинаковыми на всех операционных системах. Могут быть небольшие отличия в зависимости от используемых Windows, macOS или Linux, и/или разных релизов Eclipse.
[Как это работает?]
На следующем рисунке показаны ключевые программные и аппаратные компоненты, обеспечивающие отладку кода ESP32 с помощью OpenOCD через интерфейс JTAG, обозначенные меткой "Отладка через JTAG". Эти компоненты включают отладчик xtensa-esp32-elf-gdb debugger, встроенный в чип отладчик OpenOCD и JTAG-адаптер, подключенный к отлаживаемому процессору (ESP32 target).
Рис. 1. Основная структура системы JTAG-отладки ESP32.
Метка "Загрузка и мониторинг приложения" показывает ключевые программные и аппаратные компоненты, реализующие компиляцию, сборку и прошивку кода в ESP32, а также предоставление мониторинга диагностических сообщений из ESP32.
"Отладка через JTAG" и "Загрузка и мониторинг приложения" интегрированы в Eclipse IDE, чтобы предоставить быстрые переходы между написанием/компиляцией/загрузкой/отладкой кода. Eclipse IDE (и интегрированное ПО отладки) доступны на платформах Windows, Linux и macOS. В зависимости от ваших предпочтений, вместо Eclipse можно использовать и отладчик, и idf.py build непосредственно из командной строки терминала.
Если используется плата разработчика ESP-WROVER-KIT [4], то соединение между PC и ESP32 осуществляется одним кабелем USB. В качестве моста используется чип FT2232H, на котором предоставляются 2 канала USB, один для JTAG, и другой для UART.
[Выбор адаптера JTAG]
Самый быстрый и наиболее удобный способ познакомиться с JTAG-отладкой - использовать ESP-WROVER-KIT [4]. Каждая версия этой отладочной платы содержит на борту интерфейс JTAG, и не понадобится никаких дополнительных кабелей и внешних JTAG-адаптеров для подключения JTAG к ESP32. ESP-WROVER-KIT использует JTAG-интерфейс на основе FT2232H, и этот интерфейс работает на частоте тактов 20 МГц, что сложно достигнуть с внешним адаптером.
Если вы решили использовать отдельный JTAG-адаптер, обратите внимание на те из них, которые будут совместимы как по уровням напряжений сигналов ESP32, так и совместимы с ПО OpenOCD. Порт JTAG на ESP32 соответствует индустриальному стандарту JTAG, в котором отсутствует (и в нем нет необходимости) вывод TRST. Сигналы JTAG I/O все получают питание от вывода VDD_3P3_RTC (на который нормально должно приходить питание от шины 3.3V), так что адаптер JTAG должен быть способен работать с такими уровнями сигналов (3.3V поддерживают большинство JTAG-адаптеров).
Что касается ПО, OpenOCD поддерживает достаточное количество JTAG-адаптеров, см. [5] (однако к сожалению это не совсем полный список). Также на страничке [5] перечислены SWD-совместимые адаптеры; имейте в виду, что ESP32 не поддерживает SWD. Не будут работать с ESP32 JTAG-адаптеры, жестко привязанные к определенной линейке процессоров, например отладчики ST-LINK для семейства STM32.
Минимальный набор сигналов для работоспособного JTAG-соединения это TDI, TDO, TCK, TMS и GND. Некоторые JTAG-отладчики также требуют подключения к шине питания ESP32, например для этого может использоваться сигнал наподобие Vtar - он нужен для определения рабочего напряжения интерфейса. Сигнал SRST может опционально подключаться к CH_PD чипа ESP32, хотя в настоящий момент поддержка в OpenOCD для этого сигнала весьма минимальна.
ESP-Prog [6] это пример использования внешней платы для отладки, путем подключения её к выводам JTAG чипа ESP32.
[Настройка OpenOCD]
Если вы уже установили ESP-IDF вместе с системой сборки CMake в соответствии с руководством Getting Started [7], то OpenOCD уже установлена. После настройки рабочего окружения в терминале (запуска скрипта export.sh) вы сможете запустить OpenOCD. Проверьте это следующей командой:
$ source ~/esp/v5.4.1/esp-idf/export.sh
$ openocd --version
Open On-Chip Debugger v0.12.0-esp32-20241016 (2024-10-16-14:17)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Вы также можете проверить, что OpenOCD знает, где находятся её конфигурационные скрипты, путем вывода значения переменной окружения OPENOCD_SCRIPTS. Для этого на Linux и macOS введите команду:
$OPENOCD_SCRIPTS
На Windows введите команду:
%OPENOCD_SCRIPTS%
Если в результате будет выведен каталог, где находятся конфигурационные скрипты, то OpenOCD установлена корректно.
$ ls $OPENOCD_SCRIPTS
bitsbytes.tcl cpldfpga memory.tcl test boardcpuinterface mmr_helpers.tcl tools chip esp-config.json mem_helper.tcl target
Если описанные выше команды не работают, то обратитесь к секции установки утилит руководства [7] (для Linux и macOS), или используйте ESP-IDF Tools Installer (для Windows, также см. [7]).
Примечание: также можно скомпилировать OpenOCD из исходного кода, см. далее раздел "Сборка OpenOCD из исходного кода".
Когда OpenOCD установлена, вы можете приступить к конфигурированию ESP32 target (т. е. используемой связки из платы ESP32 и интерфейса JTAG). Конфигурирование target разделено на 3 шага:
• Конфигурирование и подключение интерфейса JTAG. • Запуск OpenOCD. • Выгрузка приложения для отладки.
Конфигурирование и подключение интерфейса JTAG. Этот шаг зависит от используемых вами адаптера JTAG и платы. В качестве направляющего руководства рассмотрите следующие примеры:
Запуск OpenOCD. Когда target сконфигурирована и подключена к компьютеру, все готово к запуску OpenOCD.
Откройте терминал и настройте его для использования ESP-IDF, как описано в соответствующей секции (Step 4. Set up the Environment Variables) руководства быстрого старта [7] (эта настройка заключается в запуске скрипта export.sh командой наподобие source ~/esp/v5.4.1/esp-idf/export.sh).
Чтобы запустить OpenOCD для определенной платы, вы должны передать в команду openocd специальную конфигурацию для этой платы. Конфигурация по умолчанию для собранного проекта ESP-IDF можно найти в поле debug_arguments_openocd файла build/project_description.json. Вот пример запуска OpenOCD для платы ESP-WROVER-KIT (эта команда будет работать на Windows, Linux и macOS):
openocd -f board/esp32-wrover-kit-3.3v.cfg
Файлы, предоставляемые после -f в этой команде, специфичны для ESP-WROVER-KIT с модулем ESP32-WROOM-32. Вам может понадобиться предоставить другие файлы в зависимости от используемого железа, см секцию "Configuration of OpenOCD for Specific Target" документации [8].
Для модуля ESP32-WROOM-32 на плате разработчика ESP-WROVER-KIT вы должны увидеть лог наподобие:
user-name@computer-name:~/esp/esp-idf$ openocd -f board/esp32-wrover-kit-3.3v.cfg
Open On-Chip Debugger v0.10.0-esp32-20190708 (2019-07-08-11:04)
Licensed under GNU GPL v2
For bug reports, read
https://openocd.org/doc/doxygen/bugs.html
none separate
adapter speed: 20000 kHz
force hard breakpoints
Info : ftdi: if you experience problems at higher adapter clocks, try the command
"ftdi_tdo_sample_edge falling"
Info : clock speed 20000 kHz
Info : JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica),
part: 0x2003, ver: 0x1)
Info : JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica),
part: 0x2003, ver: 0x1)
Info : esp32: Debug controller was reset (pwrstat=0x5F, after clear 0x0F).
Info : esp32: Core was reset (pwrstat=0x5F, after clear 0x0F).
Если вы увидели ошибку, показывающую проблему привилегий доступа, см. секцию "Permissions delegation" в файле OpenOCD README (находится в каталоге openocd-esp32).
Если ошибка заключается в нахождении файлов конфигурации, например openocd не может найти board/esp32-wrover-kit-3.3v.cfg, то проверьте корректность установки переменой окружения OPENOCD_SCRIPTS. Эту переменную OpenOCD использует для определения базового каталога для файлов конфигурации, указываемых опцией -f. Также проверьте, что файл конфигурации действительно находится по указанному пути.
В случае ошибок JTAG проверьте его подключения, правильно ли сигналы JTAG подключены к соответствующими выводам ESP32, и правильно ли подано питание.
Выгрузка приложения для отладки. Выполните сборку и прошивку приложения в ESP32, как обычно (командой idf.py flash -p ИМЯ_ПОРТА, см. [7]).
Другой способ записать образ приложения в память flash заключается в использовании OpenOCD и JTAG с помощью команды наподобие следующей:
image_file - путь до файла программируемого образа. offset - смещение в банке flash для записи образа. verify - необязательная опция. Задает проверку содержимого flash после записи. reset - необязательная опция. Сбросит target после программирования. exit - необязательная опция. Приводит к выходу из OpenOCD после программирования. compress - необязательная опция. Сжимает файл образа перед программированием. encrypt - необязательная опция. Шифрует двоичный файл перед записью во flash. Такой же функционал, что и у команды idf.py encrypted-flash. no_clock_boost - необязательная опция. Запретит перед программированием установку частоты тактов target на её максимальное возможное значение. По умолчанию разрешено ускорение тактирования (clock boost). restore_clock - необязательная опция. После программирования восстановит частоту тактов в свое первоначальное значение. По умолчанию это запрещено.
Теперь все готово к запуску отладки, примеры настройки и запуска сессии отладки см. в [2]. Пример настройки отладки в среде Visual Studio Code см. в [9]. Рекомендуется сначала проверить работоспособность отладчика в командной строке [2], а потом перейти к запуску отладки в среде Eclipse или Visual Studio Code.
[Примеры отладки]
Эта секция предназначена для пользователей, которые не знакомы с GDB. По ссылкам ниже представлен пример сессии отладки из Eclipse с использованием простого приложения get-started/blink, и описываются следующие действия:
Замечание: здесь описывается вариант использования OpenOCD способом его сборки из исходников вместо того, чтобы загрузить уже скомпилированный двоичный код. Для быстрой установки пользователи могут загрузить предварительно скомпилированный бинарник OpenOCD с сайта Espressif GitHub (https://github.com/espressif/openocd-esp32/releases) вместо того, чтобы компилировать его самостоятельно.
Все куски кода в этом описании подразумеваются запускаемыми на Windows в среде шелла MSYS2 подсистемы MINGW32.
[Установка зависимостей]
Для компиляции OpenOCD установите необходимые пакеты:
Вариант исходного кода OpenOCD, где разрешена отладка ESP32, доступен в репозитории на Espressif GitHub, см. https://github.com/espressif/openocd-esp32. Файлы исходного кода могут быть загружены клонированием репозитория следующими командами:
cd ~/esp
git clone --recursive https://github.com/espressif/openocd-esp32.git
Теперь файлы исходного кода должны быть сохранены в директории ~/esp/openocd-esp32.
[Загрузка libusb]
Для сборки OpenOCD также необходима библиотека libusb. Следующие команды загрузят архив определенного релиза libusb, и распакуют её файлы в секущую директорию.
wget https://github.com/libusb/libusb/releases/download/v1.0.22/libusb-1.0.22.7z
7z x -olibusb ./libusb-1.0.22.7z
Теперь нам нужно экспортировать следующие переменные, чтобы библиотека libusb линковалась со сборкой OpenOCD.
После завершения сборки бинарник OpenOCD будет находиться в папке ~/esp/openocd-esp32/src/.
Опционально вы можете вызвать команду make install. Она скопирует бинарник OpenOCD в указанное пользователем размещение.
Замечания:
• Размещение бинарника OpenOCD может быть указано, когда выполняется конфигурирование сборки OpenOCD, либо путем установки переменной окружения export DESTDIR="/custom/install/dir" перед выполнением команды make install. Если у вас уже есть установленная OpenOCD (например для другой платформы разработки), то вы возможно захотите пропустить шаг make install, потому что это может перезаписать существующую OpenOCD. • При возникновении ошибки исправьте её и попробуйте запустить компиляцию снова, пока команда make не выполнится. • Если есть проблема субмодуля из OpenOCD, командой cd перейдите в каталог openocd-esp32 и введите команду git submodule update --init. • Если команда ./configure запустится успешно, информация о разрешенном интерфейсе (enabled JTAG) будет напечатана в разделе OpenOCD configuration summary. • Если в логе не показана информация вашего устройства, используйте ./configure для его разрешения, как это описано в файле ../openocd-esp32/doc/INSTALL.txt. • Дополнительную информацию по компиляции OpenOCD см. в файле openocd-esp32/README.Windows. • Не забудьте сделать копию libusb-1.0.dll и libwinpthread-1.dll в папку OOCD_INSTALLDIR/bin из ~/esp/openocd-esp32/src.
После успешного завершения компиляции исполняемый exe-файл OpenOCD будет сохранен в директории ~/esp/openocd-esp32/src.
[Полный листинг компиляции]
Для удобства ниже приведен листинг выполняемых команд компиляции. Вы можете копировать эти команды и использовать их напрямую или после необходимой модификации.
Следующие инструкции могут использоваться как альтернатива для загрузки бинарного кода OpenOCD с сайта Espressif GitHub.
[Загрузка исходного кода OpenOCD]
Вариант исходного кода OpenOCD, где разрешена отладка ESP32, доступен в репозитории на Espressif GitHub, см. https://github.com/espressif/openocd-esp32. Файлы исходного кода могут быть загружены клонированием репозитория следующими командами:
cd ~/esp
git clone --recursive https://github.com/espressif/openocd-esp32.git
Теперь файлы исходного кода должны быть сохранены в директории ~/esp/openocd-esp32.
[Установка зависимостей]
Для компиляции OpenOCD установите необходимые пакеты.
Замечание: устанавливайте пакеты по одному, выполняя следующие команды поочередно, каждый раз проверяя результат установки, и затем переходите к следующему пакету. Возникающие проблемы решайте до перехода к установке следующего пакета.
• Версия pkg-config должна быть 0.2.3 или более свежая. • Версия autoconf должна быть 2.6.4 или более свежая. • Версия automake должна быть 1.9 или более свежая. • Когда в качестве адаптеров используются USB-Blaster, ASIX Presto, OpenJTAG и FT2232, должны быть загружены и установлены драйверы libFTDI и FTD2XX. • При использовании CMSIS-DAP необходима библиотека HIDAPI.
[Сборка OpenOCD]
Конфигурирование и сборка осуществляются командами:
$ cd ~/esp/openocd-esp32
$ ./bootstrap
$ ./configure
$ make
Опционально вы можете добавить последним шагом команду sudo make install. Пропустите этот шаг, если у вас уже есть установленная OpenOCD (например для другой платформы отладки), поскольку она может быть перезаписана командой make install.
Замечания:
• При возникновении ошибки исправьте её и попробуйте запустить компиляцию снова, пока команда make не выполнится. • Если есть проблема субмодуля из OpenOCD, командой cd перейдите в каталог openocd-esp32 и введите команду git submodule update --init. • Если команда ./configure запустится успешно, информация о разрешенном интерфейсе (enabled JTAG) будет напечатана в разделе OpenOCD configuration summary. • Если в логе не показана информация вашего устройства, используйте ./configure для его разрешения, как это описано в файле ../openocd-esp32/doc/INSTALL.txt. • Дополнительную информацию по компиляции OpenOCD см. в файле openocd-esp32/README.
После успешного завершения компиляции исполняемый файл OpenOCD будет сохранен в директории ~/openocd-esp32/bin.
Показанные примеры команд запуска OpenOCD подразумевают, что вы используете двоичный установленный дистрибутив.
Чтобы использовать бинарники, собранные локально из исходного кода, поменяйте пути исполняемого файла OpenOCD на src/openocd, и установите переменную окружения OPENOCD_SCRIPTS так, чтобы OpenOCD смогла найти конфигурационные файлы. Для Linux и macOS:
$ cd ~/esp/openocd-esp32
$ export OPENOCD_SCRIPTS=$PWD/tcl
Для Windows:
> cd %USERPROFILE%\esp\openocd-esp32
> set "OPENOCD_SCRIPTS=%CD%\tcl"
Пример запуска OpenOCD, собранной из исходников, для Linux и macOS:
$ src/openocd -f board/esp32-wrover-kit-3.3v.cfg
То же самое для Windows:
> src\openocd -f board\esp32-wrover-kit-3.3v.cfg
Дополнительные подсказки и советы по запуску отладки см. в [8].
[Ссылки]
1. JTAG Debugging site:docs.espressif.com. 2. ESP-IDF: использование отладчика. 3. IDF Monitor site:docs.espressif.com. 4. ESP-WROVER-KIT v4.1 Getting Started Guide site:docs.espressif.com. 5. Debug Adapter Hardware site:openocd.org. 6. Introduction to the ESP-Prog Board site:docs.espressif.com. 7. ESP-IDF Get Started site:docs.espressif.com. 8. JTAG Debug Tips and Quirks site:docs.espressif.com. 9. VScod Debug Your Project.