← На главную

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

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