OpenOCD (Open On-Chip Debugger) — это открытое ПО для программирования и отладки различного железа. Допустим, к вашему компьютеру подключен один из программаторов, поддерживаемых проектом. OpenOCD позволяет сходить через программатор в некий микроконтроллер или FPGA , используя такой протокол, как JTAG или SWD. В качестве более конкретного примера, рассмотрим, как OpenOCD может быть использован для прошивки и отладки микроконтроллеров STM32 .
В качестве программатора было решено использовать плату на базе чипа FT2232HL. Ранее такая плата была использована в статье Реверс-инжиниринг роутера на примере GL.iNet GL-AR750 для чтения SPI flash. Напомню, как она выглядит:
OpenOCD поддерживает и другие программаторы, не исключая STLink/v2. FT2232HL был выбран по той причине, что он более универсален, то есть, работает не только с STM32. Кроме того, он может быть использован для одновременного хождения в микроконтроллер как по SWD, так и UART. Таким образом, плата предоставляет функционал, аналогичный функционалу STLink/v2-1 . Только, в отличие от последнего, FT2232HL и платы на его основе продаются где угодно.
Fun fact! Существует аналогичная, но куда более компактная плата, имеющая разъем Micro USB. Называется FT2232H-56Q Mini Module. Но и цена такой платы составляет ~40$ против ~15$ за ту плату, что использовал я. Документация на плату со схемой и всяким таким находится здесь [PDF] .
Подключение к отладочной плате (я использовал LimeSTM32 ) производится так:
———— ———
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 следующего содержания:
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 из корня проекта:
Второй файл создавать не нужно. OpenOCD сам найдет его в /usr/share/openocd.
Оставляем OpenOCD работать, во втором терминале говорим:
Чтобы прошить микроконтроллер, в telnet’е выполняем команды:
> flash write_image erase build/main.hex
> reset
Чтобы каждый раз не открывать несколько терминалов, все написанное выше можно сделать одной командой:
«init; reset halt; flash write_image erase build/main.hex; »
«reset; exit»
Заметьте, что в этом случае мы вынуждены явно выполнять команду init
.
Одновременно с прошивкой микроконтроллера по SWD, мы можем ходить по UART, используя файл /dev/ttyUSB1 и какой-нибудь screen . Удобно.
Также мы можем воспользоваться отладчиком. Для этого в одном терминале запускаем OpenOCD, а во втором говорим:
В отладчике выполняем команды:
(gdb) monitor reset halt
Теперь мы можем отлаживать прошивку, как обычно. Например, сказать:
(gdb) c
А чтобы каждый раз не вводить много команд, можно просто дописать где-нибудь в Makefile:
-ex ‘target remote localhost:3333’
-ex ‘monitor reset halt’
Подробности об использовании GDB ищите в заметке Памятка по отладке при помощи GDB .
Вот и вся наука! Чтобы постоянно не возиться с проводами и резисторами, понятно, можно один раз спаять подходящий переходник. Лично я в последнее время предпочитаю использовать разъемы IDC-12 и соответствующие кабели. Один конец втыкается в отладочную плату, второй — в переходник с FT2232HL, и все просто работает.