Goal
Measure execution time and optimize code performance on an STM32(What is STM32?) microcontroller using:
- Cycle counters
- GPIO pin toggling
- STM32CubeIDE's built-in profiler (SWV/SWO)
Method 1: Cycle Counting Using DWT (Data Watchpoint & Trace)
Enable DWT Cycle Counter (for Cortex-M3/M4/M7)
c
#include "core_cm4.h" // Adjust to your core type
void DWT_Init(void) {
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // Enable trace
DWT->CYCCNT = 0; // Reset cycle counter
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; // Enable counter
}
Example Usage
c
DWT_Init();
uint32_t start = DWT->CYCCNT;
myFunction();
uint32_t end = DWT->CYCCNT;
printf("Cycles: %lu\n", end - start);
Multiply by 1 / SystemCoreClock to convert cycles to time.
Method 2: GPIO Toggling + Oscilloscope/Analyzer
Example
c
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // Start timing
myFunction();
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // Stop timing
You can observe the pin on a logic analyzer to measure function duration down to microseconds or less.
Method 3: STM32CubeIDE SWV/SWO Profiling
Requirements:
- MCU with SWO pin
- Use ST-Link or J-Link debugger
- Connect SWO pin (often on PB3 or similar, depending on your MCU)
Steps:
Enable SWV I/O in STM32CubeMX (under SYS > Debug > Serial Wire)
In Project Settings > Debug Configuration:
- Go to SWV Settings
- Enable Trace and Profiling
- Launch debugger and open:
- SWV Console
- SWV Data Trace / Performance Analyzer
Profiling Views:
- Function Execution Time
- Instruction Count
- CPU Usage over Time
Optimization Tips Based on Profiling
Optional: Use CoreMark or Dhrystone Benchmarks
- These industry benchmarks help compare MCU performance objectively.
- You can run CoreMark on STM32 and see DMIPS/MHz.
- ST sometimes provides optimized CoreMark examples in STM32Cube repos.
Summary