Обновить

Полезные утилиты RTT Viewer и System Viewer

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели8.8K
Всего голосов 8: ↑8 и ↓0+10
Комментарии6

Комментарии 6

Инструмент конечно хороший, но его окупаемость под вопросом.

Если проект под бесплатными GCC или LLVM, то это будет наверно оправдано.
Хотя если с самого начала сидят на бесплатных тулсах, то врядли разработчику купят платный отладчик, да ещё адаптер J-Link стоит немало.

А если проект на IAR, то его C-Spy даст больше преимуществ чем System Viewer.
Чтобы в C-Spy отслеживать события прерывавний в реальном времени не нужно вообще никаких программных вставок в обработчики прерываний. Это сильно упрощает наблюдение за живучестью системы.

С другой стороны то, что в System Viewer показано на демо-скриншотах далеко от реальности.
Не поверю что кто-то вот так сидит и смотрит за таким огромным количеством событий и переменных. А перед этим еще рутинно конфигурирует это.

Нет, смотрят за узкими участками , парочка переменных, желательно видеть сразу все прерывания, и не искаженные программными отладочными вставками. Желательно видеть состояния задач и всех объектов синхронизации (ивенты, семафоры, мьютексы, пайпы и т.д.) Это все есть в C-Spy через аддоны к десятку разных RTOS.

Ну и в последнее время кардинально поменялся сам рабочий процесс отладки. Больше нет глупых ошибок типа: не там запятая, не то имя, неправильное условие в if, пустой указатель, утечка памяти и тому подобные мелочи. Т.е. нет больше тех абсурдных ошибок из-за которых надо было перерывать все исходники сверху до низу. Cloude Opus 4.6 просто не делает таких ошибок в принципе.
Остались только ошибки высокого порядка, когда непонятно как работает API многоуровневых библиотек и плоходокументированная внутреняя периферия микроконтроллера или внешняя переферия. И это решается в основном логами. И самый полезный инструмент тогда RTT Viewer. Но он идет с J-Link и System Viewer для этого не нужен.

клоны J-Link сейчас не сказать что дороги

  1. Почему SystemView использует DWT_CYCCNT  вместо того, чтобы считывать значения SysTick?

Может потому, что разрешение у dwt выше? Либо нужен именно увеличивающийся вверх таймер, а не вниз как systick

А вообще, спасибо за текст! На habr всего полторы методички про rtt.

Думаю, что оба ваших предположения верны (разумеется я достоверно не знаю за разработчиков SystemView). Интересно то, что в ядре Cortex M0 (M0+) счётчик циклов DWT_CYCCNT отсутствует. Для использования SystemView придется вручную переписывать функцию чтения циклов под SysTick.

Почему это замечательный текст не в хабе" программирование МК"? Надо поставить больше тегов. В частности тег rtt.

Я только сейчас обнаружил этот полезный материал.

поскольку пробиться через входной фильтр хабра и опубликовать маленькую статейку у меня не получилось, положу информацию сюда.
По-моему, вполне по теме статьи

итак, «Народная отладка» многоядерных приложений ARM Cortex

преамбула:
..попала мне в руки плата с 2х ядерным Cortex-A7

амбула:
Как оказалось, нельзя просто так подключиться ко всем (2м в моем случае) ядрам Cortex-A7 при помощи JLink.

И нельзя останавливать по software breakpoint ядро0 (к которому легко и просто цепляется отладчик IARa), ибо в этом случае ядро1 может налететь на измененный код (breakpoint) и, если не повезет, что случается, как оказалось чаще, в итоге debug-сессия зависает наглухо вместе с процессором (почему не разобрался пока).

Однако нас это не остановит! Как известно, технология Segger RTT умеет несколько каналов как upStream, так downStream.

Нас в данном случае интересуют up (от нашего процессора к компутеру). По умолчанию их даже и сконфигурировано 2!. В памяти они расположены независимо, каждый имеет свой буфер и свои указатели голова-хвост.

Эврика! Пишем простейший враппер на SEGGER_RTT_WriteString:

unsigned int RTT_WriteStringEx(unsigned char str) { unsigned int rc=0,bufN=getCPUID(); if(bufN<SEGGER_RTT_MAX_NUM_UP_BUFFERS) { rc=SEGGER_RTT_WriteString(bufN,(const char )str); } return(rc); }


Все, что он делает, запрашивает номер ядра на котором работает ( вызовом getCPUID() ) , и отправляетстроку в соответствующий буфер. Таким образом, нам не нужно заботиться о взаимоблокировках при вызовах WriteString из разных ядер.

Со стороны компьютера поток rtt0 смотрим, как обычно, RTTViewer'ом, поток rtt1 он не умеет к сожалению, поэтому используем JlinkRTTLogger.exe (его путем нехитрых танцев с бубном можно направить в консоль)

И вот такую красоту получаем на экране:

Все, что он делает, запрашивает номер ядра на котором работает ( вызовом getCPUID() ) , и отправляет строку в соответствующий буфер. Таким образом, нам не нужно заботиться о взаимоблокировках при вызовах WriteString из разных ядер.

Со стороны компьютера поток rtt0 смотрим, как обычно, RTTViewer'ом, поток rtt1 он не умеет к сожалению, поэтому используем JlinkRTTLogger.exe (его путем нехитрых танцев с бубном можно направить в консоль)

И вот такую красоту получаем на экране:

PS. Останавливать ядро0 (к которому, как мы помним, подключен наш отладчик IARa) можно!
там где код гарантированно выполняется на ядре0, что можно обеспечить в случае режима SMP заданием affinity_mask при создании задачи rtos.

PPS Данный прием может пригодиться и для отладочной печати, например, из прерывания.

PPPS Вопрос, сколько потоков upStream умеет RTT, мне пока хватило 2, но видимо скоро понадобится 4 или 5.

PPPPS "Антинародная" отладка выглядит сильно круче, может потом сделаю еще подход к пробитию входного фильтра хабра

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации