-
Notifications
You must be signed in to change notification settings - Fork 7.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IRAM_ATTR ignored for templated function (IDFGH-2429) #4542
Comments
@BlueAndi Thanks for reporting. |
@Alvin1Zhang You are welcome. :-) It looks like a lot of 3rd party libs are not aware of this problem. I am curious about a solution. |
Fix deprecated vref function
We encountered this issue as well in our firmware. Specifically while using templates of function pointers. We used to attach ISR's by using a template that gives us type safety. It works by using a helper function: template <typename ThisType, void (ThisType::*Callback)()>
struct InterruptCallbackHelper {
static void IRAM_ATTR callback(void* ptr) { (static_cast<ThisType*>(ptr)->*Callback)(); }
}; Apparently the callback is not stored in IRAM, and when it is triggered while flash is accessed, the esp crashes. We actually found this out by objdump'ing the binary in question and checking if it was in flash or IRAM. This appears to be the case for all templates. It's quite a nasty bug - consider using |
@atlaste Currently, we don't have an automatic way to place template functions into Besides, there might be mitigations available depending on the circumstances:
If that doesn't help, there are ways to manually place the functions into flash via the linker. Not convenient but it should work. I did this a long time ago but don't have the information at hand right now. Need to find this again... |
Could you elaborate this further? What's missing and why is this not simply working?
Most of our interrupts are very timing critial; I'm a collaborator of FluidNC, the frequently used CNC firmware, used by thousands of people. We use ISR's for things like probes, endstops and motor stepping. We are well aware of the possibilities to offload things to tasks via a queue and handling it in a task, but most of what we need here is very time critical. If we don't catch a probe or endstop in time, things will simply be destroyed. As for the C3, we wanted to make the leap to the S3 at some point because it seems like a better match - but so far I haven't been able to obtain one (out of stock). Regardless of that, there will still be a lot of people using the firmware with normal ESP's. Most of the crashes we had in the past seemed to originate from ISR's. Apparently:
My main issue is: where does it stop and what are we still missing? Now it's just guessing... We've been adding things to a custom linker script to place them in IRAM manually. It's a bit of a pain, and as a result we have to put way more in IRAM than we really need to get vtables and switches working. I attempted to get rid of switches with templates, but apparently that's out of the window too... Obviously there's a limit here. This template case got me concerned. Atomic is just one case. Vectors come to mind. And many, many more hidden templates that are used in the STL for template specialization to who knows what, even in different compilation units... I hope you see my concern, so I'd rather work towards getting this solved in the compiler if possible, or at the very least have a list of what will and what will not work in an ISR, so I can do an extensive review of all the relevant code. |
Note, the root cause seems this bug, as I mentioned in the issue description.: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70435 |
…(downgrade). Because of issue with compiler. See - espressif/esp-idf#4542 - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70435
This is necessary as: - C++11 is used and there max() is not declared constexpr - C++11 is used because the compiler version supporting C++14 has a bug (see espressif/esp-idf#4542) - function must be declared in a namespace, as Arduino.h declares std::max in global namespace 😠 esp8266/Arduino@dfcaa1b#diff-3d1fc8ffad5bc435eea7c0970e45f03a0cd0c8c95bb3840b939251d2a877ee95R251 - code copied from https://en.cppreference.com/w/cpp/algorithm/max#Possible_implementation
I observe that with a linker script, one might be specify their own name convention and pick them up into IRAM with the help of wildcards (ala https://stackoverflow.com/questions/36279162/section-attribute-of-a-function-template-is-silently-ignored-in-gcc) Is there a way to accomplish this (including the wildcards) with esp-idf linker fragments? I am smacking face first into this issue, never did I anticipate I wouldn't be able to use my templated functions in this scenario... |
Environment
Problem Description
IRAM_ATTR is ignored for templated function, like
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70435
Expected Behavior
IRAM_ATTR is considered.
Code to reproduce this issue
Debug Logs
Check via xtensa-esp32-elf-nm.exe
The text was updated successfully, but these errors were encountered: