On Thursday 07 December 2006 01:04 pm, Jeff King wrote:
> The problem is in my app:
>
> bool blocking;
>
> event void Boot.booted() {
>    bool tb = TRUE;
>    call MyDebugger.write("Booting, Part 1\r\n");
>    while (tb) {
>      atomic {
>        tb = blocking;
>      }
>    }
>    call MyDebugger.write("Booting, Part 2\r\n");
> }
>
> async event void MyDebugger.writeDone() {
>    atomic {
>      blocking = FALSE;
>    }
> }
>

As Phil already said, blocking needs to be volatile so the compiler doesn't 
optimize out the changes made by MyDebugger.writeDone() when it executes in 
interrupt context.

I think in general the need/desire for a spin lock or other similar 
continue-to-test strategies suggest that some of the best benefits of TinyOS 
aren't being fully exploited.  Granted, it can mean the organization of your 
code is trickier, not unlike that of a state machine.  The "TinyOS way", 
however, yields wins in lower energy consumption.  For most TinyOS apps, this 
is a big deal.

In your example above, I'd be tempted to post a task in 
MyDebugger.writeDone().  Maybe something like this:

int state;

Boot.booted()
{
    atomic state = PART_1;
    /* first part of boot stuff here */
    MyDebugger.write("part1");
}

task void boot2()
{
    atomic state = PART_2;
    /* second part of boot stuff here */
    MyDebugger.write("part2");
}

async event void MyDebugger.writeDone()
{
    if (state == PART_1)
        post boot2();
}

The state variable may be necessary if all writeDone events shouldn't funnel 
to the second part of the boot.  In other words, writeDone may need to 
dispatch based on state.  In this way, you get a "chain" of events that are 
tied together:  Boot -> write -> writeDone -> boot2 -> write -> writeDone, 
etc.

Hope this helps,
Steve
_______________________________________________
Tinyos-help mailing list
[email protected]
https://mail.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help

Reply via email to