Skip to content

Commit 2768906

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 e530b68 commit 2768906

File tree

3 files changed

+28
-70
lines changed

3 files changed

+28
-70
lines changed

cores/esp32/esp32-hal-gpio.c

+7-6
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ typedef struct {
7575
voidFuncPtr fn;
7676
void* arg;
7777
} InterruptHandle_t;
78-
static InterruptHandle_t __pinInterruptHandlers[GPIO_PIN_COUNT] = {0,};
78+
static InterruptHandle_t __pinInterruptHandlers[GPIO_PIN_COUNT] = { {0,0}, };
7979

8080
#include "driver/rtc_io.h"
8181

@@ -275,15 +275,16 @@ extern void __detachInterrupt(uint8_t pin)
275275
esp_intr_enable(gpio_intr_handle);
276276
}
277277

278-
extern InterruptHandle_t* __getInterruptHandler(uint8_t pin) {
279-
return (pin < GPIO_PIN_COUNT) ? &__pinInterruptHandlers[pin] : NULL;
278+
extern void* __detachInterruptArg(uint8_t pin) {
279+
void* arg = (pin < GPIO_PIN_COUNT) ? __pinInterruptHandlers[pin].arg : NULL;
280+
__detachInterrupt(pin);
281+
return arg;
280282
}
281283

282-
283284
extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pinMode")));
284285
extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias("__digitalWrite")));
285286
extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead")));
286287
extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt")));
288+
extern void detachInterrupt(uint8_t pin) __attribute__((weak, alias("__detachInterrupt")));
287289
extern void attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void * arg, int mode) __attribute__ ((weak, alias("__attachInterruptArg")));
288-
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));
289-
290+
extern void* detachInterruptArg(uint8_t pin) __attribute__((weak, alias("__detachInterruptArg")));

cores/esp32/esp32-hal-gpio.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,9 @@ void digitalWrite(uint8_t pin, uint8_t val);
7979
int digitalRead(uint8_t pin);
8080

8181
void attachInterrupt(uint8_t pin, void (*)(void), int mode);
82-
void attachInterruptArg(uint8_t pin, void (*)(void*), void * arg, int mode);
8382
void detachInterrupt(uint8_t pin);
83+
void attachInterruptArg(uint8_t pin, void (*)(void*), void* arg, int mode);
84+
void* detachInterruptArg(uint8_t pin);
8485

8586
#ifdef __cplusplus
8687
}

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

+19-63
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)