EM2013SSP06

Aus Verteilte Systeme - Wiki
Wechseln zu: Navigation, Suche

Der Kaffeevollatomat AEG CF220 soll um eine aktive Steuerung erweitert werden. <br\> Die Ausarbeitung zeigt, wie erster Schritt, die Beobachtung der Kaffeemaschine, realisiert wird. Dazu wird ein Webserver auf einem Mikrocontroller-Board mit Contiki OS implementiert, der HTTP-Anfragen bearbeitet und den Status der Kaffeemaschine dynamisch generiert und als Antwort zurücksendet. Da das verwendete Mikrocontroller-Board ein Funkmodul besitzt, wird Funkübertragung zwischen Mikrocontroller-Board und Rechner verwendet.<br\> In erster Teil der Ausarbeitung wird das Betriebssystem Contiki beschrieben. Dabei werden die wichtigen Eigenschaften und Merkmale des System erläutert. Als nächstes wird existierende Verdrahtung der Kaffeemaschine analysiert und der Design für die Lösung der Anforderungen vorgestellt. Zum Schluss wird auf die Implementierung eingegangen und ein Ausblick auf weitere Erweiterungsmöglichkeiten gegeben.

Contiki OS

Contiki ist ein Open Source Betriebssysteme für die Eingebettete Systeme und Systeme, die nur wenige Ressourcen zur Verfügung haben und gewöhnlich mit einem Netzwerk verbunden sind. In vielen Konfigurationen verbraucht das System nur 2 Kilobytes RAM und 40 Kilobytes ROM [1]. Contiki wurde von Swedish Institute for Computer Science (SICS) unter der Leitung von Adam Dunkels entwickelt und erschien in Jahr 2003 in Version 1.0. In aktueller Version(2.6) werden 36 Plattformen, darunter Atmel AVR und Texas Instruments, unterstützt. Als Programmiersprache wurde C verwendet.

Systemübersicht

Beim Kompilieren des Systems, wird dieses auf Core und Loaded Program aufgeteilt. Core wird als eine einzelne binary Datei erstellt und kann nicht mehr verändert werden. Es beinhaltet den System Kernel, Program Loader, mit dessen Hilfe Loaded Program ins das System geladen werden, Language run-rime und Communication Service [2].

Prozesse

Contiki ist eine ereignisbasierte System. Ein Prozesse wird ausgeführt, wenn ein Ereignis auftritt, das durch einen Interrupt, Timer oder anderen Prozess ausgelöst wird. Beim starten eines Prozesses, wird der sequenziell bis zum Fertigstellen abgearbeitet und kann nicht durch einen anderen Prozess (non preemptive oder kooperativ) aber durch einen Interrupt oder Real-time Timer (preemptive) unterbrochen werden. Die zugeteilte CPU wird nur dann an einen anderen Prozess abgegeben, wenn der ausgeführte Prozess fertig ist, auf ein Ereignis wartet oder anderen Prozess zur Ausführung frei gibt (PT_YIELD()) [3]. Kommunikation zwischen Prozessen geschieht immer durch den Kernel [2].<br\> Ein Prozess in Contiki ist eine die Anwendungsprogramm oder Service (eine Funktion, die von mehreren Prozessen benutzt werden kann). Prozesse werden bei booten gestartet, können aber auch dynamisch zur Laufzeit geladen oder entfernt werden [2] und bestehen aus Process Control Block und Process Thread [3]. Process Control Block wird in RAM abgespeichert und erhält Run-Time Informationen über ein Prozess wie Zeiger auf nächste Process Control Block in einer Liste aktiver Prozesse (next), Textuelle Name (name), Funktionszeiger auf Process Thread (thread), Protothread Status (pt) und interne Flags für den Zustand des Prozesses (state und needspoll). <br\> Process Control Block wird nur intern von Kernel benutzt und über Macro PROCESS() deklariert [3]. Process Thread wird in ROM abgespeichert und enthält Prozesscode. Um einen Process Thread zu gegenzeichnen, werden die Makros PROCESS_BEGIN() zu Beginn und PROCESS_END() zum Ende einer Process Thread Funktion benutzt. Ein Process Thread ist ein Protothread [3].

Protothreads

Protothreads können als eine Kombination aus Events und Threads angesehen werden. Die Threads können bei Eingebetteten Systemen, wo Speicher eine der wichtigsten Ressourcen ist, ein großen Speicheroverhead verursachen, da für jeden Thread Stackspeicher allokiert werden muss, die mit anderen Threads nicht geteilt werden kann. Zum Beispiel ein Thread, mit 200 Byte großem Stack, verbraucht 10% der RAM eines MS430F149 Mikrocontrollers [4]. Protothreads sind dagegen Stackfrei und benutzen alle den selben Stack, was sehr kleiner RAM Overhead (nur 2-12 Bytes pro Protothread [1]) verursacht. Aber da die stackfrei sind, ist die Präemption nicht möglich, weil nur ein Stack benutzt wird. Dafür bietet Contiki eine extra Library, die preemptive Threads unterstützt [1]. Auch die lokalen Variable werden nicht gespeichert.<br\> Die Protothreads, wie die Thread auch, unterstützen eine sequenziellen Codefluss und bieten die Funktionen zum explizitem Warten auf ein oder mehrere Ereignisse, was bei Events nicht oder sehr schwer zu realisieren ist. Dabei werden keine implizite Blockierung benötigen, da die Codestellen, wo der Codefluss blockiert wird, explizit mit PT_YIELD() oder PROCESS_WAIT_EVENT() gekennzeichnet werden. Die PT_YIELD() oder PROCESS_WAIT_EVENT() können nur innerhalb einer Protothreaddeklaration und nicht innerhalb einer aufgerufener Funktion verwendet werde. In Contiki ist es auch möglich ein Kind-Prozess zu erzeugen, dafür wird PT_SPAWN() verwendet. PT_SPAWN() initialisiert einen Kind-Protothread und blockiert dabei den Vater-Protothread bis erzeugte Protothread fertig ist (PT_END() oder PT_EXIT() müssen aufgerufen werden). In Contiki ist die Speicher für Zustand einer Protothread in Process Control Block gespeichert und wenn es notwendig ist, kann die dynamisch beim Laufzeit allokiert werden.<br\> Protothreads sind nicht hardwarespezifisch, da sie in Programmiersprache C geschrieben sind, und können auch bei anderen Systemen mit oder ohne einem Betriebssystem verwendet werden [1].

Events

In Contiki sind zwei Eventtypen vorhande: asynchronous und synchronous Events.<br\> Bei asynchronous Events werden die Ereignisse nicht sofort an den Prozess geschickt, sondern zuerst in eine Event Queue in der Contiki Kernel abgelegt. Die Event Queue wird sequenziell durch Kernel abgearbeitet, dazu werden Prozesse aus der Event Queue von Kernel geweckt. Asynchronous Events können an einen spezialen oder alle aktive Prozesse mit Funktion process_post() gesendet werden. Wenn ein asynchronous Events an alle aktive Prozesse geschickt wurde, wird der Ereignis nacheinander an die Prozesse sequenziell geschickt [3].<br\> Synchronous Events werden von dem Kernel direkt an den Prozess gesendet. Synchronous Events sind äquivalent zu einem Funktionsaufruf und können nur an einen bestimmten Prozess mit Funktion process_post_synch() gesendet werden. Der Prozess, an den Event gesendet wurde, wird aufgeweckt und der Prozess, der Event gesendet hat, wird solange blockiert, bis aufgerufener Prozess fertig ist [3].<br\> Es gibt noch ein spezieller Art den Events in Contiki, Polling. Beim Polling wird versucht, den Prozess so schnell wie möglich zu bearbeiten. Polling wird mit Funktion process_poll() aufgerufen [3].<br\> Event werden durch ein Eventidentifier identifiziert. Eventidentifier ist eine 8-bit Zahl, die an empfangenen Prozess weitergegeben wird [3].

Timers

Einer der wichtigen Aspekte in jeder System ist Zeitverwaltung, die verwendet wird, um

  • zu überprüfen, ob eine Zeitperiode abgelaufen ist
  • System zu wecken oder schlafen zu legen
  • weitere Aufgabe zu erledigen.

Contiki stellt viele Timer Bibliotheken zur Verfügung, die von Prozessen und System benutzt werden können. Ein Clock Module stellt Funktion zur Verfügung, um Systemzeit zu behandeln und CPU kurzzeitig zu blockieren. Mehrere Timer Module

  • Timer
  • Stimer
  • Ctimer
  • Rtimer

bieten Möglichkeiten für verschiedene Zeitaufgaben [5].

uIP

uIP ist eine RFC-kompatible TCP/IP-Implementierung, die Contiki einen direkten Zugang zum Internet ermöglich. Bei Implementierung wurden nur notwendige Eigenschaften, die für TCP/IP-Kommunikation benötigt werden, implementiert. Deshalb kann uIP nur die Single Network Interface behandeln. Auch dynamische Speicherallokierung für ein- und ausgehende Daten wird nicht unterstütz. uIP hat einen Datenuffer, wo der größte TCP/UDP-Paket beim Empfangen bzw. Senden gespeichert werden kann, und eine Tabelle, um Verbindungsstatus zu halten [6]. Die Codegröße beträgt nur wenige Kilobyte und RAM Benutzung kann auf wenige als 100 Bytes konfiguriert werden. uIP unterstützt TCP, UDP, IP und ARP [1]. Um den Umgang mit der uIP zu vereinfachen wurde eine BSD-Socket ähnliche Schnittstelle entwickelt, Protosockets. Protosockets arbeiten nur mit TCP/IP Verbindungen und benutzt Protothreads, um sequenzielle Codefluß zu ermöglichen. Wie bei Protothreads beginnt eine Funktion mit PSOCK_BEGIN() und endet mit PSOCK_EXIT() [1].


Hardware

AVR Dragon

AVR Dragon unterstützte Schnittstellen:

  • In System Programming  (ISP)
  • High Voltage Serial Programming  (HVSP)
  • Parallel Programming (PP)
  • JTAG Programming (JTAG Prog)

<br\> LED Status:

LED Farbe Beschreibung
1 Rot Inaktiv, nicht mit AVR Studio verbunden
1 Orange Inaktiv, mit AVR Studio verbunden
1 Grün Daten werden übertragen
1 Gelb Firmware-Aktualisierung oder Initialisierung
2 Grün Zeigt USB-Übertragung


RZ RAVEN Evaluation and Starter Kit

RZ RAVEN Evaluation and Starter Kit besteht aus zwei AVR Raven und einem RZ USB Stick
RZ Raven besteht aus zwei Mikrocontroller ATmega3290P und ATmega1284P.

  • Atmel ATmega3290P steuert LCD und andere Peripheriegeräte
  • Atmel ATmega1284P ist für Atmel AT86RF230 radio zuständig

Beide Mikrocontroller werden über JTAG- oder ISP-Schnittstelle programmiert.


ATMega128RFA1-Mikrocontroller-Boards

<br\>

Entwicklungsumgebung

AVR Tools

  • avr-libc - AVR spezifische C-Standartbibliothek
  • binutils-avr - Assembler, Linker und weiter Hilfsporgramme
  • gcc-avr - ein C-Compiler für AVR-Mikrocontoller
  • gdb-avr - AVR Debugger
  • simulavr - AVR Simulator
  • avrdude, avrdude-doc - AVR-Programmiersoftware


Tools installieren:

apt-get install  avr-libc binutils-avr gcc-avr gdb-avr simulavr
apt-get install avrdude avrdude-doc


Jetzt werden programmer-id des Dragon-Bords

avrdude -c?

Valid programmers are:
...
dragon_jtag = Atmel AVR Dragon in JTAG mode  [/etc/avrdude.conf:663]
...

und Mikrocontroller-Typen

avrdude -c dragon_jtag -p?

Valid parts are:
...
m1284p =  ATMEGA1284P     [/etc/avrdude.conf:4760]
...
usb1287 = AT90USB1287     [/etc/avrdude.conf:13505]
...
m3290p = ATMEGA3290P     [/etc/avrdude.conf:6038]
...

rausgesucht.

Verbindung mit dem Mikrocontroller kann mit folgendem Befehl getestet werden.

sudo avrdude -c dragon_jtag -p m1284p -P usb
[sudo] password for user: 

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9705

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

Testprogramm[7]

Für den Testprogramm wurde Webserver-Anwendung ausgesucht, die in folgenden Verzeichnissen zu finden ist:

contiki/examples/webserver-ipv6-raven - für Raven Bord ATMEGA1284P
contiki/examples/ravenusbstick - für RZ USB Stick AT90USB1287

Kompilierung unter Contiki

Zuerst wird Programm für RZ USB Stick

cd contiki-2.5/examples/ravenusbstick/
make

und dann für Raven Bord

cd contiki-2.5/examples/webserver-ipv6-raven/
make

kompiliert.

Installation auf RZ USB Stick und Raven Bord

AVR Dragon wird an RZ USB Stick und Raven Bord per JTAG-Kabel angeschlossen. Nun muss das Programm auf Hardware überspielt werden.

sudo avrdude -c dragon_jtag -p usb1287 -P usb -U flash:w:ravenusbstick.hex
sudo avrdude -c dragon_jtag -p m1284p -P usb -U flash:w: webserver6-avr-raven.hex

Testen

Nach der Installation wird RZ USB Stick als Netzwerk Schnittstelle erkannt und bekommt automatisch die IPv6 Adresse: fe80::0012:13ff:fe14:1516/64, die mit ifconfig Befehl überprüft werden kann. Wenn es nicht der Fall ist, kann die Adresse manuell eingestellt werden.

sudo ip -6 address add fe80::0012:13ff:fe14:1516/64 scope link dev usb0

Als nächstes wird radvd Daemon installiert

sudo apt-get install radvd

und Konfigurationsdatei(/etc/radvd.conf) erstellt.

interface usb0
{
    AdvSendAdvert on;
    AdvLinkMTU 1280;
    AdvCurHopLimit 128;
    AdvReachableTime 360000;
    MinRtrAdvInterval 100;
    MaxRtrAdvInterval 150;
    AdvDefaultLifetime 200;
    prefix AAAA::/64
    {
        AdvOnLink on;
        AdvAutonomous on;
        AdvPreferredLifetime 4294967295; 
        AdvValidLifetime 4294967295; 
    };
};

Als letztes wird IP Adresse konfiguriert und IP Forwarding aktiviert.

sudo ip -6 address add aaaa::1/64 dev usb0
sudo echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
sudo /etc/init.d/radvd restart

Jetzt kann Raven Bord mit ping Befehl

ping6 -s aaaa::1 aaaa::11:22ff:fe33:4455

oder per Webbrowser

http://[aaaa::0011:22ff:fe33:4455]

erreicht werden.

Analyse vorhandener Verdrahtung

Die Steuerung der Kaffeemaschine ist auf einer Platine hinter dem Bedienpanel angebracht und ist in Form eines NEC 78F1977 Mikrocontroller ausgeführt. Die LEDs und die Schalter sind auf der Platine zu finden und sind in Form einer Matrixschaltung angebracht.
Eine Matrixschaltung ist ein Verfahren, um mehrere Verbraucher mit wenigen Steuerleitungen ansteuern zu können. Bei dieser Schaltung werden Verbraucher in Spalten und Zeilen angeordnet. Die Spannung wird abwechselt und periodisch auf Spalten angelegt. Wenn an einer Spalte Spannung und einer Zeile Masse angelegt ist, fließt Strom durch den Verbraucher. Bei der Schaltung sind 4 x 8 Steuerleitungen vorhanden und es ist möglich 32 verschiedene Verbraucher anzusteuern.
Im Projekt „Driver for the automatic coffee maker AEG CF220“ vom Tanjeff-N. Moos und Kai Beckmann wurde die Schaltung der Kaffeemaschine analysiert. Dabei wurde festgestellt das die Signale A bis E die Spalten der Schaltung sind und die Signale I, K,L, M die Zeilen. Die Platine der Kaffeemaschine wurde mit einem Mikrocontroller-Board verbunden. Die existierende Verdrahtung wird bei diesem Projekt verwendet.
Steckerbelegung:

Pin Signal Pin Signal
1 A 11 I
2 GND 12 K
3 B 13 GND
4 GND 14 F
5 C 15 G
6 GND 16 GND
7 D 17 L
8 GND 18 M
9 E 19 GND
10 GND 20 M

Design

Der Kaffeevollatomat AEG CF220 wird auf der Mikrocontroller-Board mit einem einem ATMega128RDF1 und Contiki als Betriebssystem durch vorhandene Vedrahtung angeschlossen. Die Kommunikation zwischen den Mikrocontroller-Board und Außenwelt geschieht per Funk (siehe Abbildung 5). Dazu wird Kommunikationsstack uIP des Betriebssystem Contiki verwendet. Kaffeemaschine Steuerung mit Contiki Grob-Design.png

Beobachtung

Eine LED kann bis zu drei Zustände haben: an, aus und blinken. Um die Zustände darzustellen werden 2-Bits benötigt
LED-Status Aufbau:

LED Status Wert
angeschaltet 11
ausgeschaltet 00
blinkt 10

Bei dem Projekt werden nur die Spalten C, D und E beobachtet. Um alle LEDs dieser Spalten abzubilden, werden 24 Bits notwendig (2 Bit für jede LED * 4 Zeilen * 3 Spalten).
Gerätstatus Aufbau:

Bit Spalte Zeile
0-1 D K
2-3 D M
4-5 D I
6-7 D L
8-9 C K
10-11 C M
12-13 C I
14-15 C L
16-17 E K
18-19 E M
20-21 E I
22-23 E L


Die existieren Verdrahtung wird an PortB der Mikrocontroller-Board angeschlossen. Es werden 7 Pins belegt. An Pins 13, 15, 16 werden Spalten der Schaltung angeschlossen und an Pins 18-21 die Zeilen. Alle Pins werden als Eingang ohne Pull-Up Widerstand definiert.
Mikrocontroller-Boart Pin-Belegung:

Mikrocontroller-Pin Signal
13 C
15 D
16 E
18 I
19 K
20 L
21 M
22 GND


Da es zwischen Kaffeemaschine und Mikrocontoller-Board Potentialdifferenz vorhanden war, wurde folgende Schaltung entwickelt, die das Problem behebt:
EM2013SSP06 Schaltung.png

Kommunikation

Auf dem Mikrocontroller-Board läuft ein Web-Server, der HTTP-Anfragen bearbeiten und den Antwort zurückschickt. Die Anfragen können über einen Webbrowser oder eine Clientanwendung, die Anfragen über HHTP-Protokoll stellt, gesendet werden.
Der Webserver wartet auf einen TCP/IP-Event und beim Eingang dessen, werden die empfangene Daten bearbeitet. Zuerst wird überprüft, ob es eine GET-Anfrage (GET /file.html HTTP/1.1 Host: [aaaa::ff:fe00:1]) ist. Bei ungültigen Anfragen wird die Verbindung getrennt. Bei gültigen Anfragen wird festgestellt, ob die angeforderte Datei vorhanden ist. Wenn die Datei nicht gefunden wird, wird 404.html als Antwort zurückgesendet, sonst wird Datei gesendet. Bei shtml-Datei muss zuerst überprüft werden, ob die Datei einen Script, bei dem die Daten zuerst generiert werden müssen, oder eine andere Datei, die eingebunden werden muss, enthält. Ein Script wird als %! stats gegenzeichnet, dazu wird ein Script-Funktion ausgeführt, die Antwort generiert. Wenn eine andere Datei eingebunden werden soll, wird es mit %!: header.shtml markiert. Aktivitätsdiagramm.png

Dokumentation

Weblinks

Einzelnachweise

  1. 1,0 1,1 1,2 1,3 1,4 1,5 [1] Contiki 2.x Reference Manual. Generated by Doxygen 1.4.1
  2. 2,0 2,1 2,2 [2] Contiki - a Lightweight and Flexible Operating System for Tiny Networked Sensors
  3. 3,0 3,1 3,2 3,3 3,4 3,5 3,6 3,7 [3] Contiki Contiki Community Wiki
  4. [4] Protothreads: Simplifying Event-Driven Programming of Memory-Constrained Embedded Systems
  5. [5] Contiki Contiki Community Wiki
  6. [6] Full TCP/IP for 8-Bit Architectures
  7. [7] Running Contiki with uIPv6 and SICSlowpan support on Atmel RAVEN hardware