From 9e239eca0ca7cbc84fcbec70d1a4c6de7770c44e Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Fri, 3 May 2019 12:11:17 +0200 Subject: [PATCH] Invented void* detachInterruptArg() that returns the argument given in attachInterruptArg(). This is sufficient for resource management - the function has static duration anyway. --- cores/esp8266/Arduino.h | 3 +- cores/esp8266/core_esp8266_wiring_digital.cpp | 11 ++- .../FunctionalInterrupts.cpp | 82 +++++-------------- 3 files changed, 28 insertions(+), 68 deletions(-) diff --git a/cores/esp8266/Arduino.h b/cores/esp8266/Arduino.h index 91ef7a43f1..2be19b5e22 100644 --- a/cores/esp8266/Arduino.h +++ b/cores/esp8266/Arduino.h @@ -217,8 +217,9 @@ void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); void attachInterrupt(uint8_t pin, void (*)(void), int mode); -void attachInterruptArg(uint8_t pin, void (*)(void*), void * arg, int mode); void detachInterrupt(uint8_t pin); +void attachInterruptArg(uint8_t pin, void (*)(void*), void* arg, int mode); +void* detachInterruptArg(uint8_t pin); void preinit(void); void setup(void); diff --git a/cores/esp8266/core_esp8266_wiring_digital.cpp b/cores/esp8266/core_esp8266_wiring_digital.cpp index acf8f470f8..c96033df42 100644 --- a/cores/esp8266/core_esp8266_wiring_digital.cpp +++ b/cores/esp8266/core_esp8266_wiring_digital.cpp @@ -192,8 +192,10 @@ extern void __detachInterrupt(uint8_t pin) { } } -extern interrupt_handler_t* __getInterruptHandler(uint8_t pin) { - return (pin < 16) ? &interrupt_handlers[pin] : nullptr; +extern void* __detachInterruptArg(uint8_t pin) { + void* arg = (pin < 16) ? interrupt_handlers[pin].arg : nullptr; + __detachInterrupt(pin); + return arg; } void initPins() { @@ -215,7 +217,8 @@ extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pi extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias("__digitalWrite"))); extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead"))); extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt"))); -extern void attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void* arg, int mode) __attribute__ ((weak, alias("__attachInterruptArg"))); -extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt"))); +extern void detachInterrupt(uint8_t pin) __attribute__((weak, alias("__detachInterrupt"))); +extern void attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void* arg, int mode) __attribute__((weak, alias("__attachInterruptArg"))); +extern void* detachInterruptArg(uint8_t pin) __attribute__((weak, alias("__detachInterruptArg"))); }; diff --git a/libraries/esp8266/examples/GPIO/FunctionalInterrupt/FunctionalInterrupts.cpp b/libraries/esp8266/examples/GPIO/FunctionalInterrupt/FunctionalInterrupts.cpp index 8b56e61b2c..be29554bc2 100644 --- a/libraries/esp8266/examples/GPIO/FunctionalInterrupt/FunctionalInterrupts.cpp +++ b/libraries/esp8266/examples/GPIO/FunctionalInterrupt/FunctionalInterrupts.cpp @@ -2,38 +2,6 @@ #include #include "Arduino.h" -#if defined(ESP8266) - -// Duplicate typedefs from core_esp8266_wiring_digital.cpp -// Keep in sync -typedef void (*voidFuncPtr)(void); -typedef void (*voidFuncPtrArg)(void*); - -typedef struct { - uint8_t mode; - voidFuncPtr fn; - void* arg; -} interrupt_handler_t; - -// Helper functions for Functional interrupt routines -extern "C" interrupt_handler_t* __getInterruptHandler(uint8_t pin); - -#elif defined(ESP32) - -// Duplicate typedefs from esp32-hal-gpio.c -// Keep in sync -typedef void (*voidFuncPtr)(void); -typedef void (*voidFuncPtrArg)(void*); -typedef struct { - voidFuncPtr fn; - void* arg; -} InterruptHandle_t; - -// Helper functions for Functional interrupt routines -extern "C" InterruptHandle_t* __getInterruptHandler(uint8_t pin); - -#endif - void ICACHE_RAM_ATTR interruptFunctional(void* arg) { ArgStructure* localArg = static_cast(arg); @@ -44,7 +12,9 @@ void ICACHE_RAM_ATTR interruptFunctional(void* arg) } if (localArg->functionInfo->reqScheduledFunction) { - schedule_function(std::bind(localArg->functionInfo->reqScheduledFunction,InterruptInfo(*(localArg->interruptInfo)))); + schedule_function( + [reqScheduledFunction = localArg->functionInfo->reqScheduledFunction, + interruptInfo = *localArg->interruptInfo]() { reqScheduledFunction(interruptInfo); }); } if (localArg->functionInfo->reqFunction) { @@ -52,24 +22,20 @@ void ICACHE_RAM_ATTR interruptFunctional(void* arg) } } - void cleanupFunctional(void* arg) - { - ArgStructure* localArg = static_cast(arg); - delete localArg; - } +void cleanupFunctional(void* arg) +{ + ArgStructure* localArg = static_cast(arg); + delete localArg; +} void attachInterrupt(uint8_t pin, std::function intRoutine, int mode) { // use the local interrupt routine which takes the ArgStructure as argument -#if defined(ESP8266) - interrupt_handler_t* handler = __getInterruptHandler(pin); -#elif defined(ESP32) - InterruptHandle_t* handler = __getInterruptHandler(pin); -#endif - if (handler->arg) + void* localArg = detachInterruptArg(pin); + if (localArg) { - cleanupFunctional(handler->arg); + cleanupFunctional(localArg); } FunctionInfo* fi = new FunctionInfo; @@ -78,19 +44,15 @@ void attachInterrupt(uint8_t pin, std::function intRoutine, int mode ArgStructure* as = new ArgStructure; as->functionInfo = fi; - ::attachInterruptArg (pin, static_cast(interruptFunctional), as, mode); + attachInterruptArg (pin, interruptFunctional, as, mode); } void attachScheduledInterrupt(uint8_t pin, std::function scheduledIntRoutine, int mode) { -#if defined(ESP8266) - interrupt_handler_t* handler = __getInterruptHandler(pin); -#elif defined(ESP32) - InterruptHandle_t* handler = __getInterruptHandler(pin); -#endif - if (handler->arg) + void* localArg = detachInterruptArg(pin); + if (localArg) { - cleanupFunctional(handler->arg); + cleanupFunctional(localArg); } InterruptInfo* ii = new InterruptInfo(pin); @@ -102,20 +64,14 @@ void attachScheduledInterrupt(uint8_t pin, std::function sc as->interruptInfo = ii; as->functionInfo = fi; - ::attachInterruptArg (pin, static_cast(interruptFunctional), as, mode); + attachInterruptArg(pin, interruptFunctional, as, mode); } void detachFunctionalInterrupt(uint8_t pin) { -#if defined(ESP8266) - interrupt_handler_t* handler = __getInterruptHandler(pin); -#elif defined(ESP32) - InterruptHandle_t* handler = __getInterruptHandler(pin); -#endif - if (handler->arg) + void* localArg = detachInterruptArg(pin); + if (localArg) { - cleanupFunctional(handler->arg); + cleanupFunctional(localArg); } - ::detachInterrupt (pin); } -