STM32: OpenOCD semihosting

Небольшая заметка для себя, чтобы не гуглить заново в следующий раз.

  • В Makefile меняем параметры линкера: вместо -specs=nano.specs пишем -specs=rdimon.specs, вместо -lnosys пишем -lrdimon. Мне также пришлось добавить -Wl,—no-wchar-size-warning, т. к. размерность wchar где-то не совпала.
  • В коде до main объявляем функцию extern void initialise_monitor_handles(void) и вызываем её в начале main. Важный момент — при отсутствии принимающей стороны на хосте этот вызов приведёт к HardFault, т. е. система сможет работать только под отладчиком.
  • Запускаем OpenOCD с командой arm semihosting enable и в его выводе увидим сообщения от printf. Ещё один важный момент — вывод будет в отладочных сообщениях, по telnet его не видно.
  • Для младших контроллеров может стать проблемой увеличение размера прошивки. В STM32F030 пришлось уменьшить размер Min_Heap_Size в LD-скрипте.

Как прошить Nordic NRF52 с помощью ST-Link и OpenOCD

Во-первых, понадобится собрать последнюю версию openocd из исходников:

git clone https://github.com/ntfreak/openocd.git
cd openocd
./bootstrap
./configure
make

По умолчанию configure включит поддержку некоторых программаторов, в том числе st-link. Если этого не произошло, значит не хватает каких-то зависимостей.

Далее, пишем скрипт:

#!/bin/sh
OPENOCD=/path/to/openocd
SOFTDEVICE=/path/to/nRF5_SDK_14.2.0_17b948a/components/softdevice/s132/hex/s132_nrf52_5.0.0_softdevice.hex

FW=$1
[ -z "$FW" ] && (echo "No fw given!" ; exit 1)

${OPENOCD}/src/openocd \
    -s ${OPENOCD}/tcl \
    -f interface/stlink.cfg \
    -f target/nrf52.cfg \
    -c init \
    -c "reset init" \
    -c halt \
    -c "nrf5 mass_erase" \
    -c "flash write_image ${SOFTDEVICE}" \
    -c "flash write_image ${FW}" \
    -c reset \
    -c exit

Цель для Makefile для Nordic SDK может выглядеть так:

OPENOCD := /path/to/openocd
SOFTDEVICE := /path/to/nRF5_SDK_14.2.0_17b948a/components/softdevice/s132/hex/s132_nrf52_5.0.0_softdevice.hex

flashst: $(OUTPUT_DIRECTORY)/nrf52832_xxaa.hex
    @echo Flashing: $<
    $(OPENOCD)/src/openocd -s $(OPENOCD)/tcl -f interface/stlink.cfg -f target/nrf52.cfg \
            -c init \
            -c "reset init" \
            -c halt \
            -c "nrf5 mass_erase" \
            -c "flash write_image $(SOFTDEVICE)" \
            -c "flash write_image $<" \
            -c reset \
            -c exit