Interrupt handlers chaining on ESP32

vvb333007
Posts: 71
Joined: Wed Jul 31, 2024 5:53 am
Location: Thailand
Contact:

Re: Interrupt handlers chaining on ESP32

Postby vvb333007 » Sat Sep 20, 2025 9:02 am


As far as I understand, you want to intercept specific interrupts from the peripheral.
...
if you want to log the handlers of the idf drivers (uart, rmt...), use the callback provided by the idf and insert the loggers there.
To be honest I'd like to have statistics for UART, I2C, SPI and RMT

1. Number of interrupts generated
2. Number of bytes (or symbols) transmitted
3. Number of bytes (or symbols) received
4. Number of errors (depending on a periferial: fifo overflow, hardware error)
5. Dropped RX bytes/symbols etc (data was received but was not delivered to the upper layer)

I'd like to make this statistics transparent for the user code. Of course I can patch the IDF, to add all of these counters but I'd like not to make any modification to the esp-idf.

What is the proper way to implement counters for uart/i2c/spi and rmt?

Thank you!
Thanks!
Slava.

User avatar
ok-home
Posts: 157
Joined: Sun May 02, 2021 7:23 pm
Location: Russia Novosibirsk
Contact:

Re: Interrupt handlers chaining on ESP32

Postby ok-home » Sat Sep 20, 2025 9:36 am

I think the simplest and most correct solution for this task is

1. The Linker Wrap Function (--wrap=)
This is the most powerful and common meaning of "wrap" in the ESP-IDF (and GNU toolchain) context. It's a linker feature used to intercept calls to specific functions.

What it does: It allows you to replace a target function (e.g., function_name) with your own wrapper function (__wrap_function_name), while still providing a way to call the original function (__real_function_name).

How to use it:

Add linker flags in your component's CMakeLists.txt file:

cmake
target_link_options(${COMPONENT_LIB} INTERFACE
"-Wl,--wrap=function_to_wrap"
"-Wl,--wrap=another_function"
"-Wl,--undefined=__real_function_to_wrap" # Ensures the original symbol is resolved
)
Implement the wrapper functions in your source code:

c
// This wrapper will replace all calls to 'function_to_wrap'
void __wrap_function_to_wrap(void) {
// Your pre-call logic here (e.g., logging, validation)
printf("Calling function_to_wrap\n");

// Call the original function
void *result = __real_function_to_wrap();

// Your post-call logic here
printf("function_to_wrap returned %p\n", result);
return result;
}

MicroController
Posts: 2669
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Interrupt handlers chaining on ESP32

Postby MicroController » Sat Sep 20, 2025 12:47 pm

I think the simplest and most correct solution for this task is

1. The Linker Wrap Function (--wrap=)
Yep, probably the best way. Wrapping only the C handlers puts your wrapper in the C domain with no need for assembly and less complications/risk of breaking things.
// This wrapper will replace all calls to 'function_to_wrap'
... unless function_to_wrap is static and/or inlined. (Should still work with interrupt handlers because 1) their address is taken/exposed and 2) they're never called from C code.)

Who is online

Users browsing this forum: Bing [Bot], Bytespider, Qwantbot and 3 guests