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).
Как это устроено
- ITM (instrumentation trace macrocell) — 32 порта-регистра ITM_STIM0…31 с адреса 0xE0000000; запись в порт создаёт пакет трассировки. Перед использованием ITM включают бит TRCENA (Cortex-M3 TRM, гл. 9).
- TPIU (trace port interface unit) — собирает пакеты и выдаёт их на вывод; в режимах SWO он может обойти форматтер, и тогда наружу идут только данные ITM и DWT (гл. 11).
- Линия 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.
Источники
- 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
- 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
- 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
- Arm. CMSIS 6 v6.4.0, core_cm3.h — ITM_SendChar(): пишет символ в порт 0, если ITM включён (ITM_TCR.ITMENA) и порт 0 разрешён (ITM_TER бит 0); без подключённого отладчика возвращается сразу
Нашли ошибку?
Смотрите также
- SWDSerial Wire Debug: отладка и прошивка Cortex-M по двум проводам
- JTAG и SWDARM JTAG 20, Cortex Debug 10, STDC14, ST-LINK
- Cortex-M3Регистры, карта памяти, bit-banding, NVIC, SysTick, MPU, старт, пример
- SysTick24-битный таймер ядра Cortex-M для системного тика
- HardFaultИсключение Cortex-M при необработанной ошибке
- ITMБлок Cortex-M, который превращает записи программы в пакеты трассировки
- SEGGER RTTОбмен с отладчиком через кольцевые буферы в ОЗУ, без отдельных выводов