Программируем/отлаживаем микроконтроллеры STM32 при помощи OpenOCD и FT2232HL

14 ноября 2018

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, и все просто работает.

Метки: , .


Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.