Настройка SWV printf на плате Nucleo STM32 - PullRequest
0 голосов
/ 28 июня 2018

Я разрабатываю прошивку на различных платах STM32L4 Nucleo с помощью Atollic Truestudio IDE (в основном Eclipse). До сих пор я использовал printf через UART благодаря виртуальному COM-порту.

Я хочу перейти на printf с использованием STM32 ITM.

Точнее работаю на Nucleo-L4A6ZG. Отладка осуществляется через GDB-сервер.

В Atollic я изменил свою конфигурацию отладки, чтобы включить SWV с тактовой частотой ядра 80 МГц. Я изменил свой скрипт запуска, как описано в справочном руководстве STM32L4, следующим образом. Я не уверен, что это необходимо, поскольку TrueStudio / Eclipse позволяет настраивать SWV из графического интерфейса, но выглядит проще:

# Set character encoding
set host-charset CP1252
set target-charset CP1252

# Reset to known state
monitor reset

# Load the program executable
load        

# Reset the chip to get to a known state. Remove "monitor reset" command 
#  if the code is not located at default address and does not run by reset. 
monitor reset

# Enable Debug connection in low power modes (DBGMCU->CR) + TPIU for SWV
set *0xE0042004 = (*0xE0042004) | 0x67

# Write 0xC5ACCE55 to the ITM Lock Access Register to unlock the write access to the ITM registers
set *0xE0000FB0 =0xC5ACCE55

# Write 0x00010005 to the ITM Trace Control Register to enable the ITM with Synchronous enabled and an ATB ID different from 0x00
set *0xE0000E80= 0x00010005

# Write 0x1 to the ITM Trace Enable Register to enable the Stimulus Port 0
set *0xE0000E00= (*0xE0000E00) | 0x1

#write 1 to ITM trace privilege register to unmask Stimulus ports 7:0
set *0xE0000E40= (*0xE0000E40) | 0x1



# Set a breakpoint at main().
tbreak main

# Run to the breakpoint.
continue

Я изменил свою функцию _write следующим образом:

static inline unsigned long ITM_SendChar (unsigned long ch)
{
  if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
      ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
  {
    while (ITM->PORT[0U].u32 == 0UL)
    {
      __asm("nop");
    }
    ITM->PORT[0U].u8 = (uint8_t)ch;
  }
  return (ch);
}

int _write(int file, char *ptr, int len)
{
    //return usart_write(platform_get_console(), (u8 *)ptr, len);
      int i=0;
      for(i=0 ; i<len ; i++)
        ITM_SendChar((*ptr++));
      return len;
}

Шаг за шагом отлаживаюсь, я вижу, что попадаю в строку ITM->PORT[0U].u8 = (uint8_t)ch;

Наконец, я запускаю трассировку в консоли SWV в IDE, но не получаю вывод.

Есть идеи, что мне не хватает? Как насчет основных часов SWV? Я не уверен, что это соответствует.

1 Ответ

0 голосов
/ 10 февраля 2019

Я столкнулся с аналогичной ситуацией на моем Nucleo-F103RB. Это помогло выбрать вариант отладки «Trace Asynchronous» на CubeMX, а не «Serial Wire». Асинхронная отладка трассировки выделяет вывод PB3 как вывод SWO.

Затем настройте конфигурацию отладки следующим образом: Конфигурация отладки проекта для включения Serial Wire Viewer (SWV)

Кроме того, я определил функцию записи внутри самого файла main.c, изменение определения в syscalls.c не сработало бы.

И, наконец, при отладке проекта в разделе «Настройки Serial Wire Viewer» включите (проверьте) только порт 0 на портах ITM Stimulus, например: Настройки Serial Wire Viewer в Debug соответственно

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

...