Классическая ситуация. Записали через интерфейс SWD прошивку и... ничего не происходит. HeartBeat LED не мигает. Логи в UART(е) не появляются. CLI не отвечает. Вероятно прошивка где-то свалилась в Hard Fault Handler. Обратилась к несуществующей памяти. Что же делать? Как понять, где ошибка?

Можно конечно включать и исключать перед сборкой куски программы и прошивать пока не выясним ту проблемную функцию. Но это может занять очень много времени. Целый день.

Есть ли более эффективный способ? Да. Тут выручит пошаговая GDB отладка. А для этого надо настроить GDB сервер и GDB клиент.

Про пошаговую отладку в консоли у меня есть отдельный пост.

Однако пошаговая отладка в консоли может показаться утомительной. Куда проще пошагово отлаживаться прямо в текстовом редакторе, например в Eclipse.

Что надо из оборудования?

оборудование

Назначение

кабель USB-A USB micro

Для подключения программатора к NetTop PC

отладочная плата (например nrf5340-DK)

для пошаговой отладки прошивки в микроконтроллере

программатор J-Link

для пошаговой отладки микроконтроллера

LapTop

для запуска утилит

Что надо из софтвера?

Утилита

Назначение

JVM

Виртуальная машина для прокрутки текстового редактора eclipse

JLinkGDBServer.exe

GDB сервер

nrfjprog.exe

утилита, чтобы прошить микроконтроллер семейства nrf

arm-none-eabi-gdb.exe

GDB клиент

eclipse.exe

Текстовый редактор

Фаза 1. Установить GNU ToolChain для Arm Embedded

Подробнее про это тут

Надо прописать в переменную Path путь к ARM ToolChain(у): препроцессору, компилятору, асcембреру, компоновщику, binutils(ам), отладчику.

C:/Program Files (x86)/GNU Arm Embedded Toolchain/10 2021.10/bin

Проверить корректность установки GNU Toolchain можно выполнив команду arm-none-eabi-gcc --version в консоли Windows

Фаза 2. Запустить GDB Сервер Отладки

В качестве сервера отладки можно использовать утилиту JLinkGDBServer.exe.
C:\Program Files (x86)\SEGGER\JLink\JLinkGDBServer.exe

Можно даже накропать простенький скрипт, чтобы не настраивать каждый раз мышкой настройки JLink GDB Server(а)

 
echo off
cls
set GDBServerOpt = -select USB -device nRF5340_xxAA_APP -endian little -if SWD -speed 400 -ir -LocalhostOnly -logtofile -log "C:\projects\code_base_workspace\code_base_firmware\tool\GdbServerLog.txt"

set GDBServerDir="C:\Program Files (x86)\SEGGER\JLink\"
set GDBServerPath=%GDBServerDir%JLinkGDBServer.exe"
cd %GDBServerDir%
call %GDBServerPath% %GDBServerOpt%

В настройках JLink GDB Server(а) надо проверить интерфейс соединения с платой. В данной плате это USB. Проверить интерфейс соединения программатора и целевого микроконтроллера. В данной схемотехнике это SWD. Проверить, что выбрано нужное процессорное ядро. В данном случае это nRF5340_xxAA_APP. Если всё верно, то нажимаем ок.

JLink GDB Server переходит в режим ожидания подключения к GDB клиенту.

Вот примерный лог успешного подключения после запуска GDB клиента.

Фаза 3. Настройка GDB Клиента

Надо открыть меню Debug Configuration, создать конфигурацию и указывает путь к *.elf файлу

На вкладке Debugger указать путь к GDB клиенту arm-none-eabi-gdb.exe.

Можно прописать полный путь к GDB клиенту
C:\Program Files (x86)\GNU Arm Embedded Toolchain\10 2021.10\bin\arm-none-eabi-gdb.exe

Настроить вкладку Startup.

ставим, что надо остановиться на функции main

Настроить вкладку Common, как показано на скриншоте

Теперь достаточно нажать кнопку Debug и можно производить пошаговую отладку

получилась такая схема взаимодействия утилит

Вывод

Если говорить по честному, то всё, что требуется от пошаговой GDB отладки это максимум отладить запуск полнодуплексного UART. Далее просто подключается интерфейс командной строки и вся последующая отладка идет через UART-CLI.

А в CLI(Shell) как раз есть возможность прицельно вычитывать куски данных из физической памяти (регистры, RAM, Flash), искать адреса по значениям (аналог утилиты Art Money), читать и дергать GPIO, пулять пакеты в SPI, I2C, перезагружать ядро, запускать конкретные функции зная из адреса из *.map файла да и вообще делать всё, что только душа пожелает.

Словарь

Акроним

Расшифровка

CLI

Command-line interface

UART

universal asynchronous receiver-transmitter

LED 

light-emitting diode

RISC

reduced instruction set computer

JVM

Java virtual machine

PC

personal computer

UNIX

UNiplexed Information Computing System

ARM

Advanced RISC Machine

SWD

Serial Wire Debug

USB

Universal Serial Bus

GNU

GNU's Not UNIX

GDB

GNU Debugger 

Ссылки

https://bitknitting.wordpress.com/2015/07/11/using-eclipse-to-program-the-nrf51822/
https://dev.px4.io/v1.10_noredirect/en/debug/eclipse_jlink.html
https://eclipse-embed-cdt.github.io/debug/jlink/
https://habr.com/ru/company/rainbow/blog/251053/
https://habr.com/ru/post/215483/
https://habr.com/ru/post/578830/
https://habr.com/ru/post/673522/https://habr.com/ru/post/694708/https://habr.com/ru/post/694408/https://habr.com/ru/post/681280/
https://karibe.co.ke/2014/03/debugging-arm-freescale-microcontrollers-with-j-link-gdb-server-and-gnu-arm-toolchain-gdb-with-semihosting-in-linux/
https://mcuoneclipse.com/2019/09/22/eclipse-jtag-debugging-the-esp32-with-a-segger-j-link/
https://mcuoneclipse.com/2022/07/16/getting-started-raspberry-pi-pico-rp2040-with-eclipse-and-j-link/

Комментарии (4)


  1. progchip666
    00.00.0000 00:00
    +1

    Не люблю работу из консоли, но статья может быть полезна даже для меня. C учётом специфики нашего времени, того и глядишь с привычными IDE могут начаться проблемы.


    1. aabzel Автор
      00.00.0000 00:00

      Этот пост как раз про пошаговую отладку из IDE Eclipse.

      Про пошаговую отладку непосредственно в консоли у меня есть другой текст  https://habr.com/ru/post/694708/


  1. progchip666
    00.00.0000 00:00
    +1

    Сорри за ламерский вопрос. А точки возможность , возможность расставить точки останова, просмотр состояния переменных и регистров такая отладка не подразумевает?


    1. aabzel Автор
      00.00.0000 00:00
      -1

      Всё что требуется от пошаговой GDB отладки это запустить полнодуплексный UART. Далее подключается интерфейс командной строки
      https://habr.com/ru/post/694408/
      и вся последующая отладка идет через UART CLI.

      В UART-CLI как раз есть возможность прицельно вычитывать куски данных из физической памяти.