Comparison of Operating Systems Tinyos and Contiki: Tobias Reusing
Comparison of Operating Systems Tinyos and Contiki: Tobias Reusing
Tobias Reusing
Betreuer: Christoph Söllner
Seminar: Sensorknoten - Betrieb, Netze & Anwendungen SS2012
Lehrstuhl Netzarchitekturen und Netzdienste, Lehrstuhl Betriebssysteme und Systemarchitekturen
Fakultät für Informatik, Technische Universität München
Email: reusing@in.tum.de
// BlinkAppC . nc
configuration BlinkAppC { }
implementation { Figure 3: The TinyOS execution model. Compo-
components MainC , LedsC , TimerC , BlinkC ; nent boundaries are crossed between all of the com-
ponents[4]
BlinkC . Boot > MainC . Boot ;
BlinkC . Leds > LedsC . Leds ; 3.3 Resource Use
BlinkC . Timer > TimerC . Timer ; TinyOS was built with the goal of minimal resource con-
} sumption since wireless sensor nodes are generally very con-
strained in regards to processing speed, program memory,
Listing 1: Minimal example of a TinyOS application RAM and power consumption.
that turns a LED on and o↵ every second. With
modifications from [4]
3.3.1 Processing Power
To preserve processing power in TinyOS boundary crossings
between di↵erent components are optimized. Since all func-
tion locations are known at compile time and there is no
makes it possible that all tasks can use the same stack, which address-space crossing basic boundary crossing has at most
saves memory because not every task needs it’s own desig- the overhead of a single procedure call. With whole-program
nated stack like in a multi-threaded approach (see section 3.3 analysis many boundary crossings can be entirely removed.
for details). Normally tasks are executed in a first-in-first- In some cases the compiler can even inline a whole compo-
out (FIFO) order, so tasks run in the same order they’re nent into it’s caller[3].
posted[4], but it is possible to implement other (more com-
plex) scheduling strategies[2]. If there is no more task in the To keep the overhead of task-switching minimal the sched-
queue after completion of the previous task, TinyOS sets the uler in TinyOS is very simple. For example tasks have no
mote into a low-power sleep state until an interrupt wakes return value and take no parameters so the scheduler does
the microcontroller[4]. not need to take care of them[4, p. 72].
Code in TinyOS can only be executed in the context of ei-
ther a task or an interrupt. Interrupts can preempt tasks 3.3.2 Program Memory
and other interrupt handlers of lower priority. Code that is Since it is known at compile time, which components and
reachable from an interrupt handler is called asynchronous which parts of those components of the application and the
code and special measures have to be taken to handle con- operating system are used, the compiled image of the ap-
currency issues that can occur because of that (see Figure 3 plication includes only the actually used procedures and as
or [4, p. 192 ↵] for further details). good as no dead code. Also the operating system itself has
a very low memory footprint: The core TinyOS operating
Since tasks in TinyOS can not be preempted, long running system uses less than 400 bytes of program memory[3].
tasks, for example tasks that handle complex computations
like cryptographic functions, will block the whole application 3.3.3 RAM
and tasks that are time critical, like tasks handling sending Keeping the RAM usage of wireless sensor nodes low is
and receiving of data over a communication medium, may very important, since the used microcontrollers are very re-
be waiting for too long before the scheduler executes them. stricted in RAM size. For example the Atmel Atmega128L
In those cases the long running computation should be split micocontrollers used in the MICA2 sensor node[15] only of-
up in shorter running tasks that post themselves after com- fers 4 Kbytes of RAM[16] which have to be shared between
pleting a part of the computation, which enables other tasks the operating system and all running user programs. There
to run in between them. Since posting and executing a task are no memory management units (MMU) or other memory
generates a overhead of about 80 clock cycles on a current protection measures available on these microcontrollers so
Kernel While event handler can not preempt each other, interrupts
can of course preempt the current running process. To
prevent race-conditions from happening, events can not be
Core
posted from within interrupt handlers. Instead they can re-
quest the kernel to start polling at the next possible point
in time.
Figure 4: The partitioning of the Contiki core and
the loaded programs
On top of this basic event-driven kernel other execution
models can be used. Instead of the simple event handlers
processes can use Protothreads[7]. Protothreads are simple
The Contiki kernel o↵ers no hardware abstraction. If hard-
forms of normal threads in a multi-threaded environment.
ware abstraction is desired libraries and/or drivers have to
Protothreads are stackless so they have to save their state
implement it themselves. All components of a Contiki ap-
information in the private memory of the process. Like the
plication have direct access to the underlying hardware.
event handler Protothreads can not be preempted and run
until the Protothread puts itself into a waiting state until it
4.2 Execution Model is scheduled again[7].
The Contiki kernel is event-driven. Processes can only be
executed by the scheduler when it either dispatches an event Contiki also comes with a library that o↵ers preemptive
to the event handler of the process or by calling the polling multi-threading on top of the event-driven kernel. The li-
handler. While events always have to be signaled by a pro- brary is only linked with the program if an application ex-
cess, the scheduler can be configured to call the polling han- plicitly uses it. In contrast to Protothreads this multi-thread-
dlers of all processes that implement one in periodic intervals ing approach requires every thread to have it’s own desig-
between the dispatching of events. Both the event handlers nated stack[6].
and the polling handlers are not preempted by the scheduler
and therefore always run to completion. Like the tasks in Both multi-threading approaches were introduced because