Skip to content

Commit 9e239ec

Browse files
committed
Invented void* detachInterruptArg() that returns the argument given in attachInterruptArg().
This is sufficient for resource management - the function has static duration anyway.
1 parent e7013ba commit 9e239ec

File tree

3 files changed

+28
-68
lines changed

3 files changed

+28
-68
lines changed

cores/esp8266/Arduino.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,9 @@ void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
217217
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
218218

219219
void attachInterrupt(uint8_t pin, void (*)(void), int mode);
220-
void attachInterruptArg(uint8_t pin, void (*)(void*), void * arg, int mode);
221220
void detachInterrupt(uint8_t pin);
221+
void attachInterruptArg(uint8_t pin, void (*)(void*), void* arg, int mode);
222+
void* detachInterruptArg(uint8_t pin);
222223

223224
void preinit(void);
224225
void setup(void);

cores/esp8266/core_esp8266_wiring_digital.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,10 @@ extern void __detachInterrupt(uint8_t pin) {
192192
}
193193
}
194194

195-
extern interrupt_handler_t* __getInterruptHandler(uint8_t pin) {
196-
return (pin < 16) ? &interrupt_handlers[pin] : nullptr;
195+
extern void* __detachInterruptArg(uint8_t pin) {
196+
void* arg = (pin < 16) ? interrupt_handlers[pin].arg : nullptr;
197+
__detachInterrupt(pin);
198+
return arg;
197199
}
198200

199201
void initPins() {
@@ -215,7 +217,8 @@ extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pi
215217
extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias("__digitalWrite")));
216218
extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead")));
217219
extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt")));
218-
extern void attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void* arg, int mode) __attribute__ ((weak, alias("__attachInterruptArg")));
219-
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));
220+
extern void detachInterrupt(uint8_t pin) __attribute__((weak, alias("__detachInterrupt")));
221+
extern void attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void* arg, int mode) __attribute__((weak, alias("__attachInterruptArg")));
222+
extern void* detachInterruptArg(uint8_t pin) __attribute__((weak, alias("__detachInterruptArg")));
220223

221224
};

libraries/esp8266/examples/GPIO/FunctionalInterrupt/FunctionalInterrupts.cpp

Lines changed: 19 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,6 @@
22
#include <Schedule.h>
33
#include "Arduino.h"
44

5-
#if defined(ESP8266)
6-
7-
// Duplicate typedefs from core_esp8266_wiring_digital.cpp
8-
// Keep in sync
9-
typedef void (*voidFuncPtr)(void);
10-
typedef void (*voidFuncPtrArg)(void*);
11-
12-
typedef struct {
13-
uint8_t mode;
14-
voidFuncPtr fn;
15-
void* arg;
16-
} interrupt_handler_t;
17-
18-
// Helper functions for Functional interrupt routines
19-
extern "C" interrupt_handler_t* __getInterruptHandler(uint8_t pin);
20-
21-
#elif defined(ESP32)
22-
23-
// Duplicate typedefs from esp32-hal-gpio.c
24-
// Keep in sync
25-
typedef void (*voidFuncPtr)(void);
26-
typedef void (*voidFuncPtrArg)(void*);
27-
typedef struct {
28-
voidFuncPtr fn;
29-
void* arg;
30-
} InterruptHandle_t;
31-
32-
// Helper functions for Functional interrupt routines
33-
extern "C" InterruptHandle_t* __getInterruptHandler(uint8_t pin);
34-
35-
#endif
36-
375
void ICACHE_RAM_ATTR interruptFunctional(void* arg)
386
{
397
ArgStructure* localArg = static_cast<ArgStructure*>(arg);
@@ -44,32 +12,30 @@ void ICACHE_RAM_ATTR interruptFunctional(void* arg)
4412
}
4513
if (localArg->functionInfo->reqScheduledFunction)
4614
{
47-
schedule_function(std::bind(localArg->functionInfo->reqScheduledFunction,InterruptInfo(*(localArg->interruptInfo))));
15+
schedule_function(
16+
[reqScheduledFunction = localArg->functionInfo->reqScheduledFunction,
17+
interruptInfo = *localArg->interruptInfo]() { reqScheduledFunction(interruptInfo); });
4818
}
4919
if (localArg->functionInfo->reqFunction)
5020
{
5121
localArg->functionInfo->reqFunction();
5222
}
5323
}
5424

55-
void cleanupFunctional(void* arg)
56-
{
57-
ArgStructure* localArg = static_cast<ArgStructure*>(arg);
58-
delete localArg;
59-
}
25+
void cleanupFunctional(void* arg)
26+
{
27+
ArgStructure* localArg = static_cast<ArgStructure*>(arg);
28+
delete localArg;
29+
}
6030

6131
void attachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode)
6232
{
6333
// use the local interrupt routine which takes the ArgStructure as argument
6434

65-
#if defined(ESP8266)
66-
interrupt_handler_t* handler = __getInterruptHandler(pin);
67-
#elif defined(ESP32)
68-
InterruptHandle_t* handler = __getInterruptHandler(pin);
69-
#endif
70-
if (handler->arg)
35+
void* localArg = detachInterruptArg(pin);
36+
if (localArg)
7137
{
72-
cleanupFunctional(handler->arg);
38+
cleanupFunctional(localArg);
7339
}
7440

7541
FunctionInfo* fi = new FunctionInfo;
@@ -78,19 +44,15 @@ void attachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode
7844
ArgStructure* as = new ArgStructure;
7945
as->functionInfo = fi;
8046

81-
::attachInterruptArg (pin, static_cast<voidFuncPtrArg>(interruptFunctional), as, mode);
47+
attachInterruptArg (pin, interruptFunctional, as, mode);
8248
}
8349

8450
void attachScheduledInterrupt(uint8_t pin, std::function<void(InterruptInfo)> scheduledIntRoutine, int mode)
8551
{
86-
#if defined(ESP8266)
87-
interrupt_handler_t* handler = __getInterruptHandler(pin);
88-
#elif defined(ESP32)
89-
InterruptHandle_t* handler = __getInterruptHandler(pin);
90-
#endif
91-
if (handler->arg)
52+
void* localArg = detachInterruptArg(pin);
53+
if (localArg)
9254
{
93-
cleanupFunctional(handler->arg);
55+
cleanupFunctional(localArg);
9456
}
9557

9658
InterruptInfo* ii = new InterruptInfo(pin);
@@ -102,20 +64,14 @@ void attachScheduledInterrupt(uint8_t pin, std::function<void(InterruptInfo)> sc
10264
as->interruptInfo = ii;
10365
as->functionInfo = fi;
10466

105-
::attachInterruptArg (pin, static_cast<voidFuncPtrArg>(interruptFunctional), as, mode);
67+
attachInterruptArg(pin, interruptFunctional, as, mode);
10668
}
10769

10870
void detachFunctionalInterrupt(uint8_t pin)
10971
{
110-
#if defined(ESP8266)
111-
interrupt_handler_t* handler = __getInterruptHandler(pin);
112-
#elif defined(ESP32)
113-
InterruptHandle_t* handler = __getInterruptHandler(pin);
114-
#endif
115-
if (handler->arg)
72+
void* localArg = detachInterruptArg(pin);
73+
if (localArg)
11674
{
117-
cleanupFunctional(handler->arg);
75+
cleanupFunctional(localArg);
11876
}
119-
::detachInterrupt (pin);
12077
}
121-

0 commit comments

Comments
 (0)