Topics

Enable traces on Serial Wire Output #debugging


David K
 

Hi, I am just getting started with Zephyr and currently working on a STM32F746ZE. I added a custom configuration for this board based on STM32F746G_DISCO. After having run successfully the blinky example, I am now trying to have traces on SWO (not UART), so that ultimately ITM_sendchar() would be called.

I have added in my Kconfig.defconfig:

config LOG_BACKEND_SWO_FREQ_HZ
	default 0

Following the documentation, I added in the blinky main.c:

//...
#include <logging/log.h>

void main(void)
{
    //...
    LOG_MODULE_REGISTER(toto, LOG_LEVEL_DBG);
    LOG_INF("Hello World ! %s\n", CONFIG_BOARD);
    // ...
}

I build and flash it flawlessly but I got no output on my console (using JLINK to connect and swoview). When I debug this with GDB I see that I don't go through the 2 lines I have added so I guess they are removed at compilation time.

I guess I am missing a flag/define/config somewhere (I get a little confused about where to define things in dts/kconfig/defconfig, ...), but I cannot find any example: any pointers ? Best regards


David K
 

Replying to my own issue:

First I misunderstood module registration:

#include <logging/log.h>
// Must be done outside the function
LOG_MODULE_REGISTER(toto, LOG_LEVEL_DBG);

void main(void)
{
    //...
    LOG_INF("Hello World ! %s\n", CONFIG_BOARD);
    // ...
}

Then, I used west build -t menuconfig to enable:

[*] Logging-->    // This one was not enabled
    [*] Enable Serial Wire Output (SWO) backend
    (0)     Set SWO output frequency 

After that I managed to get traces via the JLINK SWO Viewer.

However, it only works if I launch the SWO viewer AFTER my application is launched. If I trigger a reset of the target during a swoview session, I lost traces. I have to re-launch the swo viewer to get the logs again, meaning that I cannot have traces of a reboot for example and I cannot figure out why because the file log_backend_swo_init has the procedure described in JLINK User guide (3.8.4 Configure SWO output after device reset)


David K
 

I am still struggling to figure out why I cannot keep receiving traces through reboots. On the same dev board with FreeRTOS it was consistent: I was able to log target resets without re-launching swoview.

I don't understand why even with the basics samples (blinky, button, ...) when I reset the target the SWO output is "broken" and I have to launch a new instance of swoview to get traces again. Is it something in the DTS to configure ?

Thanks


Carles Cufi
 

Hi there,

 

We don’t use SWO but RTT (also from Segger) and we don’t need to reset the JLinkRTTViewer/Logger when we reset the target.

Could it be that the way Zephr flashes and then resets the target (pin reset vs software reset) is different from FreeRTOS?

 

In theory this is all handled by the on-board debugger chip so it should make no difference.

 

Which board are you using?

 

Carles

 

From: users@... <users@...> On Behalf Of David K via Lists.Zephyrproject.Org
Sent: 10 March 2020 17:13
To: users@...
Cc: users@...
Subject: Re: [Zephyr-users] Enable traces on Serial Wire Output #debugging

 

I am still struggling to figure out why I cannot keep receiving traces through reboots. On the same dev board with FreeRTOS it was consistent: I was able to log target resets without re-launching swoview.

I don't understand why even with the basics samples (blinky, button, ...) when I reset the target the SWO output is "broken" and I have to launch a new instance of swoview to get traces again. Is it something in the DTS to configure ?

Thanks


David K
 

Hi, thanks for your feedback ! I have a STM32F746ZE-based board and using west with jlink runner to flash it. I have the same issue when I reset the target via JLink Commander.


Carles Cufi
 

+ Erwan, Simen, Krzysztof, Andrzej

 

As mentioned in an earlier email (to which you replied without context so I had to start a new thread), RTT does work across reboots without problems, at least on Nordic platforms.

 

You wrote:

> Hi, thanks for your feedback ! I have a STM32F746ZE-based board and using west with jlink runner to flash it. I have the same issue when I reset the target via JLink Commander.

 

I do not know whether Zephyr does anything at all to the SWO pin connected to the debugger chip, and especially not on an STM32 platform (I copied Erwan who maintains these boards), but I might be wrong.

 

Carles

 

From: users@... <users@...> On Behalf Of David K via Lists.Zephyrproject.Org
Sent: 10 March 2020 17:13
To: users@...
Cc: users@...
Subject: Re: [Zephyr-users] Enable traces on Serial Wire Output #debugging

 

I am still struggling to figure out why I cannot keep receiving traces through reboots. On the same dev board with FreeRTOS it was consistent: I was able to log target resets without re-launching swoview.

I don't understand why even with the basics samples (blinky, button, ...) when I reset the target the SWO output is "broken" and I have to launch a new instance of swoview to get traces again. Is it something in the DTS to configure ?

Thanks


William Fish
 
Edited

Hi all,
I use segger ozone to do debugging via RTT it's free download which may be helpful.   
It does have swo trace and STM32 JTAG configuration inbuilt it may be something to consider. 

But I work with Nordic silicon so not sure about the STM chips. 

Billy..


Erwan Gouriou
 

Hi David,

I'm not a SWO user myself but I'm suspecting a clock set up issue.
On FreeRTOS, what was the clock configuration you were using ?

Cheers


On Wed, 11 Mar 2020 at 12:13, Cufi, Carles <Carles.Cufi@...> wrote:

+ Erwan, Simen, Krzysztof, Andrzej

 

As mentioned in an earlier email (to which you replied without context so I had to start a new thread), RTT does work across reboots without problems, at least on Nordic platforms.

 

You wrote:

> Hi, thanks for your feedback ! I have a STM32F746ZE-based board and using west with jlink runner to flash it. I have the same issue when I reset the target via JLink Commander.

 

I do not know whether Zephyr does anything at all to the SWO pin connected to the debugger chip, and especially not on an STM32 platform (I copied Erwan who maintains these boards), but I might be wrong.

 

Carles

 

From: users@... <users@...> On Behalf Of David K via Lists.Zephyrproject.Org
Sent: 10 March 2020 17:13
To: users@...
Cc: users@...
Subject: Re: [Zephyr-users] Enable traces on Serial Wire Output #debugging

 

I am still struggling to figure out why I cannot keep receiving traces through reboots. On the same dev board with FreeRTOS it was consistent: I was able to log target resets without re-launching swoview.

I don't understand why even with the basics samples (blinky, button, ...) when I reset the target the SWO output is "broken" and I have to launch a new instance of swoview to get traces again. Is it something in the DTS to configure ?

Thanks


David K
 

Hi there,

Thanks for the feedback and sorry for the delay. Here is my function that initializes the clock, it is called right after HAL_Init():

    // Configure the main internal regulator output voltage
    __IO uint32_t tmpreg;
    SET_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);

    // Delay after an RCC peripheral clock enabling
    tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);
    tmpreg = tmpreg;

    MODIFY_REG(PWR->CR1, PWR_CR1_VOS, (PWR_REGULATOR_VOLTAGE_SCALE3));

    // Delay after an RCC peripheral clock enabling
    tmpreg = READ_BIT(PWR->CR1, PWR_CR1_VOS);
    tmpreg = tmpreg;

    // Initializes the CPU, AHB and APB busses clocks
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_OscInitStruct.OscillatorType      = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState            = RCC_HSE_ON;
    RCC_OscInitStruct.HSIState            = RCC_HSI_ON;
    RCC_OscInitStruct.HSICalibrationValue = 16;
    RCC_OscInitStruct.PLL.PLLState        = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource       = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLM            = 8;
    RCC_OscInitStruct.PLL.PLLN            = 144;
    RCC_OscInitStruct.PLL.PLLP            = RCC_PLLP_DIV2;
    RCC_OscInitStruct.PLL.PLLQ            = 6;
    HAL_StatusTypeDef hal_ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
    if (hal_ret != HAL_OK)
    {
        return -ENOTSUP;
    }

    // Initializes the CPU, AHB and APB busses clocks
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    RCC_ClkInitStruct.ClockType      = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource   = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider  = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
    // HAL_RCC_ClockConfig() ultimately calls HAL_InitTick()
    hal_ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
    if (hal_ret != HAL_OK)
    {
        return -ENOTSUP;
    }

    // Initializes the peripherals clocks
    RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART6 | RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_CLK48;
    PeriphClkInitStruct.Usart6ClockSelection = RCC_USART6CLKSOURCE_HSI;
    PeriphClkInitStruct.Clk48ClockSelection  = RCC_CLK48SOURCE_PLL;
    PeriphClkInitStruct.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_CLK48;
    hal_ret = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
    if (hal_ret != HAL_OK)
    {
        return -ENOTSUP;
    }

    // Configure the Systick IRQ for FreeRTOS timebase
    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
    // Configure the Systick
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

    // SysTick_IRQn interrupt configuration done in HAL_MspInit()

    SCB_EnableICache();
    SCB_EnableDCache();

    return 0;

Also, not sure if it is related but I have 2 Time bases:

  • STM32 uses timers (TIM6) to generate interruptions for HAL
  • FreeRTOS uses SysTick for OS functions

Thanks for your help, in parallel I will look into RTT alternative.


David K
 

And I forgot to include the FreeRTOS part:

#define configCPU_CLOCK_HZ                      ( SystemCoreClock )
#define configTICK_RATE_HZ                      ( 1000 )

Where SystemCoreClock is set to 16000000 by default.