Created
November 8, 2022 22:41
-
-
Save m-mcgowan/6e8978717d4ac0e56bba638aad9d1b84 to your computer and use it in GitHub Desktop.
STM32 function profiling using the cycle counter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Quick and dirty profiler for STM32 devices with the DWT cycle counter | |
// Computes the percentage of processor time spent in a function. Best suited for functions that are called routinely. | |
// Can be used in mixed C/C++ code. | |
// profile.h | |
#pragma once | |
inline uint32_t perfCounter() { | |
return DWT->CYCCNT; | |
} | |
#define PROFILE_VALUE(name) name##_percent | |
#ifdef __cplusplus | |
#define PROFILE_DECLARE(name) \ | |
extern "C" { \ | |
float name##_percent; \ | |
} | |
#define PROFILE_USE(name) \ | |
extern "C" float name##_percent; | |
#else | |
#define PROFILE_DECLARE(name) \ | |
float name##_percent; \ | |
#define PROFILE_USE(name) \ | |
float name##_percent; | |
#endif | |
#define PROFILE_PERCENT(name, x) {\ | |
static uint32_t name##_prev = 0; \ | |
uint32_t before = perfCounter(); \ | |
(x); \ | |
uint32_t after = perfCounter(); \ | |
uint32_t duration = (after-before); \ | |
name##_percent = (duration*100)/(after - name##_prev); \ | |
name##_prev = after; \ | |
} | |
/* | |
* How to use | |
* | |
* In the code to be profiled, declare the profiling tag in global scope: | |
* | |
* PROFILE_DECLARE(my_function) | |
* | |
* The name you choose is up to you, but easiest if it is named after the function you are profiling. | |
* | |
* Wrap the call to `my_function` in PROFILE_PERCENT | |
* | |
* Before: | |
* ... | |
* my_function(1,2,3); | |
* ... | |
* | |
* After: | |
* | |
* PROFILE_PERCENT(my_function(1,2,3)); | |
* | |
* To retrieve the profile percentage value, add code to your main app, e.g. an Arduino sketch. | |
* | |
* #include <profile.h> | |
* PROFILE_USE(my_function); | |
* | |
* Then use `PROFILE_VALUE(my_function)` to retrieve the current profiled percentage, as a float. E.g. | |
* | |
* Serial.print("my_function takes "); | |
* Serial.print(PROFILE_VALUE(my_function)); | |
* Serial.print(" percent"); | |
* | |
* The profiler is best suited to functions that run regularly. The profiler determines the percentage of MCU time | |
* spent inside the function compared to the time spent outside the function. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment