Grant Edwards wrote:
On 2007-11-14, Adam Dunkels <[email protected]> wrote:
Grant Edwards wrote:
On 2007-11-14, Grant Edwards <[email protected]> wrote:
Is anybody aware of a lightweight coroutine implementation for
mspgcc? The yield operation would need to be implemented
without disabling interrupts...
Protothreads looks promising:
http://www.sics.se/~adam/pt/
Yes, protothreads do not require any interrupt-disabling code
(or any other low-level code for that matter - no assembler,
no stack manipulation, etc - protothreads are pure C).
I guess I shouldn't be surprised that Adam reads this group
considering the original protothreads paper talked about
low-power wireless sensor nodes. :)
I see that the gcc "pointers to labels" implementation is what
is used by default (which removes the restriction on using
switch() statements in a protothread).
I think it actually defaults to the switch()-based implementation. If
you are using gcc, the label-pointer implementation is better as it
doesn't inhibit switches. It is also slightly faster (at least on the
MSP430).
The memory overhead is very low: only two bytes per
protothread. Beware, however, that because protothreads are
stackless, local variables are not stored across a blocking
wait. Either use static local variables or pass around a state
struct like event-driven programming.
Yup. That'll take a little getting used to, but hopefully gcc
will warn me if I forget. In practice very, very few of the
tasks I write ever need to be re-entrant, so static locals for
persistent stuff are are fine.
Yes, gcc with a -O option warns that the variables "might be used
uninitialized in this function". Running with -Werror should make this
even more visible.
The overhead or protothreads compared to an explicit
switch()-based state machine is a few cycles so protothreads
can even be used in time-critical code such as interrupts [1].
We're using them in Contiki [2] for a bunch of different
purposes ranging from low-level radio framing protocol parsers
(inside an interrupt handler) to the high-level process
structure of Contiki.
I think it's going to fit my application very well. I've got
I've also got a fairly minimal amount of RAM to play with and
some low-level interrupt-driven stuff that runs in the
background which can't tolerate any extra interrupt latency at
all. IOW: no disabling interrupts and no multiple stacks. But,
I've got a couple different independent "threads" that need to
run in the foreground using some sort of cooperative
multitasking, and making them all into explicit state-machines
would be messy. They'll be much easier to write as implicit
state-machines using protthreads.
Sounds like the perfect match for protothreads.
/adam
--
Adam Dunkels <[email protected]>
http://www.sics.se/~adam/