-
Is there a way I can use the CB for handling function pointers. I’m trying to use it to queue multiple events that are pushed when either a timed or a pin interrupt occurs. |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 16 replies
-
Yes, there’s no reason why you shouldn’t! You just declare a buffer of your type, which is going to be the function reference of your choice: typedef void (*func)();
CircularBuffer<func,100> functions;
void a() {}
void b() {}
void c() {}
void setup() {
functions.push(a);
functions.push(b);
functions.push(c);
} Please, note I haven’t compiled the code above, I just pulled it out while on the go, it’s just a reference to describe how you can do it. |
Beta Was this translation helpful? Give feedback.
-
I got everything working except I seem to be screwing up memory. For the new classes, do I have to do a malloc, or something like that. I've eliminated the InteruptBuffer and am able to push 5 objects into the buffer. When I try to pop them, the first pops properly, the rest are ??? I know it's not the CB. I'm just not used to c++ and am not sure of how to proceed. |
Beta Was this translation helpful? Give feedback.
-
I've had a second look at your InteruptorClass InteruptClass::runNextInterupt()
{
// the following instruction retrieves the first element, also known as *head*
// NOTE: you are not checking for buffer emptiness, meaning you might be retrieving invalid memory!
InteruptorClass* interuptor = InteruptClass::peek();
if(interuptor->canRunFunction()){
interuptor->runInterupt();
// the following instruction extracts from the tail, also referred as *last element*
InteruptClass::pop();
interuptor->deleteMe();
}
else
{
// do nothimg - where waiting for period to elapse
}
} As you can see, you are executing one interrupt but deleting another one... I would restructure the code like the following, eliminating all the additional wrapping methods: // define your own method to add interrupts
InteruptorClass InteruptClass::enqueue(void (*fPointer)(InteruptorClass interupt),
EnumsClass::Interupt fifoLifoPush,
EnumsClass::Interupt functionName,
unsigned long period)
{
cBuffer.unshift(new InteruptorClass(fPointer, fifoLifoPush, functionName, period)); // adds a new item to the head
}
// I would personally call this simply *next()* or *run()*
InteruptorClass InteruptClass::runNextInterupt()
{
if(!cBuffer.isEmpty() && cBuffer.last()->canRunFunction()) { // inspects the tail
InteruptorClass* interuptor = cBuffer.pop(); // extracts the tail
interuptor->runInterupt();
// I wouldn't define a method to wrap a call to delete, you decide how objects are created and thus destroyed
// so as I've used the *new* operator above I'm using the *delete* operator here
delete interuptor;
}
else
{
// if it does nothing then remove the block
}
} Your code is also hard to follow because of the names you have picked up: Finally, the code flow is totally unclear to me and, honestly, overcomplicated. |
Beta Was this translation helpful? Give feedback.
-
Thanks for your follow-up. I am dealing with a dynamic array of class object, and all the samples I see are for statically created objects. Once I can get the dynamic class array working properly, I can then use your buffer properly. |
Beta Was this translation helpful? Give feedback.
-
@AbbottHMG I did something similar, having a dynamically growing array in ESP8266's heap of class/structs. I used a modified version of |
Beta Was this translation helpful? Give feedback.
-
It would be nice if you mark the answer which best responds to your question. Thank you |
Beta Was this translation helpful? Give feedback.
-
This is the working test version of my task manager. The task manger controls the CB and the task array that it points to. It also fills the CB with objects in the array. The ino loop empties the buffer. |
Beta Was this translation helpful? Give feedback.
Yes, there’s no reason why you shouldn’t! You just declare a buffer of your type, which is going to be the function reference of your choice:
Please, note I haven’t compiled the code above, I just pulled it out while on the go, it’s just a reference to describe how you can do it.
Also, by varying the typedef you can establish input parameters and return values: you are not limited to functions without parameters or return values, but they must all comply with the same interface.