forked from esp8266/Arduino
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Scheduled Interrupt * use capital letter for Schedule.h * Prevent memory leak when attach is called multiple times without detach * Add improved schedule_function * WIP : Integrate FunctionalInterrupt & ScheduledInterrupt * Fix travis error
- Loading branch information
Showing
5 changed files
with
272 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,70 @@ | ||
#include <FunctionalInterrupt.h> | ||
|
||
#include <Schedule.h> | ||
#include "Arduino.h" | ||
#include <ScheduledFunctions.h> | ||
|
||
// Duplicate typedefs from core_esp8266_wiring_digital_c | ||
typedef void (*voidFuncPtr)(void); | ||
typedef void (*voidFuncPtrArg)(void*); | ||
|
||
// Helper functions for Functional interrupt routines | ||
extern "C" void ICACHE_RAM_ATTR __attachInterruptArg(uint8_t pin, voidFuncPtr userFunc, void*fp , int mode); | ||
|
||
// Structure for communication | ||
struct ArgStructure { | ||
std::function<void(void)> reqFunction; | ||
}; | ||
|
||
void interruptFunctional(void* arg) | ||
{ | ||
((ArgStructure*)arg)->reqFunction(); | ||
ArgStructure* localArg = (ArgStructure*)arg; | ||
if (localArg->functionInfo->reqScheduledFunction) | ||
{ | ||
scheduledInterrupts->scheduleFunctionReg(std::bind(localArg->functionInfo->reqScheduledFunction,InterruptInfo(*(localArg->interruptInfo))), false, true); | ||
} | ||
if (localArg->functionInfo->reqFunction) | ||
{ | ||
localArg->functionInfo->reqFunction(); | ||
} | ||
} | ||
|
||
extern "C" | ||
{ | ||
void cleanupFunctional(void* arg) | ||
{ | ||
ArgStructure* localArg = (ArgStructure*)arg; | ||
delete (FunctionInfo*)localArg->functionInfo; | ||
delete (InterruptInfo*)localArg->interruptInfo; | ||
delete localArg; | ||
} | ||
} | ||
|
||
void attachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode) | ||
{ | ||
// use the local interrupt routine which takes the ArgStructure as argument | ||
__attachInterruptArg (pin, (voidFuncPtr)interruptFunctional, new ArgStructure{intRoutine}, mode); | ||
|
||
InterruptInfo* ii = nullptr; | ||
|
||
FunctionInfo* fi = new FunctionInfo; | ||
fi->reqFunction = intRoutine; | ||
|
||
ArgStructure* as = new ArgStructure; | ||
as->interruptInfo = ii; | ||
as->functionInfo = fi; | ||
|
||
__attachInterruptArg (pin, (voidFuncPtr)interruptFunctional, as, mode); | ||
} | ||
|
||
void attachScheduledInterrupt(uint8_t pin, std::function<void(InterruptInfo)> scheduledIntRoutine, int mode) | ||
{ | ||
if (!scheduledInterrupts) | ||
{ | ||
scheduledInterrupts = new ScheduledFunctions(32); | ||
} | ||
InterruptInfo* ii = new InterruptInfo; | ||
|
||
FunctionInfo* fi = new FunctionInfo; | ||
fi->reqScheduledFunction = scheduledIntRoutine; | ||
|
||
ArgStructure* as = new ArgStructure; | ||
as->interruptInfo = ii; | ||
as->functionInfo = fi; | ||
|
||
__attachInterruptArg (pin, (voidFuncPtr)interruptFunctional, as, mode); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/* | ||
* ScheduledFunctions.cpp | ||
* | ||
* Created on: 27 apr. 2018 | ||
* Author: Herman | ||
*/ | ||
#include "ScheduledFunctions.h" | ||
|
||
std::list<ScheduledFunctions::ScheduledElement> ScheduledFunctions::scheduledFunctions; | ||
|
||
ScheduledFunctions::ScheduledFunctions() | ||
:ScheduledFunctions(UINT_MAX) | ||
{ | ||
} | ||
|
||
ScheduledFunctions::ScheduledFunctions(unsigned int reqMax) | ||
{ | ||
maxElements = reqMax; | ||
} | ||
|
||
ScheduledFunctions::~ScheduledFunctions() { | ||
} | ||
|
||
ScheduledRegistration ScheduledFunctions::insertElement(ScheduledElement se, bool front) | ||
{ | ||
if (countElements >= maxElements) | ||
{ | ||
return nullptr; | ||
} | ||
else | ||
{ | ||
countElements++; | ||
if (front) | ||
{ | ||
scheduledFunctions.push_front(se); | ||
return scheduledFunctions.begin()->registration; | ||
} | ||
else | ||
{ | ||
scheduledFunctions.push_back(se); | ||
return scheduledFunctions.rbegin()->registration; | ||
} | ||
} | ||
} | ||
|
||
std::list<ScheduledFunctions::ScheduledElement>::iterator ScheduledFunctions::eraseElement(std::list<ScheduledFunctions::ScheduledElement>::iterator it) | ||
{ | ||
countElements--; | ||
return scheduledFunctions.erase(it); | ||
} | ||
|
||
bool ScheduledFunctions::scheduleFunction(ScheduledFunction sf, bool continuous, bool front) | ||
{ | ||
return (insertElement({this,continuous,nullptr,sf}, front) == nullptr); | ||
} | ||
|
||
bool ScheduledFunctions::scheduleFunction(ScheduledFunction sf) | ||
{ | ||
return scheduleFunction(sf, false, false); | ||
} | ||
|
||
ScheduledRegistration ScheduledFunctions::scheduleFunctionReg (ScheduledFunction sf, bool continuous, bool front) | ||
{ | ||
return insertElement({this,continuous,std::make_shared<int>(1),sf},front); | ||
} | ||
|
||
void ScheduledFunctions::runScheduledFunctions() | ||
{ | ||
auto lastElement = scheduledFunctions.end(); // do not execute elements added during runScheduledFunctions | ||
auto it = scheduledFunctions.begin(); | ||
while (it != lastElement) | ||
{ | ||
bool erase = false; | ||
if (it->registration == nullptr) | ||
{ | ||
it->function(); | ||
} | ||
else | ||
{ | ||
if (it->registration.use_count() > 1) | ||
{ | ||
it->function(); | ||
} | ||
else | ||
{ | ||
erase = true; | ||
} | ||
} | ||
if ((!it->continuous) || (erase)) | ||
{ | ||
it = it->_this->eraseElement(it); | ||
} | ||
else | ||
{ | ||
it++; | ||
} | ||
} | ||
} | ||
|
||
void ScheduledFunctions::removeFunction(ScheduledRegistration sr) | ||
{ | ||
auto it = scheduledFunctions.begin(); | ||
bool removed = false; | ||
while ((!removed) && (it != scheduledFunctions.end())) | ||
{ | ||
if (it->registration == sr) | ||
{ | ||
it = eraseElement(it); | ||
removed = true; | ||
} | ||
else | ||
{ | ||
it++; | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* ScheduledFunctions.h | ||
* | ||
* Created on: 27 apr. 2018 | ||
* Author: Herman | ||
*/ | ||
#include "Arduino.h" | ||
#include "Schedule.h" | ||
|
||
#include <functional> | ||
#include <memory> | ||
#include <list> | ||
#include <climits> | ||
|
||
#ifndef SCHEDULEDFUNCTIONS_H_ | ||
#define SCHEDULEDFUNCTIONS_H_ | ||
|
||
typedef std::function<void(void)> ScheduledFunction; | ||
typedef std::shared_ptr<void> ScheduledRegistration; | ||
|
||
class ScheduledFunctions { | ||
|
||
public: | ||
ScheduledFunctions(); | ||
ScheduledFunctions(unsigned int reqMax); | ||
virtual ~ScheduledFunctions(); | ||
|
||
struct ScheduledElement | ||
{ | ||
ScheduledFunctions* _this; | ||
bool continuous; | ||
ScheduledRegistration registration; | ||
ScheduledFunction function; | ||
}; | ||
|
||
ScheduledRegistration insertElement(ScheduledElement se, bool front); | ||
std::list<ScheduledElement>::iterator eraseElement(std::list<ScheduledElement>::iterator); | ||
bool scheduleFunction(ScheduledFunction sf, bool continuous, bool front); | ||
bool scheduleFunction(ScheduledFunction sf); | ||
ScheduledRegistration scheduleFunctionReg (ScheduledFunction sf, bool continuous, bool front); | ||
static void runScheduledFunctions(); | ||
void removeFunction(ScheduledRegistration sr); | ||
|
||
|
||
static std::list<ScheduledElement> scheduledFunctions; | ||
unsigned int maxElements; | ||
unsigned int countElements = 0; | ||
|
||
}; | ||
|
||
#endif /* SCHEDULEDFUNCTIONS_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters