3 Modularität, Basissystem, Systemaufbau
Die Beschränkung auf den Programm-Speicherbereich von 8 Kb Flash RAM,
die Tatsache, dass Assemblerprogrammierung eine maximale Optimierung
ermöglicht und der Versuch, eine Methode zur effizienten Umsetzung
größerer Projekte mittels Assembler zu erarbeiten, haben dazu geführt,
dass die gesamte Software in ATMEL Assembler
umgesetzt wurde.
Um nun Software in dieser relativ komplexen Anforderung effizient
umsetzten zu können, ist es notwendig, die Programmstruktur modular
zu halten und gewisse Abstraktionsschichten einzuführen, um, einerseits
die Entwicklung Problemkreis bezogen durchführen zu können und andererseits
möglichst ,,einfache'' und überschaubare Programmmodule zur Verfügung
zu haben. Damit ist zusätzlich auch ein gewisses Maß an Portabilität
zu erreichen, falls eine ähnliche Anforderung mit einer anderen Hardware
umgesetzt werden soll.
Abb. 7.2 zeigt, dass das Basissystem - wie
auch bei Betriebssystemen üblich - in einzelne Schichten unterteilt
wurde [7] S. 175. Die Grundidee, die dahinter steckt,
ist, dass eine Schicht bestimmte ,,Services'' liefert, die von der
darüber liegenden Schicht ohne Berücksichtigung der darunter liegenden
Mechanismen verwendet können.
Figure 7.2:
Applikationsaufbau
|
Hinweis:
Diese Gliederung darf nicht mit dem ISO-OSI Schichten-Modell verwechselt
werden, das vorwiegend für den Kommunikationsbereich definiert wurde,
sondern die Schichten wurden hier ausschließlich nach definierten,
aus den Gegebenheiten für sinnvoll erachteten Grenzen festgelegt.
Zusätzlich wurde durch extensive Nutzung von ,,symbolischen'' Konstanten
und durch die Verwendung vom Assembler-Makros versucht,
die Lesbarkeit des Source-Codes zu verbessern um damit einen wesentlichen
Nachteil gegenüber einer Hochsprachenumsetzung wieder Wett zu machen.
- Im vorliegenden Fall besteht die Applikationsschicht aus dem Benutzerinterface
(GUI) und der Menüsteuerung der obersten Menüebene. Diese
besteht aus einem Menüauswahl Event-Loop, um eine der Top-Level Funktionen
und damit den Funktionsmodus festzulegen (siehe dazu auch 7.6.1).
Wie im folgenden Punkt ersichtlich, wurde diese Schicht vorwiegend
aus software-organisatorischen Überlegungen eingeführt, sie beinhaltet
keine funktionellen Komponenten, die in Schicht 2 ausgeführt werden,
eine Änderung der Benutzeroberfläche (wie z.B. die Implementierung
von Zeit- und Datumsanzeigen) würde in diesen Bereich fallen.
- Die Programmsteuerung ist in der Art implementiert, dass für jeden
Betriebsmodus entweder die notwendigen Untermenüpunkte oder die entsprechenden
Programmfunktionen als Aufruf eines Unterprogramms umgesetzt werden.
Diese Schicht verwendet ebenfalls die Mechanismen, wie sie in Schicht
1 beschrieben sind und setzen auf die Basisroutinen der darunterliegenden
Schicht auf. Die Trennung in Applikationsschicht und Basissoftware
wurde vorwiegend auf Grund der in Absch. 7.5
vorgegebenen Code-Organisation eingeführt. Für jeden Hauptmenüpunkt
(Modus) existiert genau eine Sourcedatei, die die einzelnen Funktionen
umsetzt.
- An Basisfunktionen stehen Funktionen zur Ein- und Ausgabe von Menü-Interaktionen,
LCD-Texten, das Lesen und Schreiben von gespeicherten Werten, die
Anzeige von Stati sowie spezielle Ausgabeobjekte wie ,,Speedcursor''
oder ,,Menüselection'' (siehe dazu auch 7.6.2)
zur Verfügung. Diese Schicht zeichnet sich dadurch aus, dass die zugeordneten
Routinen nicht direkt auf die Hardware zugreifen, sondern Routinen
ansprechen, die quasi als ,,High-Level'' Routinen zur Verfügung
gestellt werden. In dieser Ebene sind auch die Software-Timer angesiedelt,
die nur mittels Schleifen Zeitverzögerungen bewirken oder die Pseudo-Scheduler
Schnittstelle (siehe 7.7.3.3), die Interrupt
gesteuerte Ereignisse (wie z.B. die Aktualisierung der Anzeige in
Schleifen) verwaltet.
- Die High-Level Hardwareebene greift auf die Ressourcen der halvedDISC
zu, verwendet jedoch die darunter liegende Low-Level Abstraktionsschicht,
die dann endgültig die Ports ansprechen, Timings berücksichtigen,
etc. In dieser Schicht sind Routinen zur Ausgabe typspezifischer Werte
(Zahlen im Dezimal-, BCD-, Binär- oder Hexadezimalformat, Winkelanzeige,
Hex-Byte, Hex-Word Ausgaben, ASCII-Text) oder die Tastaturbearbeitung
angesiedelt. Diese benötigen dazu die Low-Level Routinen, wie z.B.
Byte weises Lesen und Schreiben von
-Komponenten oder Port-I/O
Funktionen.
- Die Low-Level Schicht stellt die direkte Verbindung zur Hardware her.
Routinen zur Ansteuerung von
-Komponenten, wie dem PCF8591,
Einlesen oder Schreiben eines Temperatur-, Zeit- oder Datumswertes
werden in dieser Ebene umgesetzt. Diese Softwareebene ist bis zur
Adressierung des
-Busses Hardware spezifisch, und muss in
fast jedem Fall bei einer Änderung von Hardwarekomponenten mitgeändert
werden. Da die Low-Level Routinen in jedem Mikrocontroller-Projekt
vorhanden sein müssen, wurde in diesem Bereich großteils auf bestehenden
Code (z.B. die IIC-Lib oder LCD-Lib von Heiko Polster,
ACMC oder die
Timing-Routinen Harald Knapp,
www.comlogic.at)
zurückgegriffen.
gerhard.reithofer@tech-edv.co.at