OpenOCD (Open On-Chip Debugger) — это открытое ПО для программирования и отладки различного железа. Допустим, к вашему компьютеру подключен один из программаторов, поддерживаемых проектом. OpenOCD позволяет сходить через программатор в некий микроконтроллер или FPGA , используя такой протокол, как JTAG или SWD. В качестве более конкретного примера, рассмотрим, как OpenOCD может быть использован для прошивки и отладки микроконтроллеров STM32 .

В качестве программатора было решено использовать плату на базе чипа FT2232HL. Ранее такая плата была использована в статье Реверс-инжиниринг роутера на примере GL.iNet GL-AR750 для чтения SPI flash. Напомню, как она выглядит:

Плата на базе FT2232HL

OpenOCD поддерживает и другие программаторы, не исключая STLink/v2. FT2232HL был выбран по той причине, что он более универсален, то есть, работает не только с STM32. Кроме того, он может быть использован для одновременного хождения в микроконтроллер как по SWD, так и UART. Таким образом, плата предоставляет функционал, аналогичный функционалу STLink/v2-1 . Только, в отличие от последнего, FT2232HL и платы на его основе продаются где угодно.

Fun fact! Существует аналогичная, но куда более компактная плата, имеющая разъем Micro USB. Называется FT2232H-56Q Mini Module. Но и цена такой платы составляет ~40$ против ~15$ за ту плату, что использовал я. Документация на плату со схемой и всяким таким находится здесь [PDF] .

Подключение к отладочной плате (я использовал LimeSTM32 ) производится так:

FT2232HL           STM32
————       ———
GND           <—> GND
3V3           <—> 3V3
ADBUS0        <—> SWCLK
ADBUS2        <—> SWDIO
CDBUS0* (TX2) <—> RX
CDBUS1* (RX2) <—> TX

ADBUS1  <—> R, 470 Ohm <—+
|
ADBUS2  <——————+

Художество в конце намекает нам на то, что ADBUS1 и ADBUS2 следует соединить через резистор на 470 Ом. Все остальное должно быть понятно и так.

Важно! (*) Как выяснилось, маркировка на данной плате не соответствует настоящему расположению пинов. В частности, пины, обозначенные, как CDBUS0 и CDBUS1, в действительности являются BDBUS0 (пин 38) и BDBUS1 (пин 39) соответственно. Учитывайте это, если решите использовать другую плату.

Далее создаем файл ftdi.cfg следующего содержания:

interface ftdi
transport select swd
ftdi_vid_pid 0x0403 0x6010
ftdi_layout_init 0x0018 0x05fb
ftdi_layout_signal SWD_EN -data 0
ftdi_layout_signal nSRST -data 0x0010

Запускаем OpenOCD из корня проекта:

sudo openocd -f . / ftdi.cfg -f target / stm32f4x.cfg

Второй файл создавать не нужно. OpenOCD сам найдет его в /usr/share/openocd.

Оставляем OpenOCD работать, во втором терминале говорим:

telnet localhost 4444

Чтобы прошить микроконтроллер, в telnet’е выполняем команды:

> reset halt
> flash write_image erase build/main.hex
> reset

Чтобы каждый раз не открывать несколько терминалов, все написанное выше можно сделать одной командой:

sudo openocd -f . / ftdi.cfg -f target / stm32f4x.cfg -c
«init; reset halt; flash write_image erase build/main.hex; »
«reset; exit»

Заметьте, что в этом случае мы вынуждены явно выполнять команду init .

Одновременно с прошивкой микроконтроллера по SWD, мы можем ходить по UART, используя файл /dev/ttyUSB1 и какой-нибудь screen . Удобно.

Также мы можем воспользоваться отладчиком. Для этого в одном терминале запускаем OpenOCD, а во втором говорим:

arm-none-eabi-gdb build / main.elf

В отладчике выполняем команды:

(gdb) target remote localhost:3333
(gdb) monitor reset halt

Теперь мы можем отлаживать прошивку, как обычно. Например, сказать:

(gdb) b main.c:123
(gdb) c

А чтобы каждый раз не вводить много команд, можно просто дописать где-нибудь в Makefile:

arm-none-eabi-gdb build / main.elf
-ex ‘target remote localhost:3333’
-ex ‘monitor reset halt’

Подробности об использовании GDB ищите в заметке Памятка по отладке при помощи GDB .

Вот и вся наука! Чтобы постоянно не возиться с проводами и резисторами, понятно, можно один раз спаять подходящий переходник. Лично я в последнее время предпочитаю использовать разъемы IDC-12 и соответствующие кабели. Один конец втыкается в отладочную плату, второй — в переходник с FT2232HL, и все просто работает.

EnglishRussianUkrainian