В этой статье описывается, как прошивать микроконтроллеры (MCU) на ядре ARM с использованием отладчика OpenOCD и адаптера на микросхеме FT2232H (перевод [1]).
Широко распространенные, давно появившиеся на рынке MCU наподобие PIC16F и ATmega от таких производителей, как ATMEL и MICROCHIP, снабжены специальным интерфейсом для программирования внутренней энергонезависимой памяти программ и данных (flash, eeprom). Например, ATmega используют выводы SPI (MISO, MOSI, SCK), иногда JTAG, иногда специальный однопроводный интерфейс debugWire. PIC используют 2 вывода (PGC, PGD) - один для тактов, и другой как двунаправленную линию данных.
Новые MCU, особенно на основе ядра ARM, используют JTAG/SWD в качестве интерфейса для программирования и отладки.
В чем разница между интерфейсами Joint Test Action Group (JTAG) и Serial Wire Debug (SWD)? Ответ: SWD был создан как альтернатива JTAG для экономии выводов корпуса MCU: SWD заменяет 5-сигнальный JTAG на интерфейс, который требует только 2 сигнала.
Чтобы осуществить обмен данными с целевым MCU, нам нужна программа на хосте (например, хостом может быть компьютер PC с операционной системой Windows) и некий аппаратный адаптер, служащий мостом между хостом и MCU. В этом руководстве описывается, как использовать OpenOCD в качестве программы на хосте, применяемой для отправки команд и обмена данными через SWD. В качестве моста будет использоваться FT2232H, чтобы транслировать сигналы порта USB в интерфейс SWD.
AP означает порт доступа (Access Port).
AHB-AP здесь AHB означает продвинутую высокоскоростную шину (Advanced High-performance Bus), это внутренняя шина ядра Cortex.
SWCLK сигнал тактов SWD.
SWDIO сигнал данных SWD.
SW-DP Serial Wire Debug Port.
[Обзор OpenOCD]
ПО Open On-Chip Debugger (OpenOCD [3]) является бесплатным, открытым (open-source) проектом, который предназначен для отладки, внутрисхемного программирования и технологии пограничного сканирования (boundary scan, проверка целостности электрических соединений в сложных электронных схемах) с помощью адаптера отладки. Адаптер это аппаратный модуль, который предоставляет правильные логические сигналы, чтобы их понимало целевое устройство (MCU).
Отладчик OpenOCD "из коробки" поддерживает несколько видов адаптеров отладки, список которых можно найти на сайте OpenOCD [2] (также см. [3]).
Чтобы OpenOCD заработал, нужно его сконфигурировать командами или с помощью конфигурационных файлов. Когда конфигурация завершена, и установлено соединение с целевым MCU, программное обеспечение OpenOCD запустится как сервис (daemon). Это фоновый процесс, который обслуживает запросы для управления целевым MCU. После этого OpenOCD будет ждать соединений со стороны GDB, Telnet, или по другому каналу, и будет обрабатывать поступающие команды.
Conf это конфигурационные файлы, которые описывают адаптер, целевой процессор и особенности отладочной платы, на которой процессор установлен.
Log вывод для пользователя диагностической информации.
[Обзор FT2232H]
Микросхема FT2232H это высокоскоростной двухканальный преобразователь интерфейсов [6]. Каждый из каналов оборудован аппаратурой Multi-Protocol Synchronous Serial Engine (MPSSE). MPSSE может преобразовать трафик USB в передачу данных по различным интерфейсам UART/FIFO (в зависимости от того, как FT2232H сконфигурирован и как используется). Таким образом, одно подключение USB может быть преобразовано в 2 интерфейсных порта.
[Что следует иметь в виду при выборе OpenOCD]
Выбор OpenOCD в качестве инструментария отладки с адаптером FT2232H - очень хорошее решение, когда у Вас ограниченный бюджет. В дополнение к тому, что пакет OpenOCD бесплатен и имеет открытый исходный код, у него есть хорошая поддержка комьюнити пользователей.
Однако, как это часто бывает с бесплатным и открытым ПО, с OpenOCD Вы можете столкнуться с некоторыми багами, и будьте готовы к тому, что их потребуется исправить самостоятельно. Автору статьи [1] потребовалось некоторое время, чтобы запустить OpenOCD и научиться прошивать свой MCU, и он надеется, что это руководство послужит Вам хорошим и полным руководством.
Если же Вам нужен простой инструмент, то скорее всего OpenOCD не подойдет. Есть и другие альтернативы:
• Segger J-Link [4] • ULINK [4] • Отладчики, часто по умолчанию встраиваемые в оценочные платы разработчика (evaluation boards) разными поставщиками MCU (наподобие STM32, EFM32 и т. д.).
[Что потребуется для OpenOCD]
Вам понадобятся:
• FT2232H breakout board (любая отладочная плата, на которой установлен чип FT2232H). • Windows или Linux с установленной рабочей копией OpenOCD. • Целевой MCU с памятью flash, которую Вы собираетесь программировать.
Давайте теперь разберемся с каждым из этих компонентов по отдельности.
FT2232H breakout board. Такую платку можно без проблем купить на китайских сайтах наподобие Taobao, Alibaba, AliExpress или dx.com по цене порядка $14. Также очень хорошо подойдет плата FT2232H Board [7].
Также можно купить официальную плату компании FTDI, FT2232H Mini-Module [8], но скорее всего она обойдется дороже.
Windows. Можно получить исполняемую версию OpenOCD из неофициальных сборок [9].
Linux. OpenOCD можно загрузить из пула пакетов Вашего дистрибутива Linux, наподобие пакета для debian [10]. Также можно собрать OpenOCD из исходного кода, но этот метод подойдет скорее всего только для знатоков. Как выполнить сборку, в Интернете есть несколько руководств. Например, на сайте Dangerous Prototypes (для Windows) [11] или eLinux (для Linux) [12]. Также можно прочитать инструкции по компиляции в распространяемом пакете исходного кода OpenOCD (файлы README.Windows и README).
Замечание: с некоторых пор команда разработчиков OpenOCD решила больше не предоставлять официальные сборки двоичного исполняемого кода. Они предоставляют только исходный код, подразумевая при этом, что поставщики оборудования JTAG выполнят сборку самостоятельно и адаптируют эту сборку под свои адаптеры JTAG. Убедитесь, что Ваша сборка поддерживает используемый адаптер JTAG.
[Запуск OpenOCD на примере EFM32G200F32]
Автор использовал плату с микроконтроллером EFM32G200F32, это микроконтроллер ARM на ядре Cortex-M3, однако будет работать и любой другой поддерживаемый MCU.
Ножка
Мнемоника
Сигнал
25
PF0
LETIM0_OUT0#2 / DBG_SWCLK#0/1
26
PF1
LETIM0_OUT1#2 / DBG_SWDIO#0/1
27
PF2
ACMP1_0#0 / DBG_SWO#0
Как организована OpenOCD. Чтобы запустить OpenOCD, Вам просто нужен правильный конфигурационный файл (.cfg), один из тех, которые поставляются вместе с OpenOCD. Этот конфигурационный файл содержит набор команд, которые являются расширениями команд языка Jim-Tcl. Это язык программирования, который предоставляет простой и расширяемый интерпретатор команд.
Каталог инсталляции OpenOCD имеет папку scripts. В этой папке можно увидеть дочерние папки interface, board и target. Скорее всего Вам понадобятся для рассмотрения только эти папки.
interface: здесь содержатся файлы конфигурации для аппаратных адаптеров, например minimodule.cfg.
board: конфигурационные файлы для широко известных плат разработчика (т. е. плат, на которых установлен программируемый целевой MCU), например atmel_sam4s_xplained_pro.cfg, olimex_stm32_h107.cfg, stm32f4discovery.cfg и т. д. Вы можете увидеть, что эти файлы используют конфигурационные файлы из папок interface и target.
Базовая конфигурация адаптера. Сначала нам нужно указать OpenOCD тип адаптера, с которым будем работать, используя команду interface. Чтобы посмотреть полный список интерфейсов, которые поддерживает Ваша OpenOCD, используйте команду:
openocd -c interface_list
В этом руководстве мы используем адаптер на основе микросхемы FT2232H, поэтому укажем драйвер интерфейса FTDI:
interface ftdi
Также Вы должны предоставить для OpenOCD дополнительную информацию об адаптере (интерфейсе). Например, Вам нужно указать VID/PID, serial number или номер канала, который будете использовать в микросхеме FT2232H, поскольку у неё 2 канала.
Адаптер может поддерживать несколько транспортных протоколов, поэтому OpenOCD позволяет Вам выбрать такой протокол:
transport select swd
Также Вы должны указать OpenOCD начальные значения для регистров направления ножек портов общего назначения и данных FT2232H (регистры FTDI GPIO data и FTDI GPIO direction, подробнее см. [6]) с помощью команды ftdi_layout_init. Сначала нужно указать начальные значения 16 выводов канала, и затем указать направление работы этих выводов. Здесь "1" выбирает конфигурацию выхода для вывода, и "0" конфигурацию входа, и у каждого канала FT2232H имеется 16 выводов GPIO.
ftdi_layout_init 0x0018 0x05fb
Эта команда означает, что в качестве данных для GPIO будет значение 0x0018 (0000 0000 0001 1000), и в качестве конфигурации направления будет значение 0x05fb (0000 0101 1111 1011).
Для получения дополнительной информации о том, как конфигурировать адаптер, см. руководство OpenOCD [3].
Подключение MCU к адаптеру. На рисунке ниже приведена схема соединений для согласования интерфейса JTAG и SWD (так называемый резисторный хак SWD, файл swd-resistor-hack.cfg). Сигналы, показанные пунктиром, подключать необязательно.
В этом файле содержится следующее замечание: "Соедините TDI с сигналом SWDIO через последовательно подключенный резистор (сопротивлением 220 .. 470 Ом, с учетом нагрузочной способности целевого MCU и адаптера). Сигнал TDO соедините напрямую с сигналом SWDIO".
Без такой схемы подключения с резистором соединение с MCU не работает.
Таблица подключения FT2232H к EFM32G200F32:
FT2232H
EFM32G200F32
Ножка
Мнемоника
JTAG
Ножка
Мнемоника
SWD
16
ADBUS0
TCK
25
PF0
SWCLK
18
ADBUS2
TDO
26
PF1
SWDIO
17
ADBUS1
TDI (через резистор)
Пример подключения к плате FT2232H Board [7]:
Запуск OpenOCD. Сначала подготовьте специальный конфигурационный файл для Вашего адаптера. Для этого создайте новый текстовый файл и дайте ему подходящее имя (MyFT2232H-adapter.cfg). Вот пример этого файла, который можете взять за образец (отредактируйте в нем VID/PID и serial, чтобы они соответствовали Вашему адаптеру FT2232H, когда он подключен к порту USB компьютера):
# Этот конфигурационный файл был написан как приложение к руководству
# "Getting Started with OPENOCD Using FT2232H Adapter for SWD Debugging" [1],
# автор Yahya Tawil (yahya.tawil_at_gmail.com).
# Версия OpenOCD 0.9.0
interface ftdi
transport select swd
ftdi_vid_pid0x04030x6010
#ftdi_device_desc "USB Serial Converter A"
#ftdi_device_desc "Мой адаптер на основе FT2232H Board"
ftdi_serial"FTZ7O8O0"
#adapter_khz 8
ftdi_layout_init0x00180x05fb
ftdi_layout_signal SWD_EN -data 0
ftdi_layout_signal nSRST -data 0x0010
Замечание: определение сигнала SWD_EN важно для работы OpenOCD, даже если этот сигнал физически никуда не подключен. Если мы этого не сделаем, то произойдет ошибка:
Error: SWD mode is active but SWD_EN signal is not defined
После того, как Вы загрузили копию OpenOCD [9], запустите консоль интерпретатора команд CMD, и затем перейдите в каталог, где находится OpenOCD. Например (кавычки " используются, когда путь до каталога содержит пробелы):
cd "c:\Program Files (x86)\openocd-0.9.0\bin"
Предположим, что у нас есть файл конфигурации SWD_FT.cfg и целевой MCU, один из семейства чипов EFM32. Введите команду:
Info : FTDI SWD mode enabled
adapter speed: 1000 kHz
cortex_m reset_config sysresetreq
Info : clock speed 1000 kHz
Info : SWD IDCODE 0x2ba01477
Info : efm32.cpu: hardware has 6 breakpoints, 4 watchpoints
Если Вы встретились с проблемами, то см. ниже врезку "Устранение ошибок". Чаще всего бывает неправильное подключение адаптера к MCU или проблема с драйвером у пользователей Windows.
Открытие подключения telnet. Работающая система OpenOCD для приема команд запускает сервер telnet на TCP-порту 4444. Для подключения к нему откройте еще одно окно CMD, и запустите следующую команду:
telnet localhost 4444
Обмен с целевым MCU. Перед тем, как начать выполнение операций отладки, нужно остановить (halt) целевой MCU:
reset halt
В ответ будет выдано примерно такое сообщение:
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x00000bbc msp: 0x20002000
Чтобы прочитать регистры Вашего MCU, выполните команду:
reg
Чтобы прошить образ flash во внутреннюю память flash, нам нужно определить внутренние банки flash. Это может быть один банк, как в нашем случае с efm32.cfg. Чтобы убедиться, выполните команду:
Теперь, чтобы прошить Вашу программу в память flash, используйте команду write_image. Эта команда принимает файл в форматах, определяемых по расширению файла: двоичный bin (binary), ihex (Intel HEX), elf (исполняемый файл ELF), s19 (Motorola s19), mem или builder-форматы.
flash write_image erase "Desktop/FirstApp.hex"
В ответ будет выведено примерно такое сообщение:
auto erase enabled
wrote 1536 bytes from file Desktop/FirstApp.hex in 0.124740s (12.025 KiB/s)
После этого запустите записанную программу на выполнение командой:
reset run
Чтобы выйти из соединения Telnet, введите команду:
exit
Для получения дополнительной информации по прошивке памяти см. руководство OpenOCD [3].
Error: unable to open ftdi device: usb_open() failed
Эта ошибка вызвана драйвером libusb в Windows, поскольку новые версии OpenOCD используют другой драйвер, WinUSB.
Сначала убедитесь, что Вы дали указание Windows не устанавливать драйвер автоматически:
Затем удалите драйвер FTDI по умолчанию. Вы можете использовать утилиту от FTDI, которая называется CDM Uninstaller x.x - Windows Device Driver Uninstaller [13]. Для его использования нужно просто ввести VID и PID вашего адаптера с чипом FT2232H.
По умолчанию FTDI Vendor ID (VID) равен 0x0403. По умолчанию значения идентификаторов Product ID (PID) следующие:
Одноканальные устройства (чипы с буквой R): 0x6001 Двухканальные устройства (чипы FT2232C, FT2232D, FT2232H): 0x6010 Четырехканальные устройства (чипы FT4232H): 0x6011
Подробнее про CDM Uninstaller см. [14].
После удаления используйте Zadig Tool [15] для установки драйвера WinUSB.
Пример 2, ошибка:
Info : clock speed 1000 kHz
in procedure 'init'
in procedure 'ocd_bouncer'
Причина этой ошибки в неправильно подсоединенном или отсутствующем резисторе между сигналами TDI и TDO (см. схему подключения выше). Об этом резисторе упомянуто в комментариях файла swd-resistor-hack.cfg.
Также эта ошибка может быть вызвана неправильной конфигурацией, например при отсутствии команды ftdi_layout_init в файле конфигурации:
ftdi_layout_init 0x0018 0x05fb
Пример 3, ошибка:
Error: libusb_open() failed with LIBUSB_ERROR_ACCESS
Error: no device found
Error: unable to open ftdi device with vid 0403, pid 6010, description '*' and serial 'FTZ7O8O0'
Подобное сообщение об ошибке появляется, когда Вы запускаете OpenOCD в Linux без привилегии root. Для запуска OpenOCD с правами администратора используйте команду sudo (sudo opeocd).
[Ссылки]
1. Getting Started with OPENOCD Using FT2232H Adapter for SWD Debugging site:allaboutcircuits.com. 2. OpenOCD Debug Adapter Hardware site:openocd.org. 3. OpenOCD: руководство пользователя, начало. 4. Segger J-Link site:segger.com. 5. ULINK Debug and Trace Adapters site:keil.com. 6. FT2232H: двухканальная высокоскоростная USB микросхема для I/O. 7. FT2232H Board - макетная плата на высокоскоростном чипе моста USB фирмы FTDI. 8. FT2232H Mini-Module site:ftdichip.com. 9. Getting OpenOCD site:openocd.org. 10. OpenOCD Intel x86 site:packages.debian.org. 11. Compile OpenOCD for Windows site:dangerousprototypes.com. 12. Compiling OpenOCD v0.7.0 on Ubuntu 13.04 site:elinux.org. 13. CDM Uninstaller Windows Device Driver Uninstaller site:ftdichip.com. 14. Readme Future Technology Devices International Ltd CDM Uninstaller site:ftdichip.com. 15. Zadig Tool site:zadig.akeo.ie. 16. Using OpenOCD as a Standalone FLASH Programmer (a simple tutorial) site:olimex.com. 17. Getting Started with the ARM GCC Compiler on Windows, Part 5: Debugging with OpenOCD site:thehackerworkshop.com. 18. Настройка OpenOCD для AT91SAM7SE. 19. 170918SWD-OpenOCD-FT2232H.zip - документация, утилиты по тематике статьи.
Как быть с сигналом reset? В конфигурации для FT2232H есть ftdi_layout_signal nSRST -data 0x0010 а где эту ногу в микросхеме брать? Или его не обязательно подключать при активном SWD интерфейсе?
microsin: посмотрите готовые схемы адаптеров на основе чипа FT2232H (их множество опубликовано) и соответствующие конфигурационные файлы для них, тогда все вопросы отпадут сами собой. По поводу сброса - действительно, он иногда не используется, потому что есть возможность сбрасывать процессор передачей специальных команд отладочного интерфейса (SWD или JTAG). Но в общем случае тогда придется или передергивать питание у отладочной платы, или реализовывать её сброс при помощи кнопки - для того, чтобы перевести отладочный интерфейс и аппаратуру процессора в заранее известное состояние.
Комментарии
ftdi_layout_sig nal nSRST -data 0x0010
а где эту ногу в микросхеме брать? Или его не обязательно подключать при активном SWD интерфейсе?
microsin: посмотрите готовые схемы адаптеров на основе чипа FT2232H (их множество опубликовано) и соответствующие конфигурационны е файлы для них, тогда все вопросы отпадут сами собой. По поводу сброса - действительно, он иногда не используется, потому что есть возможность сбрасывать процессор передачей специальных команд отладочного интерфейса (SWD или JTAG). Но в общем случае тогда придется или передергивать питание у отладочной платы, или реализовывать её сброс при помощи кнопки - для того, чтобы перевести отладочный интерфейс и аппаратуру процессора в заранее известное состояние.
RSS лента комментариев этой записи