Re: [Tinyos-help] [Tinyos-devel] parametrized interfaces : an array of timers

2010-10-01 Thread David Gay
On Wed, Sep 22, 2010 at 12:14 AM, Roger Larsson  wrote:
>> So the fix is to add:
>>
>>   default command Timers.startPeriodic[int id](int interval) {
>>     ... complain/handle/ignore unexpected call ...
>>   }
>>
>
> That this command has to be written feels wrong for three reasons...
> 1) compiler error does not even talk about the need for a 'default',
>    >> BlinkC.nc:51: Timers.startPeriodic not connected
>    even when being on the right track you easily run inte other compile
>    errors that won't help you toward the correct solution

Probably a good idea to add an explanation of the possible fixes
(either add a wiring or a default handler) on the first occurrence of
the error message.

> 2) has to be written
> 3) not in Timers.ncc (shouldn't all Timers.xx commands be in Timers.ncc?)

No - the Timer code has nothing to do with this, it's your code that
has to decide what to do when trying to invoke a non-existent timer.
More paranoid code than TinyOS typically contains might:
- log an error somewhere
- attempt some recovery action
- ...
All of the above depend on the caller, not the callee.

>> Note that it would of course be possible to write an analysis that
>> detected that in this particular program there's no need for a
>> "default" startPeriodic command. However that would be a bad idea (in
>> general at least), as:
>
>> - it makes BlinkC less of a standalone component (the missing
>> startPeriodic command will be needed for some wiring patterns)
>
> But adding this to BlinkC.ncc gives the same problem, shouldn't really be 
> added to BlinkAppC.ncc
> Or can the compiler handle several modules defining this function? (each with 
> its own unique count series?)
> - this unique() / uniqueCount() stuff just don't feel right...
>
>> - it makes code's correctness quite dependent on exactly what analysis
>> is performed in the compiler to detect when default commands/events
>> are not required (should 'for (i = 0; i < 2; i++) call
>> Timers.startPeriodic[i](...);' work too?)
>
> A lot more likely code would be
>
> for (int i=0; i < uniqueCount("Timers"); i++)
>  Timers.startPeriodic[i](...)
>
> This pattern could be statically analysed and code generated. But if not 
> wouldn't the compiler need to put a dispatch handling somewhere?

Yes, as I said it could be analysed (2 or uniqueCount() would be
equally easily analysed FWIW). But I'm of the strong opinion that
making code correctness depend on fancy-ish analyses is a bad idea
(fancy analyses are great for optimization or bug-finding, but that's
a separate activity).

> Why not in an automatically generated default function, calling something 
> like handle_..._error() in default case?
> And let the user define this 'handle_..._error' function instead!

Because hiding potential errors is bad. And the "default" handler is
this "handle...error" function you want, on a per-module basis.

>
> And finally: Why doesn't isn't the Blink example code use this feature in the 
> first place?

Because it doesn't expect to have its timers unwired (and would fail
if they were). Note that some components do have default handlers for
some interfaces, e.g. for optional callbacks (the module signals some
event, but it's ok if no-one cares).

David Gay

___
Tinyos-help mailing list
Tinyos-help@millennium.berkeley.edu
https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help


Re: [Tinyos-help] [Tinyos-devel] parametrized interfaces : an array of timers

2010-09-22 Thread Roger Larsson
> So the fix is to add:
> 
>   default command Timers.startPeriodic[int id](int interval) {
> ... complain/handle/ignore unexpected call ...
>   }
>

That this command has to be written feels wrong for three reasons...
1) compiler error does not even talk about the need for a 'default',
>> BlinkC.nc:51: Timers.startPeriodic not connected
even when being on the right track you easily run inte other compile
errors that won't help you toward the correct solution
2) has to be written
3) not in Timers.ncc (shouldn't all Timers.xx commands be in Timers.ncc?)
 
> Note that it would of course be possible to write an analysis that
> detected that in this particular program there's no need for a
> "default" startPeriodic command. However that would be a bad idea (in
> general at least), as:

> - it makes BlinkC less of a standalone component (the missing
> startPeriodic command will be needed for some wiring patterns)

But adding this to BlinkC.ncc gives the same problem, shouldn't really be added 
to BlinkAppC.ncc
Or can the compiler handle several modules defining this function? (each with 
its own unique count series?)
- this unique() / uniqueCount() stuff just don't feel right...

> - it makes code's correctness quite dependent on exactly what analysis
> is performed in the compiler to detect when default commands/events
> are not required (should 'for (i = 0; i < 2; i++) call
> Timers.startPeriodic[i](...);' work too?)

A lot more likely code would be

for (int i=0; i < uniqueCount("Timers"); i++)
  Timers.startPeriodic[i](...)

This pattern could be statically analysed and code generated. But if not 
wouldn't the compiler need to put a dispatch handling somewhere?
Why not in an automatically generated default function, calling something like 
handle_..._error() in default case?
And let the user define this 'handle_..._error' function instead!

And finally: Why doesn't isn't the Blink example code use this feature in the 
first place?

/RogerL
___
Tinyos-help mailing list
Tinyos-help@millennium.berkeley.edu
https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help


Re: [Tinyos-help] [Tinyos-devel] parametrized interfaces : an array of timers

2010-09-21 Thread David Gay
On Wed, Sep 15, 2010 at 3:46 AM, Roger Larsson  wrote:
> I have been fighting this as well (see my mail Multichannel Oscilloscope try 
> to compile with SENSOR_ARRAY
> http://www.mail-archive.com/tinyos-help@millennium.berkeley.edu/msg34868.html 
> )
>
> Lets take this question to tinyos-devel
>
> My guess is that the compilers does not support this - it could, since code 
> could be generated statically.

There's no compiler/language problem. See below for a description of
the fix (and the related misunderstanding).

> Från: tinyos-help-boun...@millennium.berkeley.edu 
> [tinyos-help-boun...@millennium.berkeley.edu] för Anna Förster 
> [anna.foers...@supsi.ch]
> Skickat: den 15 september 2010 11:23
> Till: tinyos-help@millennium.berkeley.edu
> Ämne: [Tinyos-help] parametrized interfaces : an array of timers
>
> Dear all,
>
> I have some troubles implementing a parametrized interface of Timers. I have 
> used the code snippets from "Software design Patterns for Tinyos" from Gay et 
> al. and some hints online and from this mailing list. I am attaching the 
> complete code (it is basically the Blink application with an array of 3 
> timers). When compiling, the error is:
>
> In component `BlinkC':
> BlinkC.nc: In function `Boot.booted':
> BlinkC.nc:51: Timers.startPeriodic not connected
> BlinkC.nc:52: Timers.startPeriodic not connected
> BlinkC.nc:53: Timers.startPeriodic not connected
> make: *** [exe0] Error 1
>
> I found a hint on this mailing list from Phil Lewis that I need a default 
> implementation for the event, but this hint leads to yet another compilation 
> error, saying:
>
> In file included from BlinkAppC.nc:45:
> In component `BlinkC':
> BlinkC.nc:61: `fired' is defined, not used, in this component
> BlinkC.nc:61: (default implementations are only for used commands or events)
> BlinkC.nc:61: conflicting types for `Timers.fired'
> BlinkC.nc:56: previous declaration of `Timers.fired'
> make: *** [exe0] Error 1
>
> I would be very thankful for any ideas of how to get this wokrking. And, yes, 
> I am sure I need such a parametrized interface (not for the Blink 
> application, of course.. ) :-)
>
> Anna
>
> CODE
> 
>
> ##
> BlinkAppC.nc:
> ##
>
> configuration BlinkAppC
> {
> }
> implementation
> {
>  components MainC, BlinkC, LedsC;
>  components new TimerMilliC() as Timer0;
>  components new TimerMilliC() as Timer1;
>  components new TimerMilliC() as Timer2;
>
>
>  BlinkC -> MainC.Boot;
>
>  BlinkC.Timers[0] -> Timer0;
>  BlinkC.Timers[1] -> Timer1;
>  BlinkC.Timers[2] -> Timer2;
>  BlinkC.Leds -> LedsC;
> }

All good...

>
> ##
> BlinkC.nc
> ##
>
> #include "Timer.h"
>
> module BlinkC @safe()
> {
>  uses interface Timer as Timers[int id];
> //  uses interface Timer as Timer1;
> //  uses interface Timer as Timer2;
>  uses interface Leds;
>  uses interface Boot;
> }
> implementation
> {
>  event void Boot.booted()
>  {
>   call Timers.startPeriodic[0]( 250 );
>   call Timers.startPeriodic[1]( 500 );
>   call Timers.startPeriodic[2]( 1000 );
>  }
>
>  event void Timers.fired[int id1]()
>  {
>    int id = 0;
>  }
>
> /*default event void Timers.fired() { } */

The thing that needs a 'default' implementation is startPeriodic.
Think of what happens in the code:

1. You're calling the startPeriodic command on some interface in the
Timers "parameterized interface", passing in an expression 'e' to
specify which interface you want (in this code, e is respecticely 0,
1, and 2 but in general could be any expression).
2. The implementation must evaluate e (at runtime) and dispatch to the
interface you wired to (so, in general, the compiler has no idea what
values e might take).
3. What should it do if e happens to evaluate to some value for which
there's no corresponding interface wired in BlinkAppC? The answer is
call a "default" implementation that you specified (this can do some
default handling, report an error, etc).

So the fix is to add:

  default command Timers.startPeriodic[int id](int interval) {
... complain/handle/ignore unexpected call ...
  }

Note that it would of course be possible to write an analysis that
detected that in this particular program there's no need for a
"default" startPeriodic command. However that would be a bad idea (in
general at least), as:
- it makes BlinkC less of a standalone component (the missing
startPeriodic command will be needed for some wiring patterns)
- it makes code's correctness quite dependent on exactly what analysis
is performed in the compiler to detect when default commands/events
are not required (should 'for (i = 0; i < 2; i++) call
Timers.startPeriodic[i](...);' work too?)

David Gay

___
Tinyos-help mailing list
Tinyos-help@millennium.berkeley.edu
https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help