On Wed, Feb 8, 2012 at 5:28 AM, <[email protected]> wrote:
> Dear Eric.
>
> Sorry for this elemental question but has arised a doubt about which is
> the execution sequence in the Blink Application
>
>
No need to be sorry. Elemental questions are good and indicate sound
thinking about "How does this work anyway".
I encourage that.
The core of the system is the scheduler and the scheduler loop.
Take a look at tos/system/RealMainP.nc.
After various platform/scheduler initialization things we have the
following:
signal Boot.booted();
call Scheduler.taskLoop();
The later never returns and is responsible for sleeping the processor when
there is nothing to do. Something to do
is defined as work being in the task queue. When the task queue is empty,
the processor goes to sleep.
So here is how this effects Blink.
> --------------Extract of BlinkC.nc-------------------------------------
>
> implementation
> {
> event void Boot.booted()
> {
> call Timer0.startPeriodic( 250 );
> call Timer1.startPeriodic( 500 );
> call Timer2.startPeriodic( 1000 );
> }
>
The above gets wired into MainC.Boot and gets executed when RealMain
executes the signal Boot.booted().
There are 3 timers defined and the startPeriodic causes the associated data
structures to be modified to reflect when the timer is desired to expire.
Each call to startPeriodic also posts a task that runs through all the
timer structures and sets the underlying h/w up so a timer interrupt is
generated when the earliest timer expires. This task executes after all
booted routines are called from the above signal and the taskLoop has
started to execute.
The taskLoop is responsible for executing tasks. Tasks are posted from
various pieces of code using "post". Tasks once posted are executed in
strict FIFO order. However a given task can only be pending once. Once
posted (and not executed) a task can not be posted again. You can post
again but for however many posts are done, the task will still only execute
once. The first post will return SUCCESS, all others will return EBUSY.
Note: once a task has been pulled from the queue and starts to execute, it
is no longer pending so the task can actually post itself if it has more
work to do and wants to let other tasks execute. But posting itself will
put the task at the end of the FIFO.
Back to how timers work. Last we left it, the timer h/w has been set up
to interrupt when the earliest timer will expire. This interrupt causes a
low level Timer signal to be generated which eventually ends up posting a
Timer task. This is the physical Timer that provides the low level
infrastructure for virtualized timers.
The Timer task will eventually run once any interrupts have finished and we
have returned to the taskLoop. The Timer task is responsible for scanning
the Timer data structures and issues a Timer.fired() signal for any timer
that has expired. This is the implementation of the virtualized timers.
Each virtual timer is represented by a Timer data structure.
Because the timers were started with startPeriodic, the timer is restarted
using the dt parameter.
>
> event void Timer0.fired()
> {
> dbg("BlinkC", "Timer 0 fired @ %s.\n", sim_time_string());
> call Leds.led0Toggle();
> }
>
> event void Timer1.fired()
> {
> dbg("BlinkC", "Timer 1 fired @ %s \n", sim_time_string());
> call Leds.led1Toggle();
> }
>
> event void Timer2.fired()
> {
> dbg("BlinkC", "Timer 2 fired @ %s.\n", sim_time_string());
> call Leds.led2Toggle();
> }
> }
> -------------------------------------------------------------------------
>
> The next is correct?
>
> 1) First is executed the "event void Boot.booted()" setting the time values
>
yes. this is executed from the initial "signal Boot.booted()" on start up.
The Timer<n>.fired clauses get executed after the timer h/w has been set up
and the Timer task determines the timer has expired. One or more Timer
events can be signaled off a single Timer task execution depending on which
virtual timers have expired.
2) Then is executed "event void Timer0.fired()" turn the red LED,
> according to the time in 1)
>
>
> 3) Then is executed "event void Timer1.fired()" turn the yellow LED,
> according to the time in 1)
>
>
> 3) Then is executed "event void Timer1.fired()" turn the blue LED,
> according to the time in 1)
>
> 5) Finally, since in TinyOS, the execution model is FIFO from step 4)
> return to the 1) and so on?
>
Doesn't really apply. In the context we are talking this isn't how things
work. There isn't any isolation or sequencing enforced in the timers.
They effectively execute independently of each other. One or more
Timer.fired signals may execute strictly dependent upon whether the Timer
has expired.
> It seems to me that after running event void Boot.booted() // setting the
> time values.
>
>
> Is make up independent execution threads with:
>
I don't understand what you are getting at. I'm not parsing your english.
> event void Timer0.fired()
>
> event void Timer1.fired()
>
> event void Timer2.fired()
>
>
>
> But in this case TinyOS will be working in a way different from FIFO?
>
Signals are orthogonal to tasks. Talking about signals being FIFO is
nonsensical.
Tasks are strictly FIFO. Because of how the basic scheduler is
implemented.
Hopefully that clears some things up.
eric
>
> Thanks in advance for your kind answer.
>
> Regards,
>
>
> Alejandro.
>
>
--
Eric B. Decker
Senior (over 50 :-) Researcher
_______________________________________________
Tinyos-help mailing list
[email protected]
https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help