next up previous contents
Next: Schlussfolgerung Up: Studienarbeit Previous: Lösungsansätze   Contents

Subsections


Umsetzung und praktische Ergebnisse


Dienstesystem

Das Dienstesystem wurde entsprechend der Vorüberlegungen aus Kapitel 7.4 in C++ objektorientiert implementiert. Dieses Kapitel soll den Funktionsumfang der implementierten Klassen und die Funktionalität der daraus abgeleiteten Dienste, welche in Kapitel 4 beschrieben worden sind, erläutern.

Die genauen Signaturen und die Semantik der einzelnen Funktionen sind den Quelltexten zu entnehmen. Eine Liste der relevanten Files der Prototypimplementierung zeigt die Tabelle 5.


Table 5: relevante Files der Prototypimplementierung
Variable Beschreibung
rpc.[ch] Basis- und Hilfsfunktionen des RPC-Mechanismus
service.[ch] Spezifikation und Implementierung der Klassen service_handle und service
tools.[ch] allgemeine Hilfsfunktionen
debug.[ch] Funktionen zum Speichermanagement und zur Fehlersuche
cache.[ch] Implementierung des Namensdienstes



Protokoll

Die Basis-RPC-Funktionalität welche benötigt wird, um zwischen den Diensten zu kommunizieren, wird in der Beispielimplementierung in den Dateien rpc.c und rpc.h zur Verfügung gestellt.

Kodierung

Zur Kommunikation zwischen den Diensten werden strukturierte Daten serialisiert und über einen Kommunikationskanal versendet. Die Kodierung, welche für die Serialisierung der Daten eingesetzt wird, wurde in Anlehnung an BER[24] entwickelt. Sie bietet im Vergleich zu BER nur eine eingeschränkten Funktionsumfang und kommt dadurch mit weniger Metainformationen und somit mit weniger Bandbreite aus. Es wurden nur wenige Datentypen implementiert [*], welche in Tabelle 6 aufgelistet sind. Es wurde auch auf eine Anpassung der Daten in eine plattformunabhängige Darstellung wie z.B. bei XDR verzichtet, da wir derzeit davon ausgehen, dass nur x86-Komponenten miteinander kommunizieren werden. Die Kodierung ist jedoch einfach gegen eine andere austauschbar.

Die einzelnen Daten werden anhand ihres Datentypes jeweils durch ein Identifikations-Byte eingeleitet. Anschließend folgt das unbearbeitete Datum. Bei der Dekodierung wird jeweils der Typ-Identifikator gelesen und anhand diesem die entsprechende Anzahl an Bytes als Datum angenommen.

Zusätzlich ist es Möglich, eine beliebige Anzahl an Daten zu gruppieren. Dies hat den Vorteil, dass man bei der Auswertung des Datenstromes inhaltlich zusammenhängende Daten als Einheit bearbeiten kann. Somit besteht die Möglichkeit, Strukturen in dem Datenstrom zu definieren. Diese Gruppierung ist auch rekursiv anwendbar.


Table 6: Datentypen
Bezeichnung in rpc.h Typ-ID Datentyp Größe C-Datentyp
TYPE_BYTE 0x1 Byte 1 char
TYPE_INT 0x2 Integer 4 int
TYPE_STR 0x3 String -[*] char*
TYPE_GROUP_START 0x4 - - -
TYPE_GROUP_END 0x5 - - -


RPC-Protokoll

Das implementierte RPC-Protokoll basiert auf der Serialisierung strukturierter Daten. Dabei ist das Verfahren, welches zum serialisieren genutzt wird, nicht festgelegt sondern austauschbar.

Es werden Anfragen (Request) und Antworten (Response) unterschieden, welche jeweils einen unterschiedlichen Aufbau des Datenstroms haben. Ein Request wird immer durch einen String eingeleitet, welcher die gerufene Funktion bezeichnet. Anschließend folgen die kodierten Parameter. Die Parameter-Struktur ist frei wählbar und wird von jedem entsprechenden Dienst ausgewertet und gegebenenfalls durch einen Fehlercode zurückgewiesen. Antworten auf Requests werden immer durch einen Status-Byte eingeleitet (mögliche Werte sind in Tabelle 7 aufgelistet). Im Anschluss daran folgen die kodierten Ergebniswerte. Die Struktur der Ergebnisse ist ebenfalls frei wählbar.


Table 7: Status-Codes der Antwort
Bezeichnung Code Bedeutung    
CALL_STATUS_CALLED 0x01 die Anfrage wurde ausgewertet    
CALL_STATUS_FOUND 0x02 die gerufene Funktion wurde gefunden    
CALL_STATUS_OK 0x04 der Ruf der Funktion war erfolgreich    
CALL_STATUS_FAILD 0x08 der Ruf der Funktion war nicht erfolgreich    
CALL_STATUS_NFUNC 0xa0 die gerufene Funktion wurde nicht gefunden    


Dieser geringe Funktionsumfang hat sich als ausreichend herausgestellt. Durch das genutzte RPC-Protokoll und die beschriebene Kodierung wird Bandbreite schonend genutzt. Somit ist der Einsatz des RPC-Mechanismuses für die Kommunikation über den RS485-Bus geeignet.

C++-Klassen

service_handle

(siehe Tabelle 8) Die Basisklasse service_handle stellt alle grundlegenden Funktionen und Variablen zur Verfügung, um einen Dienst zu spezifizieren, um einen Dienst entfernt zu nutzen und um Informationen über einen Dienst zu sammeln. Objekte dieser Klasse werden auch dazu genutzt, um einen Dienst bei einer Suche zu referenzieren.


Table 8: Funktions- und Variablenbeschreibung der Klasse service_handle
Variable Beschreibung
description Liste der beschreibenden Elemente des Dienstes (siehe Kapitel 7.4)
ipaddr eindeutige IP-Adresse
port Port-Nummer, auf dem der Dienst Anfragen entgegen nimmt
ttl Die Time-To-Live wird bei erfolgreichem Funktionstest des Dienstes auf einen definierten Wert gesetzt. Sobald der Dienst nicht verfügbar ist, so wird dieser Wert verringert. Bei ttl=0 wird der Dienst aus der Diensteliste entfernt.
type SERVICE_LOCAL(1): Der Dienst ist lokal
  SERVICE_REMOTE(2): Der Dienst ist ein Verweis auf einen entfernten Dienst
  SERVICE_HINT(4): Der Dienst ein permanenter Hinweis auf einen entfernten Dienst und wird bei ttl=0 nicht gelöscht.
last_scan letzter Zeitpunkt, an dem der Dienst verfügbar war
   
Funktion Beschreibung
describe_service Funktionsset um einen Dienst zu beschreiben. Die Beschreibung wird in description gespeichert
call Funktion um eine bestimmte Funktion des Dienstes zu rufen.


service

(siehe Tabelle 9 auf Seite [*]) Dies ist die Basisklasse, welche alle nötigen Funktionen und Variablen für einen Dienst zur Verfügung stellt. Sie verwaltet alle zur Verfügung gestellten Funktionen und Variablen. Darüber hinaus startet sie einen Server-Thread (siehe rpc.h). Diese Klasse implementiert zusätzlich den Vergleichsoperator, um Beschreibungslisten von Diensten miteinander zu vergleichen.


Table 9: Funktions- und Variablenbeschreibung der Klasse service
Variable Beschreibung
rpc_env Referenz auf eine Datenstruktur des RPC-Mechanismus
status Status des Dienstes (1 entspricht aktiv)
function_list Liste der exportierten Funktionen
variable_list Liste der Variablen, welche von Clienten eingesehen und geändert werden können
   
Funktion Beschreibung
REGISTER_FUNCTION Diese Funktion registriert andere Funtkionen, welche entfernt aufgerufen werden können.
REGISTER_VARIABLE Diese Funktion registriert Klassen-Variablen, welche entfernt abgefragt werden können.


Ein Objekt der Klasse service stellt standardmäßig Funktionen (siehe Tabelle 10 auf Seite [*]) für den entfernten Aufruf zur Verfügung, mit welchen man Eigenschaften des Dienstes abfragen und den Dienst überwachen kann. Dadurch ist eine leichtes Herausfinden der Funktionalität eines Dienstes mit einfachen Tools möglich.


Table 10: Standardfunktionen eines Dienstes
Funktion Beschreibung
ping Basisfunktion, welche auf einen entfernten Aufruf antwortet, um zu testen, ob der Dienst noch erreichbar ist.
get_functions Diese Funktion liefert eine Liste aller exportierten Funktionen zurück.
get_variables Diese Funktion liefert eine Liste aller exportierten Variablen zurück.
get_var Diese Funktion liefert den Wert einer bestimmten Variable.
set_var Diese Funktion setzt eine bestimmte Variable.


cache

(siehe Table 11) Die Klasse cache implementiert alle nötigen Funktionen, um einen Namensdienst aufzubauen und mit diesem zu arbeiten. Objekte dieser Klasse können in drei verschiedenen Modi arbeiten. Im Mastermodus werden alle Registrierungen von Diensten an alle anderen Namensdienste, welche sich im Mastermodus befinden repliziert. Ein weiterer Modus ist der Standardnamensdienst. In diesem Modus agiert der Dienst als Namens-Cache. Alle Registrierungen werden an einen Masterserver weitergeleitet und unbekannte Dienste werden von den Masterservern abgefragt. Es ist sinnvoll, dem Standardnamensdienst eine Liste aller Masterserver mitzugeben. Somit ist es möglich, dass Registrierungen und Abfragen durch Nutzung eines anderen Masterservers ausgeführt werden können, falls ein Masterserver ausgefallen ist. Der dritte Modus ist der Clientmodus. Dieser kommuniziert normalerweise mit einem Standardnamensdienst[*]auf dem selben Rechnersystem über den bekannten Port 4000. Über ein Objekt in diesem Modus können Suchanfragen gestellt werden oder können Registrierungen erfolgen.

Objekte dieser Klasse, welche im Master- oder Standardnamensdienstmode sind, betreiben zusätzlich noch Dienste-Monitoring (in Funktion service_cache::watcher). In der Prototypimplementation werden die Dienste aller 5 Sekunden (DEFAULT_SCANTIME) auf ihre Funktion geprüft. Sobald ein Dienst 2 mal nicht antwortet (DEFAULT_TTL), wird er bei einer Suchanfrage nicht mehr beachtet. Nach weiteren 3 (DEFAULT_DEATH_TTL) gescheiterten Tests wird der Dienst abgemeldet. Falls der Dienst nur durch eine Netzwerkstörung nicht erreichbar war und somit eigentlich funktionstüchtig ist, so bleibt dieser solange deaktiviert, bis er sich erneut anmeldet. Dies geschieht in der Regel aller 120 Sekunden (DEFAULT_REREGISTER).


Table 11: Funktions- und Variablenbeschreibung der Klasse cache
Funktion Beschreibung
search Suche nach einem bestimmten Dienst
register_service Registrierung eines Dienstes
deregister_service Abmelden eines Dienstes
reregister_services Neues Registrieren der angemeldeten Dienste bei einem Masterserver


Erweiterungen

Derzeit wird davon ausgegangen, dass ein Dienst voll einsatzfähig ist, sobald er von einem Namensdienst angezeigt wird. Dies ist nicht sehr robust. In einer Weiterentwicklung ist es denkbar, dass die Funktion call in der Klasse service auch eine überwachende Funktion übernimmt. Sobald ein Dienst auf eine Anfrage nicht antwortet, könnte transparent ein weiterer Dienst gesucht werden, welcher die selbe Funktionalität erfüllt.

Dienste

Auf den oben beschriebenen Klassen wurden einige Basisdienste für das Zugangssystem entwickelt, welche in Kapitel 7.7 spezifiziert worden sind.

Neue Dienste können einfach programmiert werden, in dem man die Klasse service ableitet und neue Funktionalität implementiert (siehe Beispiel 4 auf Seite [*]). Auch die Implementierung der Nutzung eines entfernten Dienstes ist nicht kompliziert (siehe Beispiel 5 auf Seite [*]). Die genaue Spezifikation der API ist den Quell-Dateien zu entnehmen.


\begin{example}
% latex2html id marker 427
[htb]
\begin{Verbatim}[frame=single,f...
... r->run();
}\end{Verbatim}\caption{
Implementierung eines Dienstes}\end{example}


\begin{example}
% latex2html id marker 432
[htb]
\begin{Verbatim}[frame=single,f...
...,&c);
}\end{Verbatim}\caption{
Implementierung eines Diensterufes}\end{example}


IP over RS485

Wie in Kapitel 6 beschrieben, ist es für die Einführung des Zugangssystemes an der TUC notwendig, den vorhandenen RS485-Bus zur Kommunikation zu nutzen. Es ist auch herausgestellt worden, dass es sinnvoll ist, einen Treiber zu implementieren, welcher transparent IP zur Verfügung stellt.

Recherchen haben ergeben, dass es für Linux noch keine Implementierung für IP-Over-RS485 gibt. Aus diesem Grund wurde ein eigenes Kernel-Modul entwickelt.


In dem Fall der TUC werden nur 2 Adern des verlegten Kabels genutzt. Dies lässt laut RS485-Spezifikation eine asynchrone Kommunikation (Halbduplex) zu. Das hat zur Folge, dass nur ein Bus-Teilnehmer senden kann und alle anderen Teilnehmer empfangen diese Daten. Um dennoch eine geordnete Kommunikation zu ermöglichen, muss ein Teilnehmer die Steuerung des Busses übernehmen. Steuerung bedeutet hierbei, dass er koordiniert, welcher Teilnehmer senden darf und welcher nicht. Die steuernde Komponente soll hier als Master und die restlichen Komponenten als Slave bezeichnet werden. Jeder Teilnehmer wird durch eine busweit eindeutige Nummer identifiziert (Teilnehmernummer oder RS485-nodeid)

Protokoll

Für die Kommunikation über einen RS485-Bus gibt es meinen Recherchen zu Folge keinen Protkollstandard. Aus diesem Grund wurde ein eigenes Protokoll entwickelt.


Der Master sendet jeweils ein Paket auf den Bus, welches genau einen Teilnehmer adressiert. Sobald der entsprechende Teilnehmer dieses Paket empfangen hat, antwortet er mit einem Paket identischen Aufbaus, wobei in dem Adressfeld nun der Absender steht, damit der Master identifizieren kann, ob der richtige Teilnehmer geantwortet hat.

Figure 3: RS485 Bus-Protokoll
\includegraphics[]{rs485-spec}

Ein Paket besteht jeweils aus einer Startmarkierung (Start-Kennung FRAME_SS=0x53), einem Adressfeld, der Nutzlast (Payload) und einer Markierung des Paketendes (End-Kennung FRAME_ES=0xca). Die Größe der Nutzlast ist von der eingestellten MTU abhängig. Auf eine Prüfsumme über die Nutzlast wurde vorerst verzichtet, da sich höhere Schichten (TCP) darum kümmern. Die Adresse, welche in dem Adressfeld angegeben werden kann, ist identisch zu der Teilnehmernummer (nodeid).

Bei diesem Verfahren treten jedoch verschiedene Laufzeitprobleme auf. Deshalb wurden einige Zeitabstände definiert, um die Übertragung optimieren zu können. Diese sind auch notwendig, da die eingesetzten Medienwandler Verzögerungen aufweisen. Die Sendeeinheit wird nach einer sendefreien Zeit von einem Baud bei 9600 Baud/s automatisch abgeschaltet. In dieser Zeit kann kein anderer Teilnehmer senden (Timer d1).


Table 12: Parameter zur Feinabstimmung der RS485-Kommunikation
Bezeichnung Beschreibung Standardwert  
d1 Wartezeit nach dem Senden, bis sich die Sendeeinheit deaktiviert hat 100 µs  
d2 Timeout, bis eine Antwort zu erfolgen hat 100 µs  
n2 Anzahl der Timeouts d2, bis der nächste Teilnehmer angesprochen wird 10  
d3 Verzögerung bis Antwort gesendet wird 200 µs  
d4 Verzögerung bis nächster Teilnehmer nach erfolgreicher Antwort angesprochen wird 2000 µs  
irqto Interrupt-Timeout: innerhalb dieser Zeit muss der Interrupt ausgelöst werden, ansonsten wird das Kernel-Modul neu initialisiert 10 jiffies  
rxto Empfangs-Timeout: innerhalb dieser Zeit müssen Pakete empfangen werden, ansonsten wird die serielle Schnittstelle neu initialisiert 100 jiffies  


Der Parameter n2 ist eingeführt worden, da die kleinste Zeitauflösung (z.B. für Kernel-Timer) in einem Standard-Kernel (also nicht Realtime-Kernel) ein jiffie[*] ist. Um dennoch in kleinen Zeiträumen warten zu können, wurde die Funktion usleep genutzt. Nach der Wartezeit wird geprüft, ob Daten vorhanden sind, ansonsten wird wieder unter Zuhilfenahme dieser Funktion gewartet. Dies wird n2-mal durchgeführt, bevor zum nächsten Slave übergegangen wird.


Zuerst wurde IP-Over-RS485 über einen Treiber implementiert, welcher im User-Space des Linux-Kernels zwischen der seriellen Schnittstelle (tty) und einem generischen Netzwerkinterface (tun/tap-Kernel-Treiber) vermittelt hat. Jedoch hat sich gezeigt, dass dies nicht optimal war, da die kleinste Zeitauflösung des Linux-Kernels ein jiffie ist, und der Treiber für die serielle Schnittstelle nur in dieser Auflösung mit dem Senden beginnen kann. Da nun Sender und Empfänger nur im Abstand von 10ms agieren konnten und die Frequenzgeber beider Teilnehmer unterschiedlich schnell liefen, konnte man im Worst-Case nur mit einer Latenz von 20ms kommunizieren, welche sich durch Interferenz begründen lässt (siehe Abbildung 4).

Figure 4: Kommunikation auf dem RS485-Bus
\includegraphics[]{rs485_inter}

Deshalb wurde Arbeit in die Entwicklung eines Kernelmoduls gesteckt, da man im Kernel unmittelbar auf Interrupts reagieren und direkt mit dem seriellen UART kommunizieren kann. [1]

Kernel-Modul

Das Kernel-Modul besitzt eine Reihe von weiteren Parametern (siehe Tabelle 13), um die Funktionalität auf verschiedenen Systemen zu realisieren.


Table 13: Parameter zur Feinabstimmung der RS485-Kommunikation
Bezeichnung Beschreibung Standardwert  
iobase Basisadresse der seriellen Schnittstelle nicht gesetzt  
irq Interrupt der seriellen Schnittstelle nicht gesetzt  
nodeid Adresse des Teilnehmers; Teilnehmer 0 ist Master 0  
option 0x1: Verhalten von RTS wird invertiert 0  
divisor Divisor zur Basisfrequenz (1.8461 MHz) des UART, um die Geschwindigkeit der seriellen Schnittstelle einzustellen 1 (115220 Baud/s)  
max_nodes Anzahl der Teilnehmer, welche der Master verwalten soll 15  
windbond 0x01: Die Basisfrequenz bei einem Winbond-UART ist 24MHz und muss auf 1.8461 MHz heruntergeregelt werden 0  


Nach erfolgreicher Installation des Kernelmoduls werden im Master-Mode so viele Netzwerkinterfaces (rs00, rs01, ..) bereitgestellt, wie es Teilnehmer gibt. Über diese Interfaces können nun Punkt-Zu-Punkt-Verbindungen konfiguriert werden.


\begin{example}
% latex2html id marker 497\begin{Verbatim}[frame=single,frames...
... b)\end{Verbatim}\caption{Konfiguration des RS485-Netzwerk-Devices}\end{example}

Die Beschreibung der internen Struktur dieses Kernel-Modules würde den Rahmen dieser Studienarbeit sprengen und soll somit hier nicht weiter diskutiert werden [19].

Probleme

Als Problem hat sich die Kommunikation zwischen unterschiedlichen UART-Chipsätzen herausgestellt. Es treten hohe Bitfehler auf. Normalerweise werden ältere UART-Chips (wie sie z.B. im embedded PC ,,miniPC'' eingebaut sind) mit einer Frequenz von 1.8461 MHz betrieben. Diese werden standardmäßig durch (16+divisor) geteilt. Somit ist eine maximale Datenrate von 115200 Baud/s möglich. Neuere Chips, welche eine maximale Datenrate von 2Mbit/s ermöglichen, arbeiten mit 24 MHz. Diese können über die Konfiguration entsprechender Register auf 1.8461 MHz dividiert werden, um herkömmliche Geschwindigkeiten zu ermöglichen. Jedoch stimmen die resultierenden Frequenzen nicht genau überein, was vermutlich die Fehler verursacht. [20]

Dieser Effekt dürfte nicht mehr auftreten, wenn ausschließlich moderne Boards benutzt werden, welche auch einen UART-Chip haben, welcher mit 24 MHz betrieben wird.

Überwachung des Modules

Neben den Standard-Zählern eines Unix-Netzwerk-Interface stellt der RS485-Treiber eine weitere Schnisttstelle zum Überwachen der Funktionalität des Kernel-Modules im /proc-Verzeichnis zur Verfügung. Daraus sind neben statistischen Zählern (payload Bytes, start sentinel) auch Informationen über Timeouts (irq-to, rx-to) und dem Status einzelner Teilnehmer incl. dem Zeitpunkt ihrer letzten Kommunikation sichtbar.


\begin{example}
% latex2html id marker 512
[htb]
\begin{Verbatim}[frame=single,f...
...0/0 on=0 0-0=0\end{Verbatim}\caption{Informationen aus /proc/rs485}\end{example}

Übergang in das Campusnetz

Für die Kopplung (Bridge) zwischen dem RS485-Bus und dem Campusnetz kommt ein Standard-PC oder eine Steuereinheit mit Ethernet in Reichweite zu einer Datendose zum Einsatz. Diese Brücke betreibt den RS485-Bus als Master und vermittelt Pakete zwischen dem Ethernet-Interface (eth0) und den RS485-Netzwerk-Interfaces (rs00, rs01, ..). Zusätzlich fungiert diese Brücke als Proxy für ARP-Anfragen (Proxy-ARP). Somit ist es möglich, dass die Steuereinheiten campusweit und transparent über IP angesprochen werden können. Es bietet sich an, alle Bridges nur über ein spezielles VLAN an das Campusnetz anzuschließen und Pakete in diesem VLAN nur von dedizierten Servern zuzulassen, um die Sicherheit der Klienten zu erhöhen.


Client-Betriebssystem

Um viel Flexibilität auf den Client-Controllern zu bekommen, ist es sinnvoll, ein ausgereiftes Betriebssystem darauf laufen zu lassen. Dies wurde auch in Kapitel 7.1.1 schon erläutert.


Bevor im Rahmen dieser Arbeit eine eigene LINUX-Mini-Distribution entwickelt wurde, sind verschiedene existierende Distributionen für embedded Systeme evaluiert worden (z.B. jailbait, muLinux, fdlinux und greenfrog).

Zusammenfassend haben alle diese fertigen Distributionen den Nachteil, dass sie an eine bestimmte glibc-Version gebunden sind, welche meist sehr alt ist. Des Weiteren basieren sie auf alten Kernels und sind nur für Spezialanwendungen (z.B. Router) konzipiert.

Viele dieser Distributionen basieren auf dem Programm busybox [2], welches in einem statisch gelinkten Programm alle notwendigen Posix-Befehle zur Verfügung stellt. Dieses Programm kann auch als init-Ersatz benutzt werden. Somit ist es möglich, eine ausgereifte Distribution ausschließlich mit Hilfe von busybox zu bauen.

Die vollständige Konfiguration und Aufbereitung dieser Distribution soll hier nicht beschrieben werden. Sie ist dem Entwicklungsverzeichnis [18] der Distribution zu entnehmen.

Die derzeitige Installation der LINUX-Distribution erfolgt unter Zuhilfenahme des Paketes etherboot [26]. Beim Boot-Vorgang erhalten die Clienten automatisch über DHCP eine IP und es wird ein lauffähiges Linux über ROOT-NFS gebootet, welches die Flash-Disk der Controller partitioniert und sich selbst darin installiert.

Die komplette Konfiguration aller Controller geschieht zentral in der Datei /etc/setup. Um die Controller automatisch und eindeutig zu identifizieren, wird die MAC-Adresse der der internen Netzwerkkarte ausgelesen. Im Falle des miniPC besteht die Möglichkeit über das jida-Interface einen eindeutigen CPU-Identifikator auszulesen. Jedoch ist mir dies nicht gelungen. Grund hierfür ist, dass nur vorkompilierte Kernel-Module vorhanden sind, welche bei der eingesetzten Kernelversion (2.4.13) zu einem Absturz führen.


Table 14: Ressourcenverbrauch der mini-Distribution
Mountpunkt Größe in KB Beschreibung
/bin 2388 busybox und weitere Tools
/boot 711 Kernel
/etc 98 Konfigurationen und Setup-Programme
/lib 2204 Systembibliotheken
/root 798 Programme für das Zugangssystem
Summe: 6199  


Anhand des eindeutigen Identifikators (MAC-Adresse) wird aus der Datei /etc/setup eine Controller-spezifische Konfigurationsdatei (/etc/config) erzeugt. Darin sind alle zur Laufzeit notwendigen Parameter enthalten, welche von allen benötigten Skripten ausgewertet werden.

Partitionierung

Um bei einem Absturz zu verhindern, dass das Filesystem einen inkonsistenten Zustand erfährt, wurde die Flash-Disk in den Controllern in zwei Partitionen partitioniert (je 8 MByte), welche mit dem EXT3-Filesystem formatiert worden sind. Dieses Filesystem, bietet Data-Journaling-Fähigkeiten, so dass ein Absturz des Systems während eines Schreibvorganges keine Beschädigung des Filesystems nach sich zieht.

Die beiden Partitionen sind für unterschiedliche Aufgaben vorgesehen. Die erste Partition (root-Filesystem /) beherbergt alle Dateien, welche für die Funktionen des Betriebssystems und des Zugangssystem wichtig sind. Diese Partition ist vor Schreibzugriffen geschützt (Read-Only). Die zweite Partition verwaltet alle Daten, welche auf den Steuereinheiten während seiner Laufzeit geändert werden. Das sind vor allem Daten, welche von dem Dienst proxy in einem Cache abgelegt sind.

Produktivitätstools

Um administrative Arbeiten auf den Controllern zu erleichtern wurden einige Tools geschrieben, welche in Tabelle 15 aufgeführt sind.


Table: Administrations-Tools für die Controller
Variable Beschreibung
boot_local veranlasst ein Reboot von dem internen Flash
boot_net veranlasst ein Reboot über die Netzwerkkarte
get erneuert eine Systemdatei über einen zentralen Server via http
rw schaltet die Systempartition schreibfähig
ro schaltet die Systempartition schreibgeschützt


Kernel

Wie schon an anderer Stelle erwähnt, kommt auf den Steuereinheiten ein Standard Linux-Kernel zum Einsatz (2.4.13). Die genaue Konfiguration ist der Projekthomepage zu entnehmen [18].

Dieser Kernel benötigt keine VGA-Karte und nutzt als Standardkonsole die erste serielle Schnittstelle. Dadurch ist es möglich, dass man diese Schnittstelle als Wartungskonsole nutzen kann. Über diese ist auch ein direkter Filetransfer über das zmodem-Protokoll möglich, in dem man das Programm rz aufruft und mittels eines Terminalprogramms (z.B. kermit) Dateien überträgt.

Hardware

Steuereinheit

Während der Entwicklung des Zugangssystemes wurden als Controller für die Steuereinheiten zwei embedded PC-Systeme evaluiert. Beide erwiesen sich als zuverlässig. Dennoch unterscheiden sie sich in der Handhabung und in den technischen Daten, welche in Tabelle 16 verglichen werden.


Table 16: Vergleich zwischen miniPC und Bisquit-PC
  miniPC Biscuit-PC
CPU 486 66MHz 486 133 MHz
RAM 16 MByte 16 MByte (erweiterbar)
Nachteile wird sehr heiß verbraucht viel Strom
  COM3/4 müssen durch Software initialisiert werden  
  Ethernet nur optional  
Vorteile kompaktes Gehäuse Bauteile einfach zugänglich
    einfach erweiterbar
    ATA-Flash nutzbar
    Ethernet inklusive


Als Vorteil des miniPC ist festzuhalten, dass er durch sein kompaktes Gehäuse eine einfache Montage an DIN-Schinen (,,Hut-Schinen'') zulässt und sich einfach austauschen lässt. Jedoch ist die Installation eines Betriebssystem auf dem miniPC nicht einfach, falls kein Ethernetmodul eingebaut ist. Zur Installation müsste man von Diskette booten und über PPP (serieller Anschluß) ein Grundsystem installieren. Alternativ könnte man das CPU-Modul des miniPC ausbauen, was sehr aufwändig ist und mittels eines Evalutaionsboards ein Grundsystem einspielen.

Vorteilhafter für die Wartung und Installation ist ein Board, auf welches man eine ATA-Flash-Disk (Solid State Disk) stecken kann. Diese Flash-Disks haben einen 2,5''-IDE-Anschluss, welchen man mittels eines Adapters einfach an einen normalen PC anschließen und somit ein Grundsystem installieren könnte. Solch eine IDE-Schnittstelle hat der Biscuit PC, welcher mir zur Verfügung stand. Dieser hat zusätzlich auch noch einen PC/104-Bus, über den man einfach beliebige Erweiterungskarten stecken kann. Darüber hinaus ist ein embedded PC auf Einplatinenbasis kostengünstiger als das Konzept des miniPC.

Magnetkartenleser

Die derzeit eingesetzten Magnetkartenleser geben die Informationen der Magnetkarten im Clock-Data-Protokoll über zwei Steuerleitungen ab. Dies bedeutet, dass auf einer Leitung ein Takt gesendet wird und parallel dazu auf der zweiten Leitung die entsprechenden Daten (bitweise). [14]

Um diese Informationen im Betriebsystem auslesen zu können, wurde ein Kernelmodul geschrieben, welches diese Daten auswertet und im /proc-Filesystem dem Administrator zugänglich macht.

Dabei wird das Clock-Signal des Magnetkartenleser an Pin 10 der parallelen Schnittstelle angeschlossen, welche bei einer steigenden Flanke einen Interrupt ausgelöst . Im Kernelmodul wird bei dieser Unterbrechung das Daten-Signal (Pin 12) ausgewertet, und anhand der Spezifikation des Magnetkartenlesers decodiert. Die gelesenen Daten werden über ein File im /proc-Filesystem (/proc/card) bereitgestellt und können mittels Filesystemfunktionen ausgelesen werden. Solange keine Daten anliegen, blockiert die Leseoperation. Im Fehlerfall wird das Schlüsselwort ,,ERROR'' zurückgegeben.


Ein wichtiger Punkt, welcher in dieser Arbeit noch nicht angesprochen worden ist, ist die Frage wie realisiert wird, dass sowohl alte Magnetkarten als auch neue Magnetkarten mit einer erweiterten Identifikationsnummer im neuen Zugangssystem funktionstüchtig sind. Dies stellt jedoch kein Problem dar, da in der Zuordnung von Magnetkarten-IDs zu Nutzer (siehe Dienst mcard) keine Beschränkungen existieren. Die alten Magnetkarten liefern eine 10-Stellige ID zurück und werden im Zugangssystem als solche verarbeitet. Von der MoUSe geschriebene neue Magnetkarten-IDs können beliebig lang sein und werden als längere Zahl interpretiert.

Tür-Relais und Tür-Sensor

Hauptaufgabe der Steuereinheiten ist das Steuern eines Tür-Relais (,,Tür-Summer'') und das Auswerten eines Tür-Sensors. Der Sensor gibt Auskunft darüber, ob eine Tür im Schloss eingerastet ist. Dieser Sensor schließt ein Signalkabel kurz, welche direkt an einen Eingang der parallelen Schnittstelle angeschlossen und im Linux-Kernel ausgewertet werden kann.

Das Tür-Relais wird mit 12 Volt durch die interne Stromversorgung der Steuereinheiten gespeist und durch ein elektronisches Lastrelais gesteuert, welches an einem Ausgang der parallelen Schnittstelle angeschlossen ist.


Zusammenfassen ist festzustellen, dass ein Austausch der Controller-Box bei gleichzeitiger Nutzung vorhandene externer Hardware (Magnetkartenleser, Tür-Relais, RS485-Bus, Tür-Sensor) möglich ist.


next up previous contents
Next: Schlussfolgerung Up: Studienarbeit Previous: Lösungsansätze   Contents
Ronald Schmidt 2002-10-07