Upload
others
View
11
Download
1
Embed Size (px)
Citation preview
182.694 Microcontroller VU
Martin PernerSS 2017
Featuring Today:TinyOS Part 2
Weekly Training Objective
Already done
3.4.1 Input capture3.6.3 SPI ∗3.7.2 Watchdog ∗
This week
4.2.1 UART to GLCD †4.2.2 Keypad4.2.3 Debounced Buttons ∗
Martin Perner TinyOS Part 2 May 22, 2017 2
TinyOS – Recap
TinyOS
is a small operating system that is designed to run on low-power wireless sensor nodes,and networked embedded systems.
provides a set of important services and abstractions.
defines a concurrent execution model.
is written in nesC, which is a C dialect.
can be seen as a mixture of OOP and hardware wiring.
Martin Perner TinyOS Part 2 May 22, 2017 3
TinyOS first steps
Flash an example application
in apps/Blink/ execute$ make bigAVR6 1280
with connected board execute$ make bigAVR6 1280 install
A binary is generated and downloaded.
Hint
$ make bigAVR6 1280 install,id
Sets TOS NODE ID to the value of id.This can be used, e.g., for defining the IP address of the node, or allow for differentfunctionality (master/slave).
Martin Perner TinyOS Part 2 May 22, 2017 4
Interfaces
Enabling reusability
Multiple interfaces can be used/provided.
Interfaces are bidirectional.
command, implemented by provider of the interface, called by user.event, implemented by user of the interface, signaled by provider.
Bidirectionality is the basis for split-phase.
Martin Perner TinyOS Part 2 May 22, 2017 5
Example Interface
A generic timer interface – Timer.nc
i n t e r f a c e Timer<p r e c i s i o n t a g>{
command vo id s t a r t P e r i o d i c ( u i n t 3 2 t dt ) ;command vo id s ta r tOneShot ( u i n t 3 2 t dt ) ;command vo id s top ( ) ;e ven t vo id f i r e d ( ) ;
. . .}
Interface, and thus timer-usage, independent of microcontroller used.
Martin Perner TinyOS Part 2 May 22, 2017 6
Configurations
Wiring
TinyOS only allows to wire interfaces. This wiring is done in configurations.
Connecting interfaces of components via -> resp. <-
The arrow goes from user to provider!
Connecting an interface of the configuration to an interface of a component is done with =
Martin Perner TinyOS Part 2 May 22, 2017 7
Example Configuration
Configuration
c o n f i g u r a t i o n DemoC{
us e s i n t e r f a c e Boot ;p r o v i d e s i n t e r f a c e MoreMagic ;
}
imp l ementa t i on{
components DemoP , MakeMagicC ;
Boot = DemoP . Boot ;MoreMagic = MakeMagicC . MoreMagic ;
MakeMagicC . Magic −> DemoP . Magic ;}
DemoC
Boot
MoreMagic
Martin Perner TinyOS Part 2 May 22, 2017 8
Example Configuration
Configuration
c o n f i g u r a t i o n DemoC{
us e s i n t e r f a c e Boot ;p r o v i d e s i n t e r f a c e MoreMagic ;
}
imp l ementa t i on{
components DemoP , MakeMagicC ;
Boot = DemoP . Boot ;MoreMagic = MakeMagicC . MoreMagic ;
MakeMagicC . Magic −> DemoP . Magic ;}
DemoC
Boot
MoreMagic
DemoP
Magic
Boot
MakeMagicC
MoreMagic
Magic
Martin Perner TinyOS Part 2 May 22, 2017 8
Example Configuration
Configuration
c o n f i g u r a t i o n DemoC{
us e s i n t e r f a c e Boot ;p r o v i d e s i n t e r f a c e MoreMagic ;
}
imp l ementa t i on{
components DemoP , MakeMagicC ;
Boot = DemoP . Boot ;MoreMagic = MakeMagicC . MoreMagic ;
MakeMagicC . Magic −> DemoP . Magic ;}
DemoC
Boot
DemoP
Magic
MakeMagicC
MoreMagic
Magic
Martin Perner TinyOS Part 2 May 22, 2017 8
Example Configuration
Configuration
c o n f i g u r a t i o n DemoC{
us e s i n t e r f a c e Boot ;p r o v i d e s i n t e r f a c e MoreMagic ;
}
imp l ementa t i on{
components DemoP , MakeMagicC ;
Boot = DemoP . Boot ;MoreMagic = MakeMagicC . MoreMagic ;
MakeMagicC . Magic −> DemoP . Magic ;}
DemoC
Boot
MoreMagic
DemoP
MakeMagicC
Boot
MoreMagic
Martin Perner TinyOS Part 2 May 22, 2017 8
Example Module
Modules – Where code is placed
module DemoP{
us e s i n t e r f a c e Boot ;p r o v i d e s i n t e r f a c e Magic ;
}
imp l ementa t i on{
even t vo id Boot . booted ( ) {. . .
}
command i n t Magic . ge t ( ) {. . .
}}
DemoP
Boot
Magic
Martin Perner TinyOS Part 2 May 22, 2017 9
Function Examples
Required by Interface
Command function:
( async ) command u i n t 8 t f ( u i n t 8 t x ) ;y = c a l l f ( x ) ;
Event function:
( async ) even t vo i d am ready ( u i n t 8 t x ) ;s i g n a l am ready ( x ) ;
To be used inside a module
Task:
t a s k vo i d f ( ) ;pos t f ( ) ;
Plain function:
u i n t 8 t f ( u i n t 8 t x ) ;y = f ( x ) ;
Martin Perner TinyOS Part 2 May 22, 2017 10
Split-Phase
Classic Approach
f(x)
call f(x) return; y = f(x)
f(x) access some hardware, and has to wait for a signal by the hardware.After calling f(x) the exeuction blocks until completion (busy waiting . . . )
Martin Perner TinyOS Part 2 May 22, 2017 11
Split-Phase
The Split-Phase Approach
start f(x) y = f(x) is done
call f(x) signals fdone(y)return
After calling f(x), the execution is started in the background. The caller receives a callback(event) upon completion of f(x).
Martin Perner TinyOS Part 2 May 22, 2017 12
Deferred Task Execution
Function call
f(x)
g(z)
cont. f(x)
call f(x)
signal/call g(z)
etc.
Assume that the return value and the side-effects of g(·) are not required by f(·). Why shouldwe wait?
Martin Perner TinyOS Part 2 May 22, 2017 13
Deferred Task Execution
Post a Task
f(x)
g()
call f(x)
post g()
Task have no parameters.Parameter passing needs to be done with state-variables in the module.
A task can only be posted once onto the tasklist.
Martin Perner TinyOS Part 2 May 22, 2017 14
Booting
How is TinyOS booted?
We have seen the interface Boot of MainC being used for initialization.
It provides an event booted, which is called after start-up of the system.
Martin Perner TinyOS Part 2 May 22, 2017 15
Booting
tos/system/MainC.nc
#i n c l u d e ” hardware . h”
c o n f i g u r a t i o n MainC {p r o v i d e s i n t e r f a c e Boot ;u s e s i n t e r f a c e I n i t as S o f t w a r e I n i t ;
}
imp l ementa t i on {components PlatformC , RealMainP , T inySchedu le rC ;
RealMainP . Schedu l e r −> TinySchedu le rC ;RealMainP . P l a t f o rm I n i t −> Plat formC ;
// Export the S o f t w a r e I n i t and Booted f o r a p p l i c a t i o n sS o f t w a r e I n i t = RealMainP . S o f t w a r e I n i t ;Boot = RealMainP ;
}
Martin Perner TinyOS Part 2 May 22, 2017 16
Booting
tos/system/RealMainP.nc
module RealMainP @safe() {provides interface Boot;uses interface Scheduler;uses interface Init as PlatformInit;uses interface Init as SoftwareInit;
}
implementation {int main() @C() @spontaneous () {
atomic {platform_bootstrap ();call Scheduler.init ();call PlatformInit.init ();while(call Scheduler.runNextTask ());call SoftwareInit.init ();while(call Scheduler.runNextTask ());
}__nesc_enable_interrupt ();signal Boot.booted ();call Scheduler.taskLoop ();return -1;
}default command error_t PlatformInit.init() { return SUCCESS; }default command error_t SoftwareInit.init() { return SUCCESS; }default event void Boot.booted (){}
}
Martin Perner TinyOS Part 2 May 22, 2017 17
How many instances of a Component are there?
Do we care?
If we need some boot-up initialization, we use MainC and the Boot interface
Do we get a new component every time we use it?
No, components are “singletons” (there is only one)
What can we do if we want two instances of a stateful component? (e.g., Queue)
Generic Components
Add generic in front of signature of configuration/module
Instantiate with new keyword
We can pass parameters, and even types, at instantiation.
Martin Perner TinyOS Part 2 May 22, 2017 18
Generic Components – Examples
QueueC.nc
g e n e r i c module QueueC ( typede f queue t , u i n t 8 t queueS i z e ) {p r o v i d e s i n t e r f a c e Queue<queue t >;
}. . .
SomeThing
g e n e r i c c o n f i g u r a t i o n SomeThing ( ) {. . .
}
imp l ementa t i on {components new QueueC ( u i n t 8 t , 5) as Queue ;. . .
}
Martin Perner TinyOS Part 2 May 22, 2017 19
Generic Component
Limitation
Contrary to, e.g., C++, the type checking happens on declaration
At this point, the used type is unknown
Does x+ 1 compile for very type used for x?
The attribute @integer() can be applied to the declaration for some type assumptions.
WeirdC
g e n e r i c module WeirdC ( typede f f o o t @ i n t e g e r ( ) ) {. . .
}
Martin Perner TinyOS Part 2 May 22, 2017 20
Abstract Data Type (ADT)
Does a type argument to a component helps?
How can we use it in an interface?
Use a typed interface!
QueueC.nc
i n t e r f a c e Queue<t> {. . .command t head ( ) ;. . .
}
Martin Perner TinyOS Part 2 May 22, 2017 21
Recap – Fan-In and Fan-Out
What happens if an interface is connected to multiple component
If there are multiple modules connected to the same interface, then
All connected providers of a command receive the call.All connected users of an event are signaled.The order is not defined!Generally, there is no possibility to determine whose signal caused an event.
The last item can be circumvented by using parameterized interfaces.
Martin Perner TinyOS Part 2 May 22, 2017 22
Parameterized Interfaces
Adding caller/callee information to an interface
Dirty hack: Additional parameter in command/event plus generic component to pass theparameter.
Better: use parameterized interfaces
Adds “implicit” parameter to function call.Interface definition does not need to be changeduse/provide clauses are extended.Parameters are assigned in configuration.
Martin Perner TinyOS Part 2 May 22, 2017 23
Parameterized Interface
Default Cases!
Implementationwise, parameterized interfaces are more or less a switch.
There is no compile-time check if every called parameter is wired (could be datadependent!)
The caller/callee must provide default implementations for parameterized calls.
Martin Perner TinyOS Part 2 May 22, 2017 24
Example Parameterized Interface 1
Demo Application
Count towards a generic value
Increment after a timer has fired
Output to a port interface
Martin Perner TinyOS Part 2 May 22, 2017 25
Example Parameterized Interface 1
CounterC
#inc l u d e ”Timer . h”g e n e r i c module CounterC ( u i n t 8 t top ) {
us e s i n t e r f a c e Boot ;u s e s i n t e r f a c e Timer<TMi l l i> as Timer ;u s e s i n t e r f a c e Port as Counte rPor t ;
}imp l ementa t i on {
u i n t 8 t coun t e r ;
t a s k vo id i n c r ement ( ) {coun t e r++;i f ( coun t e r > top ) {
coun t e r = 0 ;}c a l l Counte rPor t . s e t ( coun t e r ) ;
}even t vo id Boot . booted ( ) {
coun t e r = 0 ;c a l l Counte rPor t . makeOutput ( ) ;c a l l Timer . s t a r t P e r i o d i c ( 5 0 0 ) ;
}even t vo id Timer . f i r e d ( ) {
pos t i n c r ement ( ) ;}
}
Martin Perner TinyOS Part 2 May 22, 2017 26
Example Parameterized Interface 1 – Port
Port
i n t e r f a c e Port {command vo id makeOutput ( ) ;command vo id s e t ( u i n t 8 t ) ;
}
Martin Perner TinyOS Part 2 May 22, 2017 27
Example Parameterized Interface 1 – CounterAppC
CounterAppC
c o n f i g u r a t i o n CounterAppC {}
imp l ementa t i on {components MainC ;components new CounterC (6 ) as Counter ;components new RawPortC ( ( u i n t 8 t ) &PORTA, ( u i n t 8 t ) &DDRA) as PortA ;components new RawPortC ( ( u i n t 8 t ) &PORTB, ( u i n t 8 t ) &DDRB) as PortB ;components new T ime rM i l l i C ( ) as Timer ;
Counter . Boot −> MainC . Boot ;Counter . Timer −> Timer ;Counter . Counte rPor t −> PortA . Port [ 3 ] ;Counter . Counte rPor t −> PortB . Port [ 4 ] ;
}
Martin Perner TinyOS Part 2 May 22, 2017 28
Example Parameterized Interface 1 – RawPortC
RawPortC
g e n e r i c module RawPortC ( u i n t 8 t po r t add r , u i n t 8 t dd r add r ) {p r o v i d e s i n t e r f a c e Port [ u i n t 8 t i d ] ;
}
imp l ementa t i on {#de f i n e PORT (∗TCAST( v o l a t i l e u i n t 8 t ∗ ONE, po r t a dd r ) )#d e f i n e DDR (∗TCAST( v o l a t i l e u i n t 8 t ∗ ONE, dd r add r ) )
i n l i n e command vo id Port . makeOutput [ u i n t 8 t i d ] ( ) {DDR = 0 x f f ;}
i n l i n e command vo id Port . s e t [ u i n t 8 t i d ] ( u i n t 8 t v a l u e ) {i f ( i d != va l u e ) {PORT = va l u e ;}e l s e {
PORT = 0 x f f ;}
}}
Martin Perner TinyOS Part 2 May 22, 2017 29
Example Parameterized Interface 1 – Discussion
What have we achieved?
Caller still unaware of the callees, as before
Callees got a parameter passed. Not very impressive.
Generic Components are better fitted for this scenario!
Martin Perner TinyOS Part 2 May 22, 2017 30
Example Parameterized Interface 2
Weirder Demo Application
Count towards a generic value
Set current value to one port, on overflow set all ports to 0xff
selected.h
#i f n d e f SELECTED H#de f i n e SELECTED H
#de f i n e UNIQUE PORT ” un i q u e po r t ”
#end i f
Martin Perner TinyOS Part 2 May 22, 2017 31
Example Parameterized Interface 2
SelectedAppC
#inc l u d e ” s e l e c t e d . h”
c o n f i g u r a t i o n Se lectedAppC {}
imp l ementa t i on {components MainC ;components new CounterC (6 ) as Counter ;components new RawPortC ( ( u i n t 8 t ) &PORTA, ( u i n t 8 t ) &DDRA) as PortA ;components new RawPortC ( ( u i n t 8 t ) &PORTB, ( u i n t 8 t ) &DDRB) as PortB ;components new T ime rM i l l i C ( ) as Timer ;
Counter . Boot −> MainC . Boot ;Counter . Timer −> Timer ;Counter . Counte rPor t [ un ique (UNIQUE PORT ) ] −> PortA . Port ;Counter . Counte rPor t [ un ique (UNIQUE PORT ) ] −> PortB . Port ;
}
Martin Perner TinyOS Part 2 May 22, 2017 32
Example Parameterized Interface 2
CounterC
#inc l u d e ”Timer . h”#inc l u d e ” s e l e c t e d . h”
g e n e r i c module CounterC ( u i n t 8 t top ) {us e s i n t e r f a c e Boot ;u s e s i n t e r f a c e Timer<TMi l l i> as Timer ;u s e s i n t e r f a c e Port as Counte rPor t [ u i n t 8 t i d ] ;
}
imp l ementa t i on {u i n t 8 t counte r , i =0;
t a s k vo id i n c r ement ( ) {coun t e r++;i f ( coun t e r > top ) {
f o r ( i =0; i < uniqueCount (UNIQUE PORT ) ; i++) {c a l l Counte rPor t . s e t [ i ] ( 0 x f f ) ;
}coun t e r = 0 ;
}c a l l Counte rPor t . s e t [ c oun t e r ] ( coun t e r ) ;
}. . .
Martin Perner TinyOS Part 2 May 22, 2017 33
Example Parameterized Interface 2
CounterC cont.
. . .e v en t vo id Boot . booted ( ) {
coun t e r = 0 ;f o r ( i =0; i < uniqueCount (UNIQUE PORT ) ; i++) {
c a l l Counte rPor t . makeOutput [ i ] ( ) ;}c a l l Timer . s t a r t P e r i o d i c ( 5 0 0 ) ;
}
even t vo id Timer . f i r e d ( ) {pos t i n c r ement ( ) ;
}
d e f a u l t command vo id Counte rPor t . makeOutput [ u i n t 8 t i d ] ( ) {DDRF = 0xFF ;}
d e f a u l t command vo id Counte rPor t . s e t [ u i n t 8 t i d ] ( u i n t 8 t v a l u e ) {PINF = 0xFF ;
}}
Martin Perner TinyOS Part 2 May 22, 2017 34
Example Parameterized Interface 2 – Discussion
Interface Port and module RawPortC as before.
What have we achieved?
As the top-value of the counter is larger than 2, PORTF is toggled.
Caller is aware of the callees.
Caller needs to provide default implementation to prevent out-of-bound behavior.
Callees unaware of the caller.
Martin Perner TinyOS Part 2 May 22, 2017 35
Unique
Why are we using unique?
Numbers to parameterized interface need to be unique.
Counting per hand is hard, ugly, and a path to hell . . .
If we need to pass the number of attached interfaces, we would need to pass a parameterto the component. Instead we can use uniqueCount.
There are cases we non-consecutive numbering for the parameterized interface is used,e.g., port numbers.
Requirements
Counting happens based on a unique string (use a define in a header!)
unique returns a unique id. Numeric from 0 to n− 1
uniqueCount returns n
Martin Perner TinyOS Part 2 May 22, 2017 36
Parameterized Interface at caller and callee
What needs to be changed?
Add parameter to both sides in wiring.
Add parameter to interface declaration.
Add parameter at interface function declaration and usage.
Note: if the same value, generated by unique, is used multiple times: use an enum!
. . .enum {
COUNTER PORT1 = un ique (UNIQUE PORT)} ;Counter . Counte rPor t [COUNTER PORT1] −> PortA . Port [COUNTER PORT1 ] ;. . .
Martin Perner TinyOS Part 2 May 22, 2017 37
Execution Model
The Execution Model of TinyOS
TinyOS has two basic execution modes:
synchronous
asynchronous
Martin Perner TinyOS Part 2 May 22, 2017 38
Execution Model
Tasks in TinyOS
Every synchronous execution in TinyOS is a task.
As there is no preemptive scheduler (per-default), a task runs until it is finished.
This is problematic for long running computations ⇒ defer computation by postinganother task.
Can be interrupted by asynchronous event: interrupt.
Interrupts
Interrupts are handled in TinyOS as asynchronous executions.
As usual, they can happen at any time, given interrupts are enabled.
Do the usual synchronization problems also arise?
Martin Perner TinyOS Part 2 May 22, 2017 39
Execution Model
Mixing Asynchronous/Synchronous Executions
TinyOS has checks to prevent obvious mistakes, but the programmer still has to take care.
Variables used in asynchronous context must be accessed in atomic sections.
Functions that can be called from asynchronous contexts must be declared async.
To get from asynchronous to synchronous execution a task has to be posted.
Martin Perner TinyOS Part 2 May 22, 2017 40
Default Task Scheduling Policy
Non-Preemptive FIFO
Small, Easy, Fast
Every task is posted into the task queue
Queue is processed in FIFO ordering
Every task can only be posted once
Every task consumes only 1 byte in the task queue
Limited to 255 tasks
Task queue length is evaluated at compile time
Every task runs until completion
Dispatch long operations in multiple separate tasks
What about context switches?
Martin Perner TinyOS Part 2 May 22, 2017 41
Concurrency
Execution model in nesC is “run-to-completion” tasks
No preemptionAtomic with respect to other tasksNot atomic with respect to interrupt handlers
Code divided into two parts:
Synchronous Code: functions, commands, events, tasks that are only reachable from tasksAsynchronous Code: used in interrupt handlers (must be marked async)
Race conditions:
No race conditions between tasksAvoid race conditions by protection through an atomic statementCalls to functions are only protected if every call is protectedCompiler detects race conditions
Martin Perner TinyOS Part 2 May 22, 2017 42
Tasks in TinyOS 2.x
How to use a task
command vo id t h i n g y ( ) {. . .po s t p roce s sTask ( ) ;. . .
}
. . .
t a s k vo id p roce s sTask ( ) {//do work. . .i f ( moreToProcess ) {
pos t p roce s sTask ( ) ;}
}
The post will only fail iff the task is already posted in task queue and its execution has notstarted yet.
Martin Perner TinyOS Part 2 May 22, 2017 43
Task Example
Blink with Tasks
module Bl inkTaskC{
. . .}
imp l ementa t i on{
t a s k vo id t o g g l e ( ) {c a l l Leds . l ed0Togg l e ( ) ;
}even t vo id Boot . booted ( ) {
c a l l Timer0 . s t a r t P e r i o d i c ( 1 000 ) ;}even t vo id Timer0 . f i r e d ( ) {
pos t t o g g l e ( ) ;}
}
Martin Perner TinyOS Part 2 May 22, 2017 44
Splitting Computation via Tasks
Break-up long running computations for reduced latency
Instead oft a s k vo id computeTask (){
u i n t 3 2 t i ;f o r ( i =0; i <400001; i++){. . . .}
}
Try
t a s k vo id computeTask (){s t a t i c u i n t 3 2 t i ;u i n t 3 2 t s t a r t=i ;f o r ( ; i<s t a r t +10000 && i <400001; i++){
. . .}i f ( i >=400000) {
i =0;} e l s e {
pos t computeTask ( ) ;}
}
Martin Perner TinyOS Part 2 May 22, 2017 45
What Really Happens With Tasks
The Foundation in the Scheduler
command vo id Schedu l e r . i n i t ( ){
atomic {memset ( ( vo id ∗)m next , NO TASK, s i z e o f ( m next ) ) ;m head = NO TASK;m t a i l = NO TASK;
}}
command vo id Schedu l e r . taskLoop ( ){
f o r ( ; ; ) {u i n t 8 t nextTask ;atomic {
wh i l e ( ( nextTask=popTask ( ) ) == NO TASK) {c a l l McuSleep . s l e e p ( ) ;
}}s i g n a l TaskBas ic . runTask [ nextTask ] ( ) ;
}}
We see that every synchronous execution in TinyOS is based on a task.
Martin Perner TinyOS Part 2 May 22, 2017 46
What Really Happens With Tasks
Data-Structure usage
async command e r r o r t TaskBas ic . postTask [ u i n t 8 t i d ] ( ){
atomic{ r e t u r n pushTask ( i d ) ? SUCCESS : EBUSY; }}
boo l pushTask ( u i n t 8 t i d ){i f ( ! i sWa i t i n g ( i d ) ) {
i f (m head==NO TASK) {m head=i d ;m t a i l=i d ;
}e l s e {
m next [ m t a i l ]= i d ;m t a i l=i d ;
}r e t u r n TRUE;
}e l s e {
r e t u r n FALSE ;}
}
Martin Perner TinyOS Part 2 May 22, 2017 47
Threads
Deprecated!
As there was no one willing to maintain threads, they have been deprecated in the currentTinyOS development version.
Thread Based Priority Queues using Preemptive Jobs
BiggerNot that easy“Slow”
Platform independent part:
Thread QueueThreadThread context
Platform dependent part:
the “real” context switching
Martin Perner TinyOS Part 2 May 22, 2017 48
Benefits of TinyOS
Benefits of TinyOS over plain C
Predefined modules (hardware drivers)
Inherent modularization
Generic modules
Tasks
Martin Perner TinyOS Part 2 May 22, 2017 49
Drawbacks of TinyOS
TinyOS Memory Requirements
ATmega1280 static memory:
Flash: 128 kB
EEPROM: 4 kB
RAM: 8 kB
Usage of the Blink demo :
1816 B Flash, relates to 1.8 kB or 1.4% (.text segment size)
51 B RAM, relates to 0.05 kB or 0.6% (.bss segment size)
This is bad for a simple blinking application, but good for an “operating system”.
Martin Perner TinyOS Part 2 May 22, 2017 50
Command/Event and the Stack
Be aware of recursive behavior!
A module that wants to quickly sample multiple values from a sensor:
even t vo id Read . readDone ( e r r o r t e r r , u i n t 1 6 t v a l ) {b u f f e r [ i nd e x ] = v a l ;i n d ex++;i f ( i nd ex < BUFFER SIZE ) {
c a l l Read . r ead ( ) ;}
}
The sensor module, for some reason, caches the read values!command e r r o r t Read . r ead ( ) {
s i g n a l Read . readDone (SUCCESS , s e n s o rVa l ) ;}
This results in rapid growth of stack!Therefore, it is dangerous to signal events from commands! Post a task.
Martin Perner TinyOS Part 2 May 22, 2017 51
Important Stuff
Consider the programming hints!
Use provided modules/configurations! (Crc, Queue, Pool(!), . . . )
Enjoy the benefits of the compostability: develop and test small units!
Martin Perner TinyOS Part 2 May 22, 2017 52
Questions?
Martin Perner TinyOS Part 2 May 22, 2017 53