Программирование ARM ESP-IDF: JTAG-отладка Fri, July 04 2025  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


ESP-IDF: JTAG-отладка Печать
Добавил(а) microsin   

Эта статья (перевод документации [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).

ESP IDF JTAG debugging overview

Рис. 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  cpld             fpga            memory.tcl       test
board cpu interface mmr_helpers.tcl tools
chip esp-config.json mem_helper.tcl target

Если описанные выше команды не работают, то обратитесь к секции установки утилит руководства [7] (для Linux и macOS), или используйте ESP-IDF Tools Installer (для Windows, также см. [7]).

Примечание: также можно скомпилировать OpenOCD из исходного кода, см. далее раздел "Сборка OpenOCD из исходного кода".

[Конфигурирование целевого процессора (ESP32 target)]

Когда OpenOCD установлена, вы можете приступить к конфигурированию ESP32 target (т. е. используемой связки из платы ESP32 и интерфейса JTAG). Конфигурирование target разделено на 3 шага:

• Конфигурирование и подключение интерфейса JTAG.
• Запуск OpenOCD.
• Выгрузка приложения для отладки.

Конфигурирование и подключение интерфейса JTAG. Этот шаг зависит от используемых вами адаптера JTAG и платы. В качестве направляющего руководства рассмотрите следующие примеры:

Configure ESP-WROVER-KIT JTAG Interface
Configure Other JTAG Interfaces

Запуск 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 с помощью команды наподобие следующей:

openocd -f board/esp32-wrover-kit-3.3v.cfg -c "program_esp filename.bin 0x10000 verify exit"

Команда прошивки OpenOCD program_esp имеет следующий формат:

program_esp < image_file> < offset> [verify] [reset] [exit] [compress] [encrypt]

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, и описываются следующие действия:

1. Навигация по коду, стек вызовов функций (Call Stack) и потоки (Threads).
2. Установка и очистка точек останова (Breakpoints).
3. Остановка процессора вручную.
4. Пошаговое выполнение кода.
5. Просмотр и редактирование памяти.
6. Просмотр и установка переменных программы.
7. Установка точек останова, срабатывающих по условию (Conditional Breakpoints).

Аналогичные действия по отладке доступны в командной строке GDB [2].

Замечание: отладка объектов FreeRTOS в настоящий момент возможна только из командной строки GDB.

[Сборка OpenOCD из исходного кода]

Выполните следующие шаги для компиляции OpenOCD, в зависимости от используемой операционной системы:

Замечание: здесь описывается вариант использования OpenOCD способом его сборки из исходников вместо того, чтобы загрузить уже скомпилированный двоичный код. Для быстрой установки пользователи могут загрузить предварительно скомпилированный бинарник OpenOCD с сайта Espressif GitHub (https://github.com/espressif/openocd-esp32/releases) вместо того, чтобы компилировать его самостоятельно.

Все куски кода в этом описании подразумеваются запускаемыми на Windows в среде шелла MSYS2 подсистемы MINGW32.

[Установка зависимостей]

Для компиляции OpenOCD установите необходимые пакеты:

pacman -S --noconfirm --needed autoconf automake git make \
  mingw-w64-i686-gcc \
  mingw-w64-i686-toolchain \
  mingw-w64-i686-libtool \
  mingw-w64-i686-pkg-config \
  mingw-w64-cross-winpthreads-git \
  p7zip

[Загрузка исходного кода 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.

export CPPFLAGS="$CPPFLAGS -I${PWD}/libusb/include/libusb-1.0"
export LDFLAGS="$LDFLAGS -L${PWD}/libusb/MinGW32/.libs/dll"

[Сборка OpenOCD]

Следующие команды выполнят конфигурирование OpenOCD, и затем её сборку.

cd ~/esp/openocd-esp32
export CPPFLAGS="$CPPFLAGS -D__USE_MINGW_ANSI_STDIO=1 -Wno-error"; \
 export CFLAGS="$CFLAGS -Wno-error"
./bootstrap
./configure --disable-doxygen-pdf --enable-ftdi --enable-jlink --enable-ulink \
 --build=i686-w64-mingw32 --host=i686-w64-mingw32
make
cp ../libusb/MinGW32/dll/libusb-1.0.dll ./src
cp /opt/i686-w64-mingw32/bin/libwinpthread-1.dll ./src

После завершения сборки бинарник 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.

[Полный листинг компиляции]

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

pacman -S --noconfirm --needed autoconf automake git make mingw-w64-i686-gcc \
 mingw-w64-i686-toolchain mingw-w64-i686-libtool mingw-w64-i686-pkg-config \
 mingw-w64-cross-winpthreads-git p7zip
cd ~/esp
git clone --recursive https://github.com/espressif/openocd-esp32.git

wget https://github.com/libusb/libusb/releases/download/v1.0.22/libusb-1.0.22.7z 7z x -olibusb ./libusb-1.0.22.7z export CPPFLAGS="$CPPFLAGS -I${PWD}/libusb/include/libusb-1.0"; export \ LDFLAGS="$LDFLAGS -L${PWD}/libusb/MinGW32/.libs/dll"
export CPPFLAGS="$CPPFLAGS -D__USE_MINGW_ANSI_STDIO=1 -Wno-error"; \ export CFLAGS="$CFLAGS -Wno-error" cd ~/esp/openocd-esp32 ./bootstrap ./configure --disable-doxygen-pdf --enable-ftdi --enable-jlink --enable-ulink \ --build=i686-w64-mingw32 --host=i686-w64-mingw32 make cp ../libusb/MinGW32/dll/libusb-1.0.dll ./src cp /opt/i686-w64-mingw32/bin/libwinpthread-1.dll ./src
# # необязательные команды # export DESTDIR="$PWD" # make install # cp ./src/libusb-1.0.dll $DESTDIR/mingw32/bin # cp ./src/libwinpthread-1.dll $DESTDIR/mingw32/bin

Следующие инструкции могут использоваться как альтернатива для загрузки бинарного кода 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 установите необходимые пакеты.

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

sudo apt-get install make
sudo apt-get install libtool
sudo apt-get install pkg-config
sudo apt-get install autoconf
sudo apt-get install automake
sudo apt-get install texinfo
sudo apt-get install libusb-1.0

Замечания:

• Версия 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.

 

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


Защитный код
Обновить

Top of Page