STM32 отладка через SWV в TrueSTUDIO

Хочу рассказать как использовать отладку через консоль SWV в среде Atollic TrueSTUDIO. Меня заинтересовала эта тема тем, что мне стали необходимы продвинутые способы отладки для STM32 в реальном времени и, как всегда это случается, я наступил на некоторые грабли. Об этом можно прочитать на форуме.

Начну сразу с настроек, а потом и за теорию немного поясню.

Для начала необходимо настроить конфигурацию Debug отладчика и настроить SWV при запущенной отладке. Отладчик настраивается в режим SWD, это важно, т.к. при JTAG просто ничего не будет работать. Остальные настройки очевидны, Core Clock это частота тактирования SYSCLK микроконтроллера.

Окно настройки Debug конфигурации для работы SWV
Окно настройки Debug конфигурации для работы SWV

Для входа в окно настроек необходимо нажать кнопку «Configure Trace» SWV консоли. Устанавливаем чекбокс порта 0, другие пока не трогаем, в них нет необходимости.

Настройка SWV консоли для вывода отладочных сообщений в порт 0
Настройка SWV консоли для вывода отладочных сообщений в порт 0

Далее, в тексте программы уже можно использовать вывод сообщений посредством функции printf. Данная функция использует потоковый вывод данных посредством системного вызова _write. Т.е. достаточно переопределить вызов и все должно заработать, что и было сделано в файле syscalls.c:

int _write ( int file, char *ptr, int len )
{
	int i = 0;

	for ( i = 0; i < len; i++ )
		ITM_SendChar ( *ptr++ );

	return len;
}

Пример вывода простого отладочного сообщения в консоль SWV:

#ifdef DEBUG
	printf ( "[ INFO ] Program start now\n" );
#endif

Рядом с кнопкой «Configure Trace» SWV консоли находится кнопка «Start Trace» в виде красного кружка, нажимается во время первой точки останова программы. И после запуска программы в консоли можно увидеть наше сообщение:

SWV консоль для вывода отладочных сообщений STM32

Самые внимательные заметили в реализации _write вызов функции ITM_SendChar ( *ptr++ ). ITM или Instrumentation Trace Macrocell позволяет приложению писать произвольные данные через SWO пин отладчика, используя 32 параллельных канала. Данные передаются от ядра Cortex M через кабель отладчика прямо в компьютер, где современные средства отладки, коим и является TrueSTUDIO, легко могут визуализировать эти данные.

Ядро позволяет использовать ITM для различных применений, но самое простое это как раз отладочный вывод через функцию printf. По умолчанию резервируется канал 0 (его то мы и настраивали чуть выше), а остальные 31 свободны для других применений.

Применений много, по мере изучения постараюсь делиться в блоге материалом (но это не точно). А пока вы можете подписаться на мой канал в telegram, где я публикую анонсы статей и другую информацию для разработчиков.

24 Ответов в “STM32 отладка через SWV в TrueSTUDIO

  1. Имею stm32f4 discovery. Можно ли мне использовать вывод через swo? Если да, то как нужно подключиться к swo. Использую Atollic True Studio. Не знаю откуда мне в программе вытащить вкладку SWO. Версия программы 9.1. И не могу найти функцию ITM_SendChar. Где её можно взять.
    Если что-то не понятное пишу не браните. Опыт с Arduino и Coo Cox не большой. Если кто то знает как с помощью stm Studio сделать консольный вывод плиз подскажите.

    1. Конечно можете. У stm32f4 discovery как и всех отладочных плат этой серии встроенный отладчик STLink V2. Если отлаживаете внешнее устройство через отладчик на плате дискавери, то на SWD коннекторе 6й пин как раз SWO. В Atollic чтобы открыть вкладку с SWV консолью необходимо перейти в Debug Perspective, когда запускаете отладку, то переходите в нее автоматически, далее в меню Window->Show View->Other, в открывшемся окне находите поиском SWV Console.

      Открыть SWV консоль в Atollic

      Функция ITM_SendChar() прописывается в syscalls.c

      syscalls stm32

      Если этого файла нет в проекте, то его необходимо добавить, нажав ПКМ на папке проекта -> New -> Other и здесь уже выбрать Minimal System Calls Implementation.

      Added minimal system calls implementation in stm32 project

  2. Спасибо за ответ admin. У меня заработала функция ITM_SendChar( ). Теперь вопрос: а как сделать, чтобы работала функция printf( )? Если это вообще возможно. Сейчас я пишу, компиляция проходит успешно, но ничего не происходит в окне SWV consol.

    1. Если все настроено корректно, то должно работать. В начале отладки на первой точке останова нужно нажать красный кружок Start Trace в SWV консоли и можно запускать программу на исполнение.

  3. Функция ITM_SendChar( ); выводит информацию в окно Start Trace в SWV. Но когда пишу функцию printf( ); ничего не выводится. Короче написал свою функцию на основе ITM_SendChar( );. У меня такой вопрос ещё. Не по теме немного, но пока не знаю где можно правильно спросить. Есть такая штука в стандарте С11: _Generic. Судя по описанию полезная для обобщений типов. В настройках Atollic true studio стоит стандарт С11. Но при попытке использовать это средство вылетают ошибки. Никто не может подсказать где узнать, почему не работает данное средство? Вроде все делаю по книге Стивена Прата 6-е издание по Си.

  4. Дима,
    проверь частоту тактирования, заданную для SWV в атолике. Также убедись, что у тебя мк работает на основной частоте. Просто камни топовых серий (4хх, 7хх) по дефолту стартуют на пониженной частоте. Т. е. в главную функцию надо добавить функцию настройки тактирования в номинальном режиме. Проверь, SWV trace log, после запуска трассировки.
    Насчет шаблонов могу сказать, что компиляторы под встроенные системы часто бывают порезаны и не поддерживают весь набор стандартов языка.

    1. Спасибо, Влад. У меня выводятся сообщения в SWV trace только, если я пишу в коде: «ITM_SendChar( );» . Но когда пишу: «printf();», то ничего не происходит. Именно при использовании функции printf ничего не происходит. А за _Generic спасибо. Я так и представил, что компиляторы под встроенные системы часто бывают порезаны и не поддерживают весь набор стандартов языка.

  5. Привет, всем. Не знаю и не понимаю как можно в реал тайме отслеживать переменные??? Знаю , что можно в Atollic true studio. Пробую но работает только функция ITM_SendChar( ), выводит информацию в окно Start Trace в SWV. А как наблюдать за переменной в реал тайме не пойму. С английским не очень, да и работать в Atollic true studio только учусь. Как то через elf файл. Раньше работал в coocox и смотрел за переменными через STMstudio и всё получалось. А сейчас и STMstudio не могу настроить. Может что то с elf файлом не так или в самом проекте чего то не хватает. Например некоторых векторов прерываний. Может это как то связано? Короче, может кто то подскажет на какие основные моменты нужно обратить внимание.

    1. Live expressions тепе поможет. читай юзер мануал. там мало слов требуется для понимания.

  6. Спасибо за статью. Теперь понятно как, но не понятно для чего. Что она дает. Какие задачи позволяет решить неразрешимые с обычной отладкой?

    1. Как минимум, есть возможность видеть в реалтайме значения какой-нибудь переменной без остановки программы. Иногда это бывает нужно.

  7. Начинаю понимать. Это то что дает Live Expressions (переменые в реальном времени без остановки) только виды заточены под разное применение. Вообще это удобно для отладки сложных процессов. На отладочную ногу обычно для этого сигнал выводят и смотрят осциллом. А тут можно не заморачиваться и получить больше. Надо пробовать. Хорошая вещ.

    1. Спасибо , все работает.

      Только задолбало нажимать красный маленький кружок для старта SWO….
      Не знаете как в TrueStudio это автоматизировать?

  8. Спасибо!!!
    Очень помогли. К сожалению пока не разберусь как вводить данные.
    примеры с Keil есть, с TrueSTUDIO не нашел.

    1. Какие именно данные вы хотите вводить? Не до конца понимаю, что конкретно не получается у вас.

      1. Спасибо за внимание и оперативное «реагирование» , даже удивлен.
        Перед тем как найти решение вывода информации через SWV для Atolik True Studio
        внимательно смотрел вот это видео «Отладка STM32. Перенаправление ввода-вывода. Возможности SWD, отладка больших программ.» https://youtu.be/pTJbO6RkfSI , то что меня интересует, начинается с 11 минуты, ни в Keil-e ни Atolik-е повторить это не получилось 

    2. Интересная тема, я не думал над вводом ранее, но подозреваю, что нужно в syscalls.c переопределить функцию _read(), добавив туда вызов ITM_ReceiveChar(). Как будет время попробую реализовать чтобы проверить. Если у вас получится раньше проверить дайте знать, пожалуйста.

      1. http://microsin.net/programming/arm/iar-stm32-terminal-debug-output.html

        в этой статье все хорошо разложили по полочкам.

        основной момент : «Также по сравнению с USART недостаток в том, что передача данных однонаправленная, т. е. реализовать консоль управления не получится.»

  9. int _write(int file, char *ptr, int len)
    всю жизнь переопределяю в мэйн файле или любом файле проекта. Никакие сисколы никогда не искал и в них не переопределял.
    Насчет живых переменных.
    В атолике совместно с STlinkom они не работают. С другим железом работают. В этом плане меня конечно атолик тоже расстраивает. Тот же кейл умеет. Да и новый куб IDE тоже это умеет.

    1. согласен, проще и понятней

      //тест STM32F103 + SWO (Atolik Trutudio) для старта не забыть нажать «красный кружочек»
      #include «stm32f10x.h»

      /******************** SWD **************************/
      int _write ( int file, char *ptr, int len )
      {
      int i = 0;
      for ( i = 0; i APB2ENR |= RCC_APB2ENR_IOPCEN;

      GPIOC->CRH &= ~GPIO_CRH_MODE13; //Конфигурирование PORTC.13
      GPIOC->CRH &= ~GPIO_CRH_CNF13;
      GPIOC->CRH |= GPIO_CRH_MODE13_1;
      GPIOC->CRH &= ~GPIO_CRH_CNF13 ;

      int chet=0;

      while (1)
      {
      GPIOC -> ODR ^=GPIO_ODR_ODR13;
      for (int i=0; i < 9000000; i++ ) {};
      printf("chet = %i \r\n", chet++ ); //для SWO
      }
      }

      1. выше не правильный код 🙁

        #include «stm32f10x.h»

        /******************** SWD **************************/
        int _write ( int file, char *ptr, int len )
        {
        int i = 0;
        for ( i = 0; i APB2ENR |= RCC_APB2ENR_IOPCEN;

        //Конфигурирование PORTC.13
        GPIOC->CRH &= ~GPIO_CRH_MODE13;
        GPIOC->CRH &= ~GPIO_CRH_CNF13;
        GPIOC->CRH |= GPIO_CRH_MODE13_1;
        GPIOC->CRH &= ~GPIO_CRH_CNF13 ;

        int chet=0;

        while (1)
        {
        GPIOC -> ODR ^=GPIO_ODR_ODR13;

        for (int i=0; i < 9000000; i++ ) {};
        printf("chet = %i \r\n", chet++ ); //для SWO
        }
        }

    2. «В атолике совместно с STlinkom они не работают. С другим железом работают. В этом плане меня конечно атолик тоже расстраивает. Тот же кейл умеет. Да и новый куб IDE тоже это умеет»

      насколько я понимаю речь идет о наличии выхода SWO, я паял дополнительный контакт к ST-Link по https://habr.com/ru/post/402927/ но самым разумным оказалось сделать программатор из Blue pill STM32F103 , единственно не стоит пытаться прошить прошивкой 2.1 (c виртуальным портом), работать с 64 кб не будет 100%.

  10. В руководстве есть глава «COMMON SWV PROBLEMS». У вас она не освещена. Большинство пользователей у кого не заработало могли бы решить свою проблему прочитав её.

Комментарии отключены.