Generating a macro to wrap a function so it can be called by interrupt priority level > 3

ZachVorhies
Posts: 2
Joined: Wed Sep 11, 2024 10:42 pm

Generating a macro to wrap a function so it can be called by interrupt priority level > 3

Postby ZachVorhies » Wed Sep 11, 2024 10:46 pm

Interrupt priorities 4-7 must call an asm function because these priority 4-7 interrupts do not have stack cleanup.

For the RMT driver in streaming mode, we supply a function that will get the next blocks of source data and covert it into RMT data and push that out.

However we have a problem in that when the WIFI is being used, it's interrupts block the RMT conversion interrupt from firing in time. The result is that the buffer sometimes underruns > 50 uS and the WS2812 LED strip latches prematurely.

We'd like to increase the priority but anything past priority 3 requires that the interrupt be written in ASM. My asm skills are poor and the function is large, so this is not an option for me. However, digging in I've realized that the reason the function should be ASM is because there is not stack cleanup for interrupts > 3.

GCC "naked" attribute isn't valid for the ESP32 functions, so it looks like i must do at least ASM. However, it's possible that we can just supply an ASM function that wraps a C function, as long as the proper stack cleanup is handled.

My question is this:

Whats the best way to figure out how to get the ASM? Should I just try to make a callback in regular C, compile it and then look at the object file generated lift the ASM out of that and modify it until it works a valid callback for priority > 3?

Ideally I'd like to have a macro that is something like this:

#define DEFINE_HIGH_PRIORITY_INTERRUPT_C_FUNC(asm_function_name, delegated_c_function) \
void asm_function_name (void* ptr) { \
// generates the pre-amble \
ASM_PRE_CALL_C_FUNC \
ASM_CALL_C_FUNC(ptr) \
// stack cleanup \
ASM_POST_CALL_C_FUNC // cleanup

void IRAM stream_converter(void*) {...};
DEFINE_HIGH_PRIORIT_INTERRUPT_C_FUNC(asm_stream_converter, stream_converter);
// attach interrupt...

And then I can run this interrupt at priority 4-7. Since there are at least 2 asm instruction sets for esp-related chipsets (we are not targetting the legacy 8266 chipset) I'd have to do this at least twice.

I'm looking for techniques to generate macros ASM_PRE_CALL_C_FUNC, ASM_CALL_C_FUNC, ASM_POST_CALL_C_FUNC for relevant target platforms. Or is it possible this work has already been done? Or should I try compiling object files and dissamble them?

ESP_Sprite
Posts: 9606
Joined: Thu Nov 26, 2015 4:08 am

Re: Generating a macro to wrap a function so it can be called by interrupt priority level > 3

Postby ESP_Sprite » Thu Sep 12, 2024 1:37 am

Trivial alternative solution: can you allocate more RMT blocks to your Tx channel?

ZachVorhies
Posts: 2
Joined: Wed Sep 11, 2024 10:42 pm

Re: Generating a macro to wrap a function so it can be called by interrupt priority level > 3

Postby ZachVorhies » Thu Sep 12, 2024 6:00 pm

We can for one or two strips, but we want to be able to support writing out 8 strips in parallel.

Who is online

Users browsing this forum: Bing [Bot] and 76 guests