Memory allocation problem
FabrizioRomanoGenovese opened this issue · 3 comments
First of all, thank you for the great library! My problem is the following: I need to define pretty big FSMs on my ESP8266, in the order of 400-500 transitions give or take. To make things more manageable, I've added this function to the library:
void SimpleFSM::addIncremental(Transition t[], int size) {
if ( (transitions == NULL) || (num_standard == 0) ) {
add(t, size);
}
else {
for (int i=num_standard; i < (num_standard + size); i++) {
transitions[i] = t[(i - num_standard)];
_addDotTransition(transitions[i]);
}
num_standard += size;
}
}
The idea is simple: Now I can define different arrays of states and transitions, like so:
State r[] = {
State("Living", living), // 0
State("Kitchen", kitchen), // 1
State("Office", office), // 2
State("Bedroom", bedroom), // 3
State("Bath Big", bathBig), // 4
State("Bath Small", bathSmall), // 5
};
State of[] = {
State("ofLights", lights), // 0
State("ofAC", airCon), // 1
State("ofCurtains", curtains), // 2
};
Transition tr[] = {
Transition(&r[0], &r[1], btnDownPressed),
Transition(&r[1], &r[2], btnDownPressed),
Transition(&r[2], &r[3], btnDownPressed),
Transition(&r[3], &r[4], btnDownPressed),
Transition(&r[4], &r[5], btnDownPressed),
Transition(&r[1], &r[0], btnUpPressed),
Transition(&r[2], &r[1], btnUpPressed),
Transition(&r[3], &r[2], btnUpPressed),
Transition(&r[4], &r[3], btnUpPressed),
Transition(&r[5], &r[4], btnUpPressed),
};
int num_tr = sizeof(tr) / sizeof(Transition);
Transition tof[] = {
Transition(&r[2], &of[0], btnEnterPressed),
Transition(&of[0], &of[1], btnDownPressed),
Transition(&of[1], &of[2], btnDownPressed),
Transition(&of[1], &of[0], btnUpPressed),
Transition(&of[2], &of[1], btnUpPressed),
Transition(&of[0], &r[2], btnBackPressed),
Transition(&of[1], &r[2], btnBackPressed),
Transition(&of[2], &r[2], btnBackPressed),
};
int num_tof = sizeof(tof) / sizeof(Transition);
and then add them separately, like so:
fsm.add(tr, num_tr);
fsm.addIncremental(tof, num_tof);
This is pretty much the only way I can think of to make editing of big FSMs manageable, as it allows some degree of compositionality. My problem is that the ESP8866 doesn't seem to handle this well.
- If I add just some transitions, then everything is fine.
- If I add a bit more (say around a total of 30), it behaves fine but at some point it crashes. I've added some
Serial.print
to thetrigger
function and I noticed that the transition output is garbled (e.g.transition.to
is cut or garbage altogethher). - If I keep adding transitions, the ESP eventually keeps crashing into a bootloop.
This makes me think that there is some problem with the memory management. I've tried to play with malloc
and realloc
a bit but being a total C++ noob I've ended up only wasting time. Any idea is appreciated!
By the way, I ran some tests using sizeOf
. A state should occupy 32 bytes, while a transition occupies 40. Given this, at the moment my states occupy 2400 bytes, while my transitions occupy 8040 bytes, for a total of 10440. My chip should have ~90KiB of memory for instructions, so I should be well within that limit.
Moreover, I checked https://github.com/jonblack/arduino-fsm/ to which this library is inspired: In https://github.com/jonblack/arduino-fsm/blob/master/Fsm.cpp the way to add transitions is incremental (it doesn't recurse over an array, but adds transitions one by one at user request). In particular, immediately before adding a transition, memory is reallocated by giving:
m_transitions = (Transition*) realloc(m_transitions, (m_num_transitions + 1) * sizeof(Transition));
I tried to do the same in the function I defined in the comment above, adding the line:
transitions = (Transition*) realloc(transitions, (num_standard + size) * sizeof(Transition));
just before the for
cycle. This has the only effect of putting my chip in a cycle of crashes.
Ok, solved it. Created a pull request in case someone is interested: #7
Hey Fabrizio,
thank you for your issue report and for your pull request!
Will review your code and merge it.
🙇