I'm writing my controller code as a sequence of modules that each run their own little state machines.
The main code just loops through them in order and steps them to evaluate inputs and perhaps select a new output step.
This works great, is quite robust, and uses entirely statically allocated data -- perfect for embedded computing.
But, the code for those state machines is somewhat annoying to evolve. (This is the main known draw-back of the method in question)
So, on bigger systems, where dynamic allocation won't lead to accidental thermonuclear death, we can use threads (separate from pre-emption -- cooperative threads are still threads.)
The draw-back is -- each state machine has to have its own call stack, and the stack pointer and machine state has to be moved around when task switching, and each call stack must also be big enough to fit the maximum interrupt handler, too.
But, let's say that I'm a lazy slob, and also that the Teensy3.2 has SOO MUCH SPACE that I'm not worried about running out -- what's a good task (thread) library to use? I imagine it needs to support approximately three primitives:
- spawn new task
- yield to other waiting tasks
- some kind of thread suspend/resume
sempahores/locks would perhaps be useful, too, but can be written on top of those primitives.
Note that I'm looking for convenience here -- something that is a drop-in for Teensy would be great. Something that requires I re-tool, download a proprietary IDE, and use the stock Freescale support libraries, not so much.
The main code just loops through them in order and steps them to evaluate inputs and perhaps select a new output step.
This works great, is quite robust, and uses entirely statically allocated data -- perfect for embedded computing.
But, the code for those state machines is somewhat annoying to evolve. (This is the main known draw-back of the method in question)
Code:
void Thing::step() {
switch (state_) {
case STATE_ONE:
if (found_a_thing()) {
gotoState(STATE_TWO);
} else if (stateTimeout(300)) {
gotoState(STATE_FIVE);
}
break;
case STATE_TWO:
...
}
}
So, on bigger systems, where dynamic allocation won't lead to accidental thermonuclear death, we can use threads (separate from pre-emption -- cooperative threads are still threads.)
Code:
void Thing::loop() {
if (wait_for_a_thing(300)) {
do_state_two_things();
} else {
timeout code
}
}
The draw-back is -- each state machine has to have its own call stack, and the stack pointer and machine state has to be moved around when task switching, and each call stack must also be big enough to fit the maximum interrupt handler, too.
But, let's say that I'm a lazy slob, and also that the Teensy3.2 has SOO MUCH SPACE that I'm not worried about running out -- what's a good task (thread) library to use? I imagine it needs to support approximately three primitives:
- spawn new task
- yield to other waiting tasks
- some kind of thread suspend/resume
sempahores/locks would perhaps be useful, too, but can be written on top of those primitives.
Note that I'm looking for convenience here -- something that is a drop-in for Teensy would be great. Something that requires I re-tool, download a proprietary IDE, and use the stock Freescale support libraries, not so much.