How to configure swv itm data console in stm32cubeide?

Configuring the SWV ITM Data Console in STM32CubeIDE is a powerful technique for real-time debugging and printf-style logging with minimal performance impact. Here's a comprehensive guide.



Overview: What is SWV ITM?

SWV (Serial Wire Viewer) and ITM (Instrumentation Trace Macrocell) work together to provide a dedicated hardware-based profiling and debugging channel.

  • ITM: A hardware module in the ARM Cortex-M core that allows the application to send data packets.

  • SWV: The physical interface (uses the same SWD pins as debugging) to stream this data out.

  • Key Advantage: No UART required, very low CPU overhead, and doesn't halt program execution.


Step-by-Step Configuration

Step 1: Hardware Setup

  1. Connect ST-LINK: Use a USB cable to connect your STM32 discovery/nucleo board

  2. No extra wires needed: SWV uses the existing SWD (Serial Wire Debug) connection

Step 2: Project Configuration in STM32CubeIDE

A. Pinout & Configuration Tab

  1. Enable Debug:

    • Go to "Pinout & Configuration" tab

    • Find "System Core" → SYS

    • Set Debug to Serial Wire

B. Clock Configuration

  1. Configure System Clock:

    • Go to "Clock Configuration" tab

    • Ensure your system clock is properly configured

    • Important: Note your HCLK frequency (needed later)

C. Trace Configuration

  1. Enable Trace:

    • Go back to "Pinout & Configuration"

    • Find "System Core" → SYS

    • Under "Debug", check Trace Asynchronous Sw

    • Set Core Clock to your HCLK frequency (e.g., 72,000,000 Hz)

D. Generate Code

  1. Generate Project:

    • Click "Project" → "Generate Code" or use the gear icon

    • This applies all hardware configurations


Step 3: Code Implementation

Option A: Using printf() Redirection (Recommended)

Add this code to your main.c:

c
#include <stdio.h>

// ITM Send Character function
int __io_putchar(int ch) {
    ITM_SendChar(ch);
    return ch;
}

// Optional: For scanf functionality
int __io_getchar(void) {
    return -1; // Not implemented for SWV
}

Now you can use standard printf() statements:

c
printf("System started! HCLK = %lu Hz\r\n", SystemCoreClock);
printf("Sensor value: %d\r\n", sensor_value);

Option B: Direct ITM Function Calls

c
// Send simple messages
ITM_SendChar('A');
ITM_SendChar('\n');

// Send strings
void SWV_Print(char *msg) {
    while (*msg) {
        ITM_SendChar(*msg++);
    }
}

// Usage
SWV_Print("Hello from SWV!\r\n");

Step 4: STM32CubeIDE Debug Configuration

  1. Create Debug Configuration:

    • Right-click your project → "Debug As" → "Debug Configurations"

    • Double-click "STM32 Cortex-M C/C++ Application"

    • Or edit existing configuration

  2. Debugger Tab Settings:

    • Debug probe: Your ST-LINK

    • Interface: SWD

    • Mode: Connect under reset

  3. Trace Tab Settings:

    • Check Enable Serial Wire Viewer (SWV)

    • Core Clock: Set to your HCLK frequency (e.g., 72,000,000)

    • SWV Clock: Usually same as core clock or divided by 2

    • ITM Stimulus Ports: Check Port 0 (this is for printf)

  4. Apply and Debug


Step 5: Viewing SWV Data During Debugging

  1. Start Debug Session:

    • Click "Debug" or use your debug configuration

    • Program will stop at main()

  2. Open SWV Console:

    • Go to Window → Show View → Other...

    • Navigate to SWV → SWV ITM Data Console

    • Click "OK"

  3. Configure SWV:

    • In the SWV view, click the "Configure SWV" button (wrench icon)

    • Ensure ITM Port 0 is checked

    • Click "OK"

  4. Start Tracing:

    • Click the "Start Tracing" button (red record circle)

    • Resume your program (F8)

  5. View Output:

    • All printf() statements will appear in the SWV ITM Data Console


Complete Example Code

c
/* main.c */
#include "main.h"
#include <stdio.h>

// ITM function for printf redirection
int __io_putchar(int ch) {
    ITM_SendChar(ch);
    return ch;
}

int main(void) {
    HAL_Init();
    SystemClock_Config();
    
    printf("\r\n=== SWV ITM Data Console Test ===\r\n");
    printf("System Core Clock: %lu Hz\r\n", SystemCoreClock);
    
    uint32_t counter = 0;
    while (1) {
        printf("Counter: %lu\r\n", counter++);
        HAL_Delay(1000);
    }
}

Troubleshooting Common Issues

1. No Output in SWV Console

  • Check: Core clock frequency in trace configuration

  • Check: ITM Port 0 is enabled in SWV configuration

  • Check: "Start Tracing" is clicked before resuming program

2. Garbage Characters

  • Cause: Incorrect core clock setting

  • Fix: Ensure HCLK frequency matches your system clock exactly

3. SWV Option Grayed Out

  • Cause: Debug session not active or SWV not enabled in debug config

  • Fix: Enable SWV in debug configuration → Trace tab

4. "ITM_SendChar" Undefined

  • Fix: Add this function if not defined:

c
#define ITM_Port8(n)    (*((volatile unsigned char *)(0xE0000000+4*n)))
#define ITM_Port16(n)   (*((volatile unsigned short*)(0xE0000000+4*n)))
#define ITM_Port32(n)   (*((volatile unsigned long *)(0xE0000000+4*n)))
#define DEMCR           (*((volatile unsigned long *)(0xE000EDFC)))
#define TRCENA          0x01000000

static inline uint32_t ITM_SendChar (uint32_t ch) {
    if ((DEMCR & TRCENA) && (ITM_Port32(0) != 0)) {
        while (ITM_Port32(0) == 0);
        ITM_Port8(0) = ch;
    }
    return(ch);
}

Advanced Configuration

Multiple ITM Ports

You can use different ports for different data types:

c
// Send to different ports
void SWV_SendToPort(uint8_t port, uint32_t data) {
    if (port < 32) {
        ITM_Port32(port) = data;
    }
}

// Usage: Port 0 for debug, Port 1 for sensor data, etc.
SWV_SendToPort(1, sensor_value);

This setup provides a robust, high-performance debugging console that's perfect for real-time applications!

评论

此博客中的热门博文

How To Connect Stm32 To PC?

Detailed Explanation of STM32 HAL Library Clock System

How to add a GPS sensor to ESP32 for Wokwi?