Parallax Propeller 2 (Teil 4): Senden von Strings
Das Ziel dieser Artikelserie ist eine Einführung zum Parallax Propeller 2. In dieser Folge geht es um erweiterte Möglichkeiten zum Senden von Strings wie etwa mit Print auf Arduino-Systemen. Mit dieser ersten Lösung kann man dann einige Debug-Informationen auf klassischem Weg senden. Bisher kann der Code lediglich ein einzelnes Zeichen mit 115.200 Bd (8 Datenbits, keine Parität und 1 Stoppbit) senden. Der komplette Code ist in Bild 1 zu sehen und kann hier heruntergeladen werden.
Wenn man z.B. den String „Code alive“ wie in Bild 2 senden will, führt dies zu vielfachen Aufrufen der Funktion tx() - ein Aufruf für jedes Zeichen. Bei sich wiederholenden Codezeilen sollte man über eine Generalisierung der Aufgabe nachdenken. Kopierte Abschnitte von Codefragmenten überall im Projekt sind keine gute Idee, besonders wenn man später etwas hinzufügen oder den Code korrigieren muss. Besser ist der Bau einet Funktion, die einen String als Argument übergeben bekommt und diesen dann in einzelne Zeichen zerlegt, welche die Funktion nacheinander per tx()-Funktion sendet. Das klingt einfach, und wenn schon einmal programmiert hat, der sollte das nicht nur in der Theorie hinbekommen. Wer allerdings zum ersten Mal mit SIN bzw. SPIN2 zu tun hat, hat noch etwas mehr Lesearbeit und Tüftelei vor sich.
Übergabe von Strings
Zeichenketten sind nur eine fortlaufende Speichermenge sind, die alle Zeichen hintereinander enthält und mit einer binären Null ("\0") abgeschlossen wird. Folglich wird einfach die Startadresse dieses Speicherblocks an eine Funktion übergeben. Bei C/C++ erfüllt der &-Operator in Verbindung mit dem ersten Element der Kette diesen Zweck. In SPIN2 wird dies von der Syntax her etwas anders gehandhabt, funktioniert aber weitgehend gleich. Anders ist die Art und Weise, wie die Funktion und das Argument deklariert werden. Der Typ der an die Funktion übergebenen Variable wird nicht angegeben. Ohne deklarierten Typ nimmt SPIN2 an, dass es sich um eine Variable des Typs Long (32 bit) handelt. Das ist oft praktisch, kann aber auch einige unerwünschte Nebeneffekte mit sich bringen. In diesem Fall passt das gut, denn die Speicheradresse des zu übergebenden Strings ist 32 bit lang. Doch die Art und Weise der Deklaration lokaler Variablen unterscheidet sich: Alle Variable (hier c) müssen am Funktionskopf deklariert werden. Dies geschieht mit einem „|“ nach der schließenden Klammer in dieser Zeile. Wenn wir mehr als eine Variable benötigen, setzen wir sie in diese Zeile und trennen sie mit „,“. Bild 3 zeigt, wie der Funktionskopf aussehen sollte.Innerhalb der Funktion (siehe Bild 4) werden die Daten ja Byte für Byte gelesen. Hierzu gibt es die Anweisung c := byte[s++], die eine Erklärung benötigt. Die Variable c hat ja noch keinen Typ bzw. nur den Standard-Typ. Ohne die Verwendung von byte[] würden 32 bit (Variable uint32_t) auf einmal gelesen. Mir der Anweisung byte[s++] wird aber nur ein Byte an der Stelle von „s“ bzw. an der Speicheradresse, an der der String beginn, gelesent. s++ in Verbindung mit byte[] stellt sicher, dass die Adresse nur um ein Byte inkrementiert wird. Andernfalls würden alle Operationen 32 bit breit sein. Da nun byteweise gelesen wird, fehlt noch ein Blick auf die repeat-while-Schleifenstruktur. Solange c ungleich (<>) zu binär Null ist, wird alles innerhalb der repeat-while-Anweisung wiederholt durchlaufen.
Innerhalb der Schleife von Bild 5 steck die ein Byte sendende tx()-Funktion. Darauf folgt eine weitere Zeile, die das nächste Byte des Strings s einliest und in die Variable c schreibt. Danach prüft die Schleife ob c immer noch ungleich binär Null ist.
Damit haben ist die Funktion prints() einsatzbereit. Mit ihr kann man nur ganze Strings via UART an einen angeschlossenen PC oder Logikanalysator senden. Der nächste Schritt ist das Auslesen der Zustände von I/O-Pins und dessen serielle Ausgabe. Wie schwierig ist es wohl, den Status eines I/O-Pins auszulesen? Theoretisch ist das sicher sehr einfach, doch manchmal sind es die netten Extras, die den Unterschied machen und zeigen, wie viele Funktionen in den Smart-Pins stecken.
Übersetzung: Dr. Thomas Scherer