TinyOS, An Embedded Operating System
TinyOS, An Embedded Operating System
durchgeführt von
i
Contents
1 Introduction 1
1.1 Motivation and Objectives . . . . . . . . . . . . . . . . . . . . . 1
1.2 Structure of the Thesis . . . . . . . . . . . . . . . . . . . . . . . 2
2 TinyOS 3
2.1 What is TinyOS . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 History of TinyOS . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3 Supported Platforms . . . . . . . . . . . . . . . . . . . . . . . . 4
2.4 TinyOS Hardware Abstraction . . . . . . . . . . . . . . . . . . . 5
2.5 TinyOS Internals . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.5.1 Basic Scheduler . . . . . . . . . . . . . . . . . . . . . . . 6
2.5.2 Microcontroller Power Management . . . . . . . . . . . . 6
2.5.3 Boot Sequence . . . . . . . . . . . . . . . . . . . . . . . 7
2.5.4 Ressource Arbitration . . . . . . . . . . . . . . . . . . . 8
3 nesC 11
3.1 Fundamental Programming Hints . . . . . . . . . . . . . . . . . 11
3.2 Namespace, Components, and Interfaces . . . . . . . . . . . . . 12
3.3 Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.4 Async Functions . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.5 Split-Phase Interfaces . . . . . . . . . . . . . . . . . . . . . . . . 16
3.6 Generic Components . . . . . . . . . . . . . . . . . . . . . . . . 17
3.7 Parameterized Interfaces and Configurations . . . . . . . . . . . 18
3.8 Wiring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.8.1 Modules vs. Configurations . . . . . . . . . . . . . . . . 19
3.8.2 Wiring-Operators . . . . . . . . . . . . . . . . . . . . . . 19
4 MicroC/OS-II 22
4.1 Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.2 Differences TinyOS - MicroC/OS-II . . . . . . . . . . . . . . . . 23
4.2.1 Real-Time . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.2.2 Scheduler . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.2.3 Mutual Exclusion . . . . . . . . . . . . . . . . . . . . . . 24
4.2.4 Intertask Communication . . . . . . . . . . . . . . . . . 25
4.2.5 Task Synchronisation . . . . . . . . . . . . . . . . . . . . 25
4.2.6 Memory Footprint . . . . . . . . . . . . . . . . . . . . . 25
ii
5 bigAVR6 26
5.1 The Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
5.1.1 Onboard - Features . . . . . . . . . . . . . . . . . . . . . 26
5.1.2 Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . 26
5.2 Supported Modules . . . . . . . . . . . . . . . . . . . . . . . . . 27
5.2.1 Character LCD 2x16 . . . . . . . . . . . . . . . . . . . . 27
5.2.2 GLCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
5.2.3 Touch Screen . . . . . . . . . . . . . . . . . . . . . . . . 31
5.2.4 MMC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5.2.5 MP3 extension board . . . . . . . . . . . . . . . . . . . . 34
5.2.6 Ethernet board . . . . . . . . . . . . . . . . . . . . . . . 36
5.2.7 UART . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.2.8 RTC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5.2.9 Printf Library . . . . . . . . . . . . . . . . . . . . . . . . 43
5.3 Supported Microcontrollers . . . . . . . . . . . . . . . . . . . . . 44
5.3.1 ATmega128 . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.3.2 ATmega1280 . . . . . . . . . . . . . . . . . . . . . . . . 45
6 Resources used 46
Bibliography 47
A Setup Guide 48
A.0.3 Visualize Components . . . . . . . . . . . . . . . . . . . 49
B Pin Configuration of bigAVR6 50
iii
1 Introduction
This work is about the porting of TinyOS for the bigAVR6 platform for use
in the Microcontroller Lab Course at the Vienna University of Technology.
TinyOS is an open-source operating system, designed for use with wireless
embedded sensor networks. There are 2 major stable branches, v.1.x and v2.x,
which are not compatible to each other. TinyOS 2.x introduced some major
improvements, for example the task scheduler was completely redesigned. In
it’s new version, the whole project is now distributed under the new BSD license
too.
Because of TinyOS’s component-based architecture, a high-level programmer
does not have to rewrite all the used components from scratch, as long as the
necessary modules are already exisiting. So, implementing new applications or
changing exisiting ones is an easy and fast task. There are already existing
implementations for a range of popular hardware motes, as for example the
mica, iris and teleosa motes.
For developing applications in TinyOS, nesC is used. nesC stands for Net-
work Embedded Systems C, which is very similar to C/C++. Components in
nesC are related to objects in C++.
Embedded systems are designed for one or a few specific tasks, perhaps in
combination with realtime constraints. TinyOS was originally developed for
wireless, battery powered sensor networks, so one of the main requirements is
low power consumption to achieve high operation times – flexibility is not that
important.
This work captures topics from porting TinyOS to the bigAVR6 platform
as well as extending it by adding software-modules for high-level use of the
platform modules. It is also explained how to get a build environment running
from scratch for writing applications or extending the modules for an exisiting
platform.
1
1 Introduction 1.2 Structure of the Thesis
2
2 TinyOS
3
2 TinyOS 2.3 Supported Platforms
Over the next years, the ’rene’ and ’mica’ platforms were developed. In the
year 2002, work on the nesC programming language began. Until that, TinyOS
consisted of a mixture of C files and Perl scripts. In the same year, TinyOS
1.0, the first TinyOS implemented in nesC, was released.
Improvement of TinyOS 1.x went on until February 2006, when TinyOS 2.0
beta1 was released. Version 2.1 was finished in April 2007. Among numerous
bugfixes, a cc2420 wireless radio stack implementation was added in this release.
TinyOS 2.2 was released some months later, which included an cc2420 stack
reimplementation and bugfixes. After that, in August 2008, support for the
’iris’ and ’shimmer’ platforms was added by distribution of version 2.1.
At the time of this writing, the latest TinyOS version is 2.1.1, which was
released in April 2010. Most important add-ons were support for the ’mulle’,
’epic’ and ’shimmer2’ - platforms.
4
2 TinyOS 2.4 TinyOS Hardware Abstraction
5
2 TinyOS 2.5 TinyOS Internals
6
2 TinyOS 2.5 TinyOS Internals
As mentioned before, TinyOS enters a low power mode if the task queue is
empty. Normally, microcontrollers support a range of low power modes, for
example the ATmega128 supports up to 6 different power saving modes. To
decide what mode fits best, TinyOS examines the control- and statusregisters
to find the active components, and decides subsequently which power mode to
use.
For example, on an ATmega128-based asynchronous operated platform, the
cpu-specific powersaving-mode IDLE has to be choosen if one or more timer,
SPI, UART or I2C are in use. If the ADC-submodule is working, another mode,
ADC Noise Reduction, is entered. If none of this modules are active and the
task queue is empty, the cpu is set to POWER DOWN, from which it only can
resume by some external interrupts/resets or a SPI address match interrupt.
Because entering powersaving modes always comes with wakeup latency,
problems can arise if some higher-level hardware modules have timing con-
strains and the wakeup latency is too big. To solve this, the powersaving
mode found by examing the control- and statusregisters can be overridden
by a higher-level module. For example, when going to a sleepmode just be-
fore an alarm of a timer would occur, the wakeup latency could probably
cause a miss of this alarm. Therefore, a component can provide an inter-
face named McuPowerOverride featuring a command lowestState that, wired
against McuSleepC, will be called when a powersave mode is requested, and
can override the valid powersaving mode. The enabled powersaving mode is
the weakest one of all implementations of the interface.
7
2 TinyOS 2.5 TinyOS Internals
8
2 TinyOS 2.5 TinyOS Internals
An example for such a shared resource would be a bus, for example SPI as
shown in codelistings 2.1 and 2.2. This listings are part of an implementation
for sending and receiving IEEE8023 - frames with an 10MBit ENC28J60 chip.
A microcontroller can communicate with this chip by SPI. Given that at least
one other component could need independent access to SPI too, IEEE8023C re-
quests the bus whenever data has to be exchanged between the microcontroller
and the ethernet chip. Once the resource SPI is available, the arbiter signals
this to IEEE8023C, which has implemented the proper handler for this situ-
ation, named Resource.granted(). After this handler was called, IEEE8023C
is in full control of the SPI bus, regardless of other components that may be
using SPI too. After finishing it’s work, IEEE8023C MUST free the resource
by calling Resouce.release(). From this time on, other components can use the
resource.
Listing 2.1: IEEE8023P.nc
#i n c l u d e ” IEEE8023 . h”
module IEEE8023P
{
p r o v i d e s i n t e r f a c e IEEE8023 ;
u s e s i n t e r f a c e GeneralIO a s ssMMC ;
u s e s i n t e r f a c e GeneralIO a s ssETH ;
u s e s i n t e r f a c e GeneralIO a s rstETH ;
u s e s i n t e r f a c e HplAtm128Interrupt a s intETH ;
u s e s i n t e r f a c e SpiByte ;
uses i n t e r f a c e Resource ;
}
implementation
{
command u i n t 8 t IEEE8023 . i n i t ( )
{
/∗
. . . unimportant code i s not shown h e r e . . .
∗/
/∗
queue a r e q u e s t f o r t h i s r e s o u r c e now . . .
∗/
i f ( c a l l R e s o u r c e . r e q u e s t ( ) == FAIL )
{
r e t u r n FAIL ;
}
else
{
stateETH = IEEE8023 INITIALIZING ;
r e t u r n SUCCESS ;
}
}
/∗
e v e n t h a n d l e r w i l l be c a l l e d when r e q u e s t was queued and
r e s o u r c e becomes a v a i l a b l e
∗/
event void Resource . granted ( void )
9
2 TinyOS 2.5 TinyOS Internals
{
/∗
we a r e now i n f u l l c o n t r o l o f t h e r e s o u r c e
r e a d / w r i t e data t o r e s o u r c e
∗/
c a l l Resource . r e l e a s e ( ) ;
/∗
NO MORE a c c e s s t o t h e r e s o u r c e now
queue a n o t h e r r e q u e s t t o g e t i n c o n t r o l a g a i n
∗/
}
implementation
{
components IEEE8023P ;
components Atm128SpiC a s SPI ;
IEEE8023 = IEEE8023P ;
IEEE8023P . SpiByte −> SPI . SpiByte ;
IEEE8023P . R e s o u r c e −> SPI . R e s o u r c e [ 0 ] ;
/∗
unimportant components and w i r i n g not shown h e r e
∗/
10
3 nesC
11
3 nesC 3.2 Namespace, Components, and Interfaces
12
3 nesC 3.2 Namespace, Components, and Interfaces
The actual work is done in the module’s implementation. Keep in mind that
the module providing an interface MUST implement all of the commands of
the interface:
...
command e r r o r t Uart0TxControl . s t a r t ( ) {
SET BIT (UCSR0B, TXEN) ;
c a l l McuPowerState . update ( ) ;
return SUCCESS ;
}
command e r r o r t Uart0TxControl . s t o p ( ) {
CLR BIT (UCSR0B, TXEN) ;
c a l l McuPowerState . update ( ) ;
return SUCCESS ;
}
...
implementation {
13
3 nesC 3.2 Namespace, Components, and Interfaces
So, every higher-level component can switch on and off transmission on the
Uart0 interface, and the implementation also notifies the system that some
hardware was started or stopped, an information that is used by the power-
manangement system, as described earlier. Codelisting 3.1 demonstrates how
an application can make use of such an interface.
At first, we define what components we want to use, and how they are
put(wired ) together.
Listing 3.1: MyPowersavingAppC.nc
/∗ tab :4
Harald Glanzer , 0727156 TU Wien
c o n f i g u r a t i o n MyPowersavingAppC
{
}
implementation
{
components MainC ;
components Atm128Uart0C ;
components MyPowersavingC ;
/∗
w i r e our app t o t h e i n t e r f a c e ’ Boot ’
t h i s i n t e r f a c e i s p r o v i d e d by component ’MainC ’
∗/
MyPowersavingC −> MainC . Boot ;
/∗
w i r e our app t o t h e i n t e r f a c e ’ S t d C o n t r o l ’
t h i s i n t e r f a c e i s p r o v i d e d by component ’ Atm128Uart0C ’
∗/
MyPowersavingC −> Atm128Uart0C . S t d C o n t r o l ;
}
After that, we can use the interfaces provided by the used components. See
listing 3.2 for how that works.
Listing 3.2: MyPowersavingC.nc
/∗
14
3 nesC 3.3 Tasks
i n t e r f a c e ’ Boot ’ p r o v i d e s t h e e v e n t ’ b o o t e t ’ t o us ,
which MUST BE implemented by t h e u s e r o f ’ Boot ’
A d d i t i o n a l l y , we a r e u s i n g t h e g e n e r i c i n t e r f a c e S t d C o n t r o l
t h i s i n t e r f a c e i s p r o v i d e d by v a r i o u s components − t h i s app
u s e s t h e i n t e r f a c e p r o v i d e d by ’ Atm128Uart0C ’ , so we can
e n a b l e / d i s a b l e TX f o r UART0
module MyPowersavingC @ s a f e ( )
{
u s e s i n t e r f a c e Boot ;
uses i n t e r f a c e StdControl ;
}
implementation
{
/∗
when s ys t e m has ’ b o o t e t ’ up , we w i l l r e c e i v e t h i s e v e n t and
can t a k e o v e r from h e r e . . .
∗/
e v e n t void Boot . bo ot ed ( )
{
c a l l StdControl . s t a r t ( ) ;
}
}
3.3 Tasks
In TinyOS, a module can post a task to the scheduler, which will get executed
at some point later. Because a task is a deferred procedure call, there is no
return value. Additionally, there are no parameters for tasks, though it is
possible to write an own implementation of the task interface. A declaration
of a task has this form:
t a s k void c h e c k I n t e r r u p t f l a g ( ) ;
Tasks are non-preemptive, in other words, no task will ever get interrupted
by the TinyOS scheduler. The advantage is that the programmer never has to
worry about tasks corrupting each other’s data. On the other hand, tasks never
should be too long because otherwise other tasks maybe could get delayed. So,
a task that has to do long computations should be broken into multiple tasks.
15
3 nesC 3.4 Async Functions
16
3 nesC 3.6 Generic Components
17
3 nesC 3.7 Parameterized Interfaces and Configurations
...
B i t s 1 = BV1 ;
B i t s 2 = BV2 ;
B i t s 3 = BV3 ;
}
Listing 3.4 generates 3 instances of BitVectorC, where BV3 is set to the value
of max bits which is defined at the instantiation of the configuration.
Without generic components it would be necessary to write different modules
for all the max bits values.
but this would mean unnecessary code repeation and also force the caller to
pass the argument as a run-time parameter.
Parameterized interfaces are in essence an array of interfaces and look as
followed:
i n t e r f a c e UdpReceive {
e v e n t void r e c e i v e d ( i n a d d r t ∗ s r c I p , u i n t 1 6 t s r c P o r t ,
u i n t 8 t ∗ data , u i n t 1 6 t l e n ) ;
}
module UdpTransceiverP {
<... >
p r o v i d e s i n t e r f a c e UdpReceive [ u i n t 1 6 t p o r t ] ;
<... >
}
implementation {
<... >
default e v e n t void UdpReceive . r e c e i v e d [ u i n t 1 6 t p o r t ] ( i n a d d r t ∗ s r c I p ,
u i n t 1 6 t s r c P o r t , u i n t 8 t ∗ data , u i n t 1 6 t l e n ) {
<... >
}
<... >
}
18
3 nesC 3.8 Wiring
3.8 Wiring
As said before, in nesC a component can only call functions and access variables
whithin its local namespace. To call functions outside it’s scope, a set of names
in one component, generally an interface, must be mapped to a set of names
in another component. This operation is called wiring.
3.8.2 Wiring-Operators
There are 3 operators for wiring components together:
• <-
• ->
• =
The first two operators are interchangeable, for example this two lines are
identical:
MyComponent . U s e d I n t e r f a c e −> OtherComponent . P r o v i d e d I n t e r f a c e ;
OtherComponent . P r o v i d e d I n t e r f a c e <− MyComponent . U s e d I n t e r f a c e ;
In short, the arrow always points from the user of an interface to the provider
of that interface:
User −> P r o v i d e r ;
19
3 nesC 3.8 Wiring
To implement the handler for the events that can be signaled by Provided-
Interface, a construct of this form in UsedInterface is neccessary:
e v e n t <r e t u r n t y p e > U s e d I n t e r f a c e . EventName(< a r g u m e n t l i s t >)
{
/∗
code t o h a n d l e t h e new s i t u a t i o n , as s i g n a l l e d by t h i s e v e n t
∗/
}
The third operator ’=’ exports an interface. It defines how the configuration
of an interface is implemented, by delegating it to another component. In
contrast, the ’arrow’ - operator combines components that already exist.
Listing 3.5: GlcdC.nc
/∗ ∗
∗ High l e v e l i m p l e m e n t a t i o n f o r KS0108 Glcd
∗ @author : Markus Hartmann e988811@student . t u w i e n . ac . a t
∗ @date : 01.02.2012
∗/
c o n f i g u r a t i o n GlcdC
{
p r o v i d e s i n t e r f a c e Glcd ;
}
implementation
{
components MainC ;
components GlcdP ;
components HplKS0108C ;
The difference is explained on the basis of codelisting 3.5, the top-level con-
figuration for a component that provides functionality for a graphical display.
This component provides the interface Glcd which can be used by a high-level
programmer to easily use such a display. GlcdC consists of the private com-
ponent GlcdP and uses the interface HPL provided by HplKS0108C and Init
provided by MainC. Glcd is an interface of the configuration itself, implemented
in the component GlcdP and mapped to by using “=”. The interface Glcd gets
exported by the configuration so that other, higher-level components can use
this interface by specifying that component GlcdC with interface Glcd is used.
Opposite to that, component HplKS0108C is used “inside” to get the work
done (hidden from the user of GlcdC, no functionality is exported to a higher
20
3 nesC 3.8 Wiring
level). GlcdC wires itself to the SoftwareInit interface from MainC, which calles
the init() function after startup.
21
4 MicroC/OS-II
To emphasize the characteristics of TinyOS, another OS called OS-II is pre-
sented. The MicroC kernel was developed by Jean J. Labrosse.
4.1 Basics
MicroC/OS-II is a portable, ROMable, scalable preemptive real-time multitask-
ing kernel, written in ANSI-C. Small portions of the sourcecode are written in
assembler to adapt to different processor architectures. MicroC/OS-II is based
on MicroC/OS, also called The Real Time Kernel, which was published in 1992.
MicroC/OS v1.11 is compatible to its successor.
MicroC/OS-II is used in all kinds of embedded systems, ranging from engine
controls to audio equiment.
Important characteristics of this real-time multitasking OS are:
• Scaleable, with a minimum RAM footprint of 6KByte
• Maximum RAM footprint 24KByte
• Preemptive scheduler
• 10 Kernel services
• 80 System calls
• Support for semaphores
• Support for event flags
• Support for message queues
• Support for message mailboxes
• Up to 250 application tasks
• Constant / deterministic execution time for most services provided
• Support for large number of processor architectures
• Supported processors range from 8bit to 64bit architectures
• Supports multi-threaded applications
22
4 MicroC/OS-II 4.2 Differences TinyOS - MicroC/OS-II
4.2.1 Real-Time
A real-time system is a system where not only the correctness of a calculation is
important, but also the instant when this calculation was finished. The most
import features of a real-time kernel are minimal and predictable interrupt
latency and task switching latency.
While MicroC/OS-II supports a timely determinstic behaviour, no such as-
sertion can be given for TinyOS.
4.2.2 Scheduler
MicroC/OS-II has a preemptive scheduler – that means that every task gets
only a limited time for using the CPU. The time a task gets for execution also
depends on the task’s priority – all tasks MUST have different priorities –
because otherwise additional round-robin scheduling or similar would be nec-
essary to handle tasks with equal priority. More important tasks get higher
priority.
A task can be in 5 different states, as shown in figure 4.1:
23
4 MicroC/OS-II 4.2 Differences TinyOS - MicroC/OS-II
24
4 MicroC/OS-II 4.2 Differences TinyOS - MicroC/OS-II
25
5 bigAVR6
5.1 The Hardware
This development board, as shown in Figure 5.1, is produced by mikroElek-
tronika and supports 64- and 100-pin AVR TQFP packages.
5.1.2 Extensions
• 2x16 Character LCD, directly connectable via on-boad connectors
• 64x128 GLCD with touchscreen foil, directly connectable via on-boad
connectors
• IEEE802.3 extensionboard 10MBit
• SmartMP3 decoder board
• ...
26
5 bigAVR6 5.2 Supported Modules
The logic level of the following pins MUST NOT be touched by the pro-
grammer when using the LCD2x16:
27
5 bigAVR6 5.2 Supported Modules
i n t e r f a c e BufferedLcd {
/∗ ∗
∗ @param p e r i o d r e f r e s h p e r i o d i n ms , s e t t o 0 t o d i s a b l e a u t o r e f r e s h
∗/
command void a u t o R e f r e s h ( u i n t 3 2 t p e r i o d ) ;
command void c l e a r ( ) ;
command void w r i t e ( char ∗ s t r i n g ) ;
command void w r i t e P ( const char ∗ s t r i n g ) ;
command void goTo ( u i n t 8 t l i n e , u i n t 8 t c o l ) ;
command void f o r c e R e f r e s h ( ) ;
}
When examing schematic 5.2, one can see that there is a design flaw existing:
pin RW is bound to GND. Because of this (low=write operation), no read
operation is possible. Accordingly, it is not possible to read the corresponding
register to determine whether a write-operation has already finished. To handle
this problem and give the LCD controller enough time to process a write-
operation(needed for initializing, clearing the display and writing characters to
it), there are two options:
• use busywaiting - blocking
• use a timer - non-blocking
With the first solution - busy waiting - the time to wait can be minimized
to the absolutely necessary time, but obviously the time spent in the spinloop
is lost cpu time, which is bad.
The second solution - using the generic timer interface TimerMilliC - doesn’t
waste cpu time(apart from the extratime spent in the timer’s interrupt vector),
but problematic about this solution is that the existing timer-framework doesn’t
provide good granularity. The minimal periodic time that can be achieved
28
5 bigAVR6 5.2 Supported Modules
is about 20msec, which is hereby the waiting time for every character when
sending a string to the display. While this is not problematic when initializing
or clearing the display, a considerable delay is introduced when text is written
to the display.
The interface provided uses busy waiting to write a single character. To
minimize the time while refreshing the display, only changed lines are rewritten.
5.2.2 GLCD
The GLCD extension consists of a KS0108B GLCD dot matrix liquid crystal
graphic display with a resolution of 128 x 64 pixel. As the schematics show in
Figure 5.3, SW15/8 must be turned on to activate the GLCD-backlight, the
contrast can be changed with potentiometer P3.
The logic level of the following pins MUST NOT be touched by the pro-
grammer when using the GLCD and the touchscreen:
• PORT A: all ports reserved for GLCD
• PORT E: PE2, PE3, PE4, PE5, PE6, PE7 reserved for GLCD
• PORT F: PF0, PF1 reserved for touchscreen
• PORT G: PG3, PG4 reserved for touchscreen
29
5 bigAVR6 5.2 Supported Modules
for writing and drawing objects such as dots, rectangles and circles. GlcdC itself
is wired to HplKS0108C for low-level functions and to MainC.SoftwareInit. The
latter ensures that the hardware is initialized properly without any necessary
action on the users side.
Listing 5.2: Glcd.nc
/∗ ∗
∗ High l e v e l i n t e r f a c e f o r KS0108 GLCD D i s p l a y
∗ @author : Markus Hartmann e988811@student . t u w i e n . ac . a t
∗ @date : 01.02.2012
∗/
#include ”KS0108 . h”
i n t e r f a c e Glcd
{
/∗ ∗
∗ Set p i x e l
∗
∗ @param x−c o o r d i n a t e
∗ @param y−c o o r d i n a t e
∗
∗ @return SUCCESS
∗
∗/
command e r r o r t s e t P i x e l ( const u i n t 8 t x , const u i n t 8 t y ) ;
/∗ ∗
∗ Clear p i x e l
∗
∗ @param x−c o o r d i n a t e
∗ @param y−c o o r d i n a t e
∗
∗ @return SUCCESS
∗
∗/
command e r r o r t c l e a r P i x e l ( const u i n t 8 t x , const u i n t 8 t y ) ;
/∗ ∗
∗ Invert pixel
∗
∗ @param x−c o o r d i n a t e
∗ @param y−c o o r d i n a t e
∗
∗ @return SUCCESS
∗
∗/
command e r r o r t i n v e r t P i x e l ( const u i n t 8 t x , const u i n t 8 t y ) ;
/∗ ∗
∗ Draw l i n e
∗
∗ @param f i r s t p o i n t x
∗ @param f i r s t p o i n t y
∗ @param se c on d p o i n t x
∗ @param se c on d p o i n t y
∗
∗ @return SUCCESS
∗
∗/
30
5 bigAVR6 5.2 Supported Modules
/∗ ∗
∗ Draw r e c t a n g l e
∗
∗ @param upper l e f t x
∗ @param upper l e f t y
∗ @param l o w e r r i g h t x
∗ @param l o w e r r i g h t y
∗
∗ @return SUCCESS
∗
∗/
command e r r o r t drawRect ( const u i n t 8 t x1 , const u i n t 8 t y1 ,
const u i n t 8 t x2 , const u i n t 8 t y2 ) ;
/∗ ∗
∗ Draw e l l i p s e
∗
∗ @param c e n t e r x
∗ @param c e n t e r y
∗ @param r a d i u s h o r i z o n t a l
∗ @param r a d i u s v e r t i c a l
∗
∗ @return SUCCESS
∗
∗/
command e r r o r t d r a w E l l i p s e ( const u i n t 8 t x , const u i n t 8 t y ,
const u i n t 8 t r a d i u s h , const u i n t 8 t r a d i u s v ) ;
/∗ ∗
∗ F i l l Display with pattern
∗
∗ @param p a t t e r n
∗
∗ @return SUCCESS
∗
∗/
command e r r o r t f i l l ( u i n t 8 t p a t t e r n ) ;
/∗ ∗
∗ drawText
∗
∗ @param t e x t
∗ @param x−c o o r d i n a t e o f l o w e r l e f t e d g e
∗ @param y−c o o r d i n a t e o f l o w e r l e f t e d g e
∗
∗ @return SUCCESS
∗
∗/
command void drawText ( const char ∗ t e x t , const u i n t 8 t x , const u i n t 8 t y ) ;
31
5 bigAVR6 5.2 Supported Modules
#include ” TouchScreen . h”
i n t e r f a c e TouchScreen
{
/∗ ∗
∗
∗ @param x o f f s e t
∗ @param y o f f s e t
∗
∗ @return SUCCESS
∗/
command e r r o r t c a l i b r a t e ( i n t 8 t x o f f s e t , i n t 8 t y o f f s e t ) ;
/∗ ∗
∗
∗ @param p o i n t e r t o b u f f e r f o r c o o r d i n a t e s
∗
32
5 bigAVR6 5.2 Supported Modules
/∗ ∗
∗ N o t i f i c a t i o n t h a t c o o r d i n a t e s are ready
∗
∗/
e v e n t void c o o r d i n a t e s R e a d y ( void ) ;
}
5.2.4 MMC
A MMC/SD connector is available onboard so that memory cards can be
interfaced to the microcontroller via SPI. As shown in Figure 5.5, activate
SW15/3/4/5/6/7 to use it. Because the memory card is powered with 3.3V,
whereas the microcontroller needs 5V supply, a 74LVCC3245 bus transceiver
is used to obtain the needed voltage levels.
The logic level of the following pins MUST NOT be touched by the pro-
grammer when using the MMC:
• PORT B: PB1, PB2, PB3 reserved for MMC: SCK / MISO / MOSI
• PORT G: PG1, PG2 reserved for MMC: CS / CD
33
5 bigAVR6 5.2 Supported Modules
c a l l Sdcard . r e a d B l o c k ( blockAddr , ∗ b u f f e r ) ;
i n t e r f a c e Sdcard {
command e r r o r t i n i t ( ) ;
e v e n t void i n i t D o n e ( e r r o r t e r r o r ) ;
command e r r o r t r e a d B l o c k ( u i n t 3 2 t blockAddr , u i n t 8 t ∗ b u f f e r ) ;
e v e n t void readBlockDone ( u i n t 8 t ∗ b u f f e r , e r r o r t e r r o r ) ;
command b o o l i n s e r t e d ( ) ;
}
34
5 bigAVR6 5.2 Supported Modules
The board is connected via SPI, the maximum speed for reading registers is
2MHZ (sufficiently below CLKI6
= 4, 1M HZ according to manual), the max-
imum for sending data 4MHZ. The module is wired to SoftwareInit for ini-
tialization and provides high level functions with interface MP3 as shown in
Listing 5.5.
Listing 5.5: MP3.nc
/∗ ∗
∗ @author : Markus Hartmann <e9808811@student . t u w i e n . ac . at>
∗ @date : 31.07.2012
∗/
i n t e r f a c e MP3
{
/∗ ∗
∗ S t a r t and s t o p s i n e t e s t
∗
∗ @param on TRUE t o s t a r t − FALSE t o s t o p
∗
∗ @return SUCCESS i f command was s u c c e s s f u l l y s e n t o v e r SPI
∗/
command e r r o r t s i n e T e s t ( b o o l on ) ;
/∗ ∗
∗ S e t volume
∗
∗ @param volume Volume t o be s e t
∗
∗ @return SUCCESS i f command was s u c c e s s f u l l y s e n t o v e r SPI
∗/
command e r r o r t setVolume ( u i n t 8 t volume ) ;
/∗ ∗
∗ Send d a t a
∗
∗ @param d a t a A p o i n t t o a d a t a b u f f e r where t h e d a t a i s s t o r e d
∗ @param l e n Length o f t h e message t o be s e n t − d a t a must be a t l e a s t as l a r g e as l e n
∗
∗ @return SUCCESS i f r e q u e s t was g r a n t e d and s e n d i n g t h e d a t a s t a r t e d
∗/
command e r r o r t sendData ( u i n t 8 t ∗ data , u i n t 8 t l e n ) ;
/∗ ∗
∗ Check i f VS1011e i s r e a d y t o a c c e p t new d a t a
∗
∗ @return FALSE i f VS1011e i s b u s y or s e n d i n g o f d a t a i s i n p r o g r e s s − o t h e r w i s e TRUE
∗/
command b o o l i s B u s y ( void ) ;
/∗ ∗
∗ Read de c od e time
∗
∗ @param d a t a A p o i n t t o a d a t a b u f f e r where t h e d ec o de time w i l l be s t o r e d
∗
∗ @return SUCCESS i f command was s u c c e s s f u l l y s e n t o v e r SPI
∗/
command e r r o r t readTime ( u i n t 1 6 t ∗ time ) ;
35
5 bigAVR6 5.2 Supported Modules
/∗ ∗
∗ S e t d e co d e time
∗
∗ @param time The time t o s e t
∗
∗ @return SUCCESS i f command was s u c c e s s f u l l y s e n t o v e r SPI
∗/
command e r r o r t setTime ( u i n t 1 6 t time ) ;
}
This extension board, shown in Figure 5.7, can be used for sending and
receiving IEEE802.3 frames, and therefore embedding the development board
into a network. The board features an ethernet controller ENC28J60 that
exchanges data with a microcontroller via SPI. The board can be connected to
dsPIC, AVR-8051 and PIC by three 10-pin IDC connectors 1 . The board needs
3.3V voltage supply, but has a 74LVXc3245 bus transceiver chip for running
the board with 5V logic levels. Therefore, jumper J1 has to be set correctly.
A basic UDP/IP/ARP stack has been implemented, with the following lim-
itations:
• No UDP - level checksum
• No IP - level options
• No IP - level fragmentation
• ARP request/reply only
1
Because MikroElektronika did not manage to make the pin layout compatible with the
bigAVR6 board, it is necessary to use single pin connectors.
36
5 bigAVR6 5.2 Supported Modules
For using the extension board with the bigAVR6, the following requirements
have to be provided:
• Jumper J1 on the Ethernetboard must be set to 5V
• SPI-AVR-8051 VCC must be connected to 5V
• SPI-AVR-8051 GND must be connected to ground
• SPI-AVR-8051 CS must be connected to PORT B0
• SPI-AVR-8051 SCK must be connected to PORT B1
• SPI-AVR-8051 MOSI must be connected to PORT B2
• SPI-AVR-8051 MISO must be connected to PORT B3
• SPI-AVR-8051 RST must be connected to PORT B4
• SPI-AVR-8051 INT must be connected to PORT D0
Obviously, the state of this connected pins MUST NOT be touched by the
programmer.
IMPORTANT NOTE
RS-232 Port B CAN NOT BE USED together with this component
because Port D, which is used as the external interrupt source from the ether-
netboard, is also used as UART1(=RS-232 Port B) RX pin. Instead, RS-232
Port A MUST be used if the UDP-services are also needed.
Also, jumper J21 MUST BE set to onboard programmer for IEEE8023C
to function!
The Ethernet Board module Enc28j60C uses Interface Mac, which is pro-
vided by LlcTransceiverC and provides a control interface by itself. A complete
wiring example is shown in Listing 5.6 .
Listing 5.6: UdpAppC.nc
/∗ ∗
∗ @author : Andreas Hagmann <ahagmann@ecs . t u w i e n . ac . at>
∗ @date : 12.12.2011
∗/
#include ” debug . h”
#include ” u d p c o n f i g . h”
c o n f i g u r a t i o n UdpAppC {
implementation {
components MainC ;
components UdpDemoC ;
components new UdpC(UDP PORT ) ;
#i f n d e f WLAN
components Enc28j60C a s EthernetC ;
37
5 bigAVR6 5.2 Supported Modules
#e l s e
components Mrf24wC a s EthernetC ;
#endif
components new T i m e r M i l l i C ( ) a s Timer ;
components LlcTransceiverC ;
components BufferedLcdC a s LcdC ;
components IpTransceiverC ;
components StdoDebugC ;
components PingC ;
When the application wants to send data to or receive data from a remote
host, it requests hardware control by calling the start function of the Split
Control interface. After receiving the event
void s t a r t D o n e ( e r r o r t e r r o r )
Data can be sent and received by using component UdpC which provides
interface UdpSend and UdpReceive, shown in 5.7 and 5.8.
Listing 5.7: UdpSend.nc
/∗ ∗
∗ @author : Andreas Hagmann <ahagmann@ecs . t u w i e n . ac . at>
∗ @date : 12.12.2011
∗
∗ b a s e d on an i m p l e m e n t a t i o n o f Harald Glanzer , 0727156 TU Wien
∗/
#include ”udp . h”
i n t e r f a c e UdpSend {
command e r r o r t send ( i n a d d r t ∗ d s t I p , u i n t 1 6 t d s t P o r t , u i n t 8 t ∗ data , u i n t 1 6 t l e n ) ;
e v e n t void sendDone ( e r r o r t e r r o r ) ;
}
i n t e r f a c e UdpReceive {
e v e n t void r e c e i v e d ( i n a d d r t ∗ s r c I p , u i n t 1 6 t s r c P o r t , u i n t 8 t ∗ data , u i n t 1 6 t l e n ) ;
}
38
5 bigAVR6 5.2 Supported Modules
Afterwards, the data is handed down the stack, as shown in Figure 5.8.
At first, an UDP header is generated, and the payload, as assigned by the
application, is attached to it. As mentioned above, NO checksum is generated
at this level - if needed, a checksum must be calculated at application level.
This UDP packet(payload + UDP-header) is then handed to the next level,
the IP level.
At this level, a checksum is generated, which includes the IP-header only. In
the next step, a routing-decision has to be made: either the packet is addressed
to a host inside the Network (the remote host has the same network-adress than
the IP that has been assigned to the bigAVR6 board), or the packet must hop
outside. In the first case, the packet can be sent to the host directly, otherwise,
it must be sent to the default gateway, which can be assigned with the IpControl
interface provided by IpTransceiverC as seen in 5.9. Note the ’,’ instead of the
usual ’.’ between the numbers:
#d e f i n e GATEWAY 1 9 2 , 1 6 8 , 0 , 1
i n a d d r t cgw = { . b y t e s {GATEWAY} } ;
c a l l I p C o n t r o l . setGateway(&cgw ) ;
i n t e r f a c e IpControl {
command void s e t I p ( i n a d d r t ∗ i p ) ;
command void setGateway ( i n a d d r t ∗ gateway ) ;
command void setNetmask ( i n a d d r t ∗ netmask ) ;
command i n a d d r t ∗ g e t I p ( ) ;
command i n a d d r t ∗ getGateway ( ) ;
command i n a d d r t ∗ getNetmask ( ) ;
}
When the proper destination IP has been found, an ARP lookup is done in
a cache. If no ARP entry is found for the destionation IP, a lookup is sent
automatically. Be aware that, if no MAC is found, the ARP-request triggering
packet is lost and must be resent by the application. If the MAC is known, it is
extracted from the MAC cache, and component IEEE802.3 takes over control,
where the frameheader and the payload (data + udp-header + ip-header) is
copied into the transmit memory of the ENC28J60 by SPI. Afterwards, the
communication is started, and the completion is signaled to the application.
The MAC address is calculated out of TOS NODE ID and can be set during
installation with
make <p l a t f o r m > i n s t a l l ,< id >
39
5 bigAVR6 5.2 Supported Modules
Network Sniffing
For testing purposes, the command line tool netcat can be used. As example,
a constant string should be sent to the ip 192.168.1.100, destinationport 4443,
as shown in the following listing.
...
dstIP [ 0 ] = 192;
dstIP [ 1 ] = 168;
dstIP [ 2 ] = 1 ;
40
5 bigAVR6 5.2 Supported Modules
dstIP [ 3 ] = 100;
c a l l UDP. sendData ( ( u i n t 1 6 t ∗ ) ” h e l l o world ” , ( u i n t 8 t ∗ ) dstIP ,
8 0 , 4 4 4 3 , s i z e o f ( ” h e l l o world ” ) ) ;
...
To receive the string on the corresponding host, this command line can be
used:
nc −u − l 4443
This starts netcat in listening mode, specifies that UDP instead of TCP
should be used and that it should bind to port 4443. Port 4443 belongs to the
so-called unprivileged ports, where a ’normal’, unpriviliged user can bind to.
All ports greater thant 1023 belong to this group.
5.2.7 UART
There are 2 UART ports available onboard, RS-232 port A and port B. Compo-
nent PlatformSerialC is wired to port A and provides the following interfaces:
• StdControl to start/stop the Hardware
• UartControl to set speed and mode
• UartByte to send a single byte
• UartStream to send a String
To use the UartStream interface, receive interrupt must be enabled by hand.
A short example for wiring:
components P l a t f o r m S e r i a l C ;
components UartC ;
UartC . U a r t C o n t r o l −> P l a t f o r m S e r i a l C ;
UartC . UartStream −> P l a t f o r m S e r i a l C ;
c a l l UartStream . send ( ( u i n t 8 t ∗ ) ” H a l l o Du ! \ n” , 1 0 ) ;
c a l l UartStream . e n a b l e R e c e i v e I n t e r r u p t ( ) ;
c a l l UartStream . r e c e i v e ( r c v B u f f e r , s i z e o f ( r c v B u f f e r ) ) ;
41
5 bigAVR6 5.2 Supported Modules
5.2.8 RTC
The DS1307 Real Time Clock provides date and time with granulation of 1
second and an configureable square wave output. DS1307C provides interface
RTC as shown in 5.10 with functions to set the time, start/stop the clock and
configure the square wave output.
Listing 5.10: RTC.nc
/∗ ∗
∗ @author Markus Hartmann e988811@student . t u w i e n . ac . a t
∗/
#include ”RTC. h”
i n t e r f a c e RTC{
/∗ ∗
∗ S t a r t s the Realtime Clock
∗
∗ @param d a t a S t a r t s t h e Clock , s e t t i n g d a t e / time
∗ I f NULL i s p a s s e d , t h e c l o c k i s s t a r t e d w i t h o u t
∗ changing anything .
∗
42
5 bigAVR6 5.2 Supported Modules
/∗ ∗
∗ S t o p s t h e R e a l t i m e C l o c k − The s e c o n d s a r e s e t t o 0
∗
∗ @return SUCCESS i f b u s a v a i l a b l e and r e q u e s t a c c e p t e d .
∗/
command e r r o r t s t o p ( void ) ;
/∗ ∗
∗ Read time
∗
∗ @param d a t a A p o i n t t o a d a t a b u f f e r where t h e r e s u l t s w i l l be s t o r e d
∗
∗ @return SUCCESS i f b u s a v a i l a b l e and r e q u e s t a c c e p t e d .
∗/
command e r r o r t readTime ( r t c t i m e t ∗ data ) ;
/∗ ∗
∗ N o t i f i c a t i o n t h a t the r e s u l t s are ready
∗
∗/
e v e n t void timeReady ( void ) ;
/∗ ∗
∗ C o n t r o l t h e Squarewave o u t p u t
∗
∗ @param s q u a r e C o n f i g Output f r e q u e n c y o f t h e s q u a r e w a v e g e n e r a t o r o f t h e r t c :
∗ RTC SQW OFF, − D i s a b l e squarewave output
∗ RTC SQW 1HZ, − E n a b l e s 1Hz s q u a r e w a v e o u t p u t
∗ RTC SQW 4KHZ, − E n a b l e s 4kHz o u t p u t
∗ RTC SQW 8KHZ, − E n a b l e s 8kHz o u t p u t
∗ RTC SQW 32KHZ − E n a b l e s 32 kHz o u t p u t
∗
∗ @return SUCCESS i f b u s a v a i l a b l e and r e q u e s t a c c e p t e d .
∗/
command e r r o r t setSquareWave ( r t c s q w t s q u a r e C o n f i g ) ;
}
43
5 bigAVR6 5.3 Supported Microcontrollers
5.3.1 ATmega128
The ATmega128 Microcontroller is supported natively by TinyOS. However,
there is one necessary change to operate it with the bigAVR6 platform:
The original implementation was operated with an asynchronus timer sys-
tem driven by the clock output of the (ZigBee) wireless transceiver. As the
44
5 bigAVR6 5.3 Supported Microcontrollers
IMPORTANT NOTE:
It is possible to use a wrong value for MHZ - for example 8 when operating
with 16 MHz. The correctness of this value can not checked and may lead
to wrong baudrate calculation, incorrect timer signals and other undefined
behavior.
5.3.2 ATmega1280
The ATmega1280 is not supported by the original TinyOS, but is largely
identical with the supported ATmega1281. The same changes regarding asyn-
chronus/synchronus operation had to be made as within the ATmega128.
In addition it was necessary to change the HplAtm1280GeneralIOSlowPinP
as the ATmega1280 supports more pins and needs 16Bit Addresses to access
its Ports.
45
6 Resources used
• http://www.youtube.com/watch?v=j6hRsue5b30 / lecture about tinyos
• http://www.tinyos.net/tinyos-2.x/doc/html/tep2.html
• http://www.tinyos.net/tinyos-2.x/doc/html/tep106.html
• http://www.tinyos.net/tinyos-2.x/doc/html/tep108.html
• http://www.tinyos.net/tinyos-2.x/doc/html/tep112.html
• http://www.tinyos.net/tinyos-2.x/doc/pdf/tinyos-programming.pdf
46
Bibliography
[Lev] Philip Levis. TinyOS Programming. Treitlstr. 3/3/182-1, 1040 Vienna,
Austria. Available at http://www.tinyos.net/tinyos-2.x/doc/pdf/
tinyos-programming.pdf.
[LS] Philip Levis and Cory Sharp. Scheduler and Tasks. Treitlstr. 3/3/182-
1, 1040 Vienna, Austria. Available at http://www.tinyos.net/
tinyos-2.x/doc/html/tep106.html.
[Mika] MikroElektronika. BIGAVR6 User Manual. MikroElektronika. Avail-
able at http://www.mikroe.com/eng/downloads/get/352/bigavr6_
manual_v100.pdf”.
[Mikb] MikroElektronika. MikroElektronika Homepage. MikroElektron-
ika. Available at http://www.mikroe.com/eng/products/view/165/
smartmp3-board/”.
[Vie] ECS TU Vienna. Getting Started Guide. ECS TU Vienna. Available at
http://ti.tuwien.ac.at/ecs/teaching/courses/mclu/manuals/
getting-started-guide/at_download/file”.
47
A Setup Guide
It is assumed that avr-gcc and avrprog2 are already installed and working. The
following setup guide is from [Vie]
If not already installed, you have to install git by executing
Download the according binary packages of the nesC compiler and some
tool available from the course homepage http://ti.tuwien.ac.at/ecs/
teaching/courses/mclu/misc/tinyos-packages. For the correct path ask
your adviser of the course. If you don’t know if you need the 32 bit or 64 bit
packages find it out by
uname -m
48
A Setup Guide
Syntax highlighting
Here you can find a TinyOS syntax highlighting file for ”gedit”: http://www.
keally.org/2009/02/20/tinyos-and-nesc-syntax-highlighting/
Envoironment variables
Enter in a terminal:
echo "export TOSROOT=/home/user/TOS_ECS" >> ~/.profile
49
B Pin Configuration of bigAVR6
PORTA
A0 A1
A2 A3 LCD128x64
LCD128x64 A4 A5 LCD128x64
LCD128x64 A6 A7 LCD128x64
PORTB
DS1820 B0 B1 SPI SCK
SPI MOSI B2 B3 SPI MISO
B4 B5
B6 B7
PORTC
C0 C1
LCD2x16 C2 C3 LCD2x16
LCD2x16 C4 C5 LCD2x16
LCD2x16 C6 C7 LCD2x16
PORTD
RTC EEPROM D0 D1 EEPROM RTC
RS-232B D2 D3 RS-232B RTC
D4 D5 CAN
CAN D6 D7
PORTE
RS-232A E0 E1 RS-232A
LCD128x64 E2 E3 LCD128x64
EEPROM RTC LCD128x64 E4 E5 LCD128x64 RTC EEPROM
RTC LCD128x64 E6 E7 LCD128x64
PORTF
Touch Panel F0 F1 Touch Panel
F2 F3
F4 F5
F6 F7
50
B Pin Configuration of bigAVR6
PORTG
DS1820 G0 G1 MMC CS
MMC CD G2 G3 Touch Panel
Touch Panel G4 G5
G6 G7
51