Skip to content

Commit a6bdb27

Browse files
Use static allocation for IRQ stack (#915)
noInterrupts/interrupts use a stack to allow multiple calls to work properly. The original code was using a std::stack which will use malloc() to allocate entry space. This seems like a bad idea, and makes it so it's impossible to disable interrupts for malloc/free, etc. Define a fixed stack size and use straight C code to manage the IRQ stacks. Slightly more fixed memory requirements, but significantly lower total RAM requirements and no malloc() dependency.
1 parent 62ed93f commit a6bdb27

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

cores/rp2040/wiring_private.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,30 @@
2222
#include <CoreMutex.h>
2323
#include <hardware/gpio.h>
2424
#include <hardware/sync.h>
25-
#include <stack>
2625
#include <map>
2726

2827
// Support nested IRQ disable/re-enable
29-
static std::stack<uint32_t> _irqStack[2];
28+
#define maxIRQs 15
29+
static uint32_t _irqStackTop[2] = { 0, 0 };
30+
static uint32_t _irqStack[2][maxIRQs];
3031

3132
extern "C" void interrupts() {
32-
if (_irqStack[get_core_num()].empty()) {
33+
auto core = get_core_num();
34+
if (!_irqStackTop[core]) {
3335
// ERROR
3436
return;
3537
}
36-
auto oldIrqs = _irqStack[get_core_num()].top();
37-
_irqStack[get_core_num()].pop();
38-
restore_interrupts(oldIrqs);
38+
restore_interrupts(_irqStack[core][--_irqStackTop[core]]);
3939
}
4040

4141
extern "C" void noInterrupts() {
42-
_irqStack[get_core_num()].push(save_and_disable_interrupts());
42+
auto core = get_core_num();
43+
if (_irqStackTop[core] == maxIRQs) {
44+
// ERROR
45+
panic("IRQ stack overflow");
46+
}
47+
48+
_irqStack[core][_irqStackTop[core]++] = save_and_disable_interrupts();
4349
}
4450

4551
// Only 1 GPIO IRQ callback for all pins, so we need to look at the pin it's for and

0 commit comments

Comments
 (0)