Перейти к содержанию

SWO — вывод трассировки Cortex-M

Отладочные сообщения из прошивки можно выводить не только в UART. У ядер Cortex-M3 и M4 есть отдельный вывод трассировки SWO: программа пишет символ в регистр ITM, и он уходит в отладчик по той же колодке SWD, без лишних проводов к компьютеру.

Обновлено Редакция GAW

SWO (serial wire output) — однопроводный выход трассировки ядер Arm Cortex-M3, M4 и других Armv7-M. Через него блок TPIU выдаёт данные трассировки: сообщения программы из блока ITM и события блока DWT. Чаще всего SWO используют как отладочный канал «printf без UART»: программа пишет байт в регистр-порт ITM, байт уходит в отладчик по линии SWO рядом с линиями SWD, а среда разработки показывает его в окне Serial Wire Viewer (SWV).

Как это устроено

  1. ITM (instrumentation trace macrocell) — 32 порта-регистра ITM_STIM0…31 с адреса 0xE0000000; запись в порт создаёт пакет трассировки. Перед использованием ITM включают бит TRCENA (Cortex-M3 TRM, гл. 9).
  2. TPIU (trace port interface unit) — собирает пакеты и выдаёт их на вывод; в режимах SWO он может обойти форматтер, и тогда наружу идут только данные ITM и DWT (гл. 11).
  3. Линия SWO — асинхронный последовательный сигнал с кодом NRZ, как у UART, или Manchester; режим выбирает TPIU_SPPR, скорость — делитель TPIU_ACPR: fSWO = fref / (SWOSCALER + 1) (Armv7-M ARM, C1.10.4–C1.10.5).

В CMSIS для этого есть функция ITM_SendChar(): она отправляет символ, если ITM включён и порт 0 разрешён, и сразу возвращается, если отладчик порт не включил (core_cm3.h). Если же отладчик подключён, а предыдущий символ ещё не ушёл, функция ждёт.

SWO в STM32

У STM32F4 вывод трассировки TRACESWO совмещён с JTDO на PB3, поэтому SWO работает только при отладке по SWD, а не по JTAG (RM0090, разд. 38.3.1). В 10-контактном разъёме Cortex Debug линия SWO занимает контакт 6, вместе с TDO; распиновку показывает страница JTAG и SWD. Набор блоков отладки Cortex-M3 и их наличие в STM32F1 разобраны в статье о Cortex-M3.

Ограничения

  • В руководстве Arm по Cortex-M0 (DUI0497) блоки ITM и TPIU не описаны; статья о STM32CubeIDE по руководству ST UM2609 отмечает, что окна SWV нет на Cortex-M0 и M0+, например у STM32L053.
  • Вывод SWO занят, пока трассировка включена; если PB3 нужен программе, трассировку отключают.
  • Сообщения идут, только когда отладчик подключён и настроил SWO: в автономной работе устройства это не замена UART.

Частые вопросы

Как вывести printf через SWO на STM32?

Перенаправить вывод символа на функцию ITM_SendChar() из CMSIS: она пишет байт в порт 0 блока ITM, если ITM и порт включены. Включает их обычно отладчик, он же задаёт скорость SWO. На стороне компьютера сообщения показывает окно SWV (Serial Wire Viewer) среды разработки. Вывод PB3 у STM32F4 при этом занят под TRACESWO (RM0090, разд. 38.3.1).

Почему SWO не работает в режиме JTAG?

Потому что у STM32F4 асинхронный выход трассировки TRACESWO находится на той же ножке, что и TDO в JTAG. Поэтому трассировка через SWO возможна только при отладке по SWD (RM0090, разд. 38.3.1).

Как задаётся скорость SWO?

Делителем в регистре TPIU_ACPR: частота SWO = опорная частота трассировки / (SWOSCALER + 1), где SWOSCALER — до 0xFFFF (Armv7-M ARM, C1.10.4). Код линии — NRZ (как UART) или Manchester — выбирает TPIU_SPPR. Обе настройки обычно делает отладчик, а программа должна лишь не трогать вывод SWO.

Источники

  1. Arm. Cortex-M3 Technical Reference Manual, r2p1 (100165) — гл. 9 — ITM: регистры портов ITM_STIM0…31 с адреса 0xE0000000, ITM_TER, ITM_TCR; перед работой нужен бит TRCENA; гл. 11 — TPIU, 11.2.3 — форматы Serial Wire Output, выбор в TPIU_SPPR; при SWO можно обойти форматтер, тогда проходят только ITM и DWT
  2. Arm. Armv7-M Architecture Reference Manual, ARM DDI 0403E.e — C1.10.4 — TPIU_ACPR задаёт скорость SWO: SWO output clock = Asynchronous_Reference_Clock / (SWOSCALER + 1), SWOSCALER до 0xFFFF; C1.10.5 — TPIU_SPPR.TXMODE: 01 — асинхронный SWO с кодом Manchester, 10 — с кодом NRZ
  3. STMicroelectronics. RM0090 Reference manual: STM32F405/415, STM32F407/417, STM32F427/437 and STM32F429/439, Rev 21 — разд. 38.3.1 — асинхронный выход трассировки TRACESWO совмещён с TDO, поэтому работает только с SW-DP, не с JTAG-DP; вывод JTDO/TRACESWO — PB3
  4. Arm. CMSIS 6 v6.4.0, core_cm3.h — ITM_SendChar(): пишет символ в порт 0, если ITM включён (ITM_TCR.ITMENA) и порт 0 разрешён (ITM_TER бит 0); без подключённого отладчика возвращается сразу

Нашли ошибку?