ftCommunity | Wiki | Programmieren des Robo-Interface in C

Wiki

Thema: Programmieren des Robo-Interface in C

Version 7

von: thkais

am: 07.04.2006, 17:36:55 Uhr


Programmieren des Robo-Interface in C



Inhalt



Vorwort
Wie beginne ich?
Namenskonventionen (Variablen)
Erste Programme
. Vereinfachung des I/O-Zugriffs



Vorwort



Obwohl die von ft angebotene grafische Programmierumgebung RoboPro durchaus ihren Reiz hat (ich selbst bin nach anfänglicher Skepsis inzwischen total begeistert davon) gibt es einige Projekte, die die Möglichkeiten von RoboPro sprengen. Obwohl man diese Aussage relativ sehen muss, denn es ist sogar gelungen, einen "Rubiks Cube" (Zauberwürfel) mit RoboPro zu lösen - und das ohne PC-Unterstützung im Stand-alone Betrieb.
Wenn man einen Microcontroller (µC) direkt in C programmieren will, muss man sich zunächst über einiges im Klaren sein: Die Programmierung eines µC unterscheidet sich in vielen Dingen von der Programmierung eines PC.
Zwar können viele Algorithmen übernommen werden, aber der wichtigste Teil eines Interface, nämlich die Hardware, unterscheidet sich ganz gewaltig. Ausserdem ist das Betriebssystem nicht so absturzsicher, wie das eines PC.
Ferner gibt es auch Unterschiede zwischen verschiedenen Systemen. Ich möchte hier das weit verbreitete RCX in Verbindung mit NQC ("Not Quite C") als Vergleich heranziehen. Der größte Unterschied zwischen dem Robo-Interface und dem RCX besteht darin, dass im Robo-Interface grundsätzlich echter Maschinencode ausgeführt wird (auch in Verbindung mit RoboPro), während das RCX von Haus aus einen Bytecode ausführt (dies lässt sich mit anderen Betriebssystemen ändern, allerdings funktioniert dann kein NQC mehr). Dies hat Vor- und Nachteile: Der Vorteil eines Bytecode-Interpreters ist die Absturzsicherheit, denn der Interpreter überprüft die Plausibilität von Daten und kann im Notfall korrigierend eingreifen. Der Nachteil: Nur die Funktionen, die in diesem Bytecode integriert sind, können auch verwendet werden. Dies ist z.B. der Grund, weshalb mit NQC keine Gleitkommaarithmetik möglich ist. Beim RoboInterface ist dies prinzipiell vom Compiler abhängig, der von ft unterstützte originale Renesas-Compiler vom Hersteller des im Robo-Interface eingebauten µC ist in der Lage, Gleitkommaartihmetik zu unterstützen. Ich möchte aber auch nicht den großen Nachteil verschweigen: Dadurch, dass "echter" Maschinencode ausgeführt wird, können Programmfehler wesentlich dramatischere Auswirkungen haben,
als bei einem Bytecode-Interpreter. Es gibt für das Betriebssystem nur begrenzte Möglichkeiten, hier einzugreifen. Aber was heisst eigentlich "Betriebssystem" bei einem µC? Wer sich mit µC auch abseits vom Robo-Interface beschäftigt, wird sehen, dass üblicherweise kein Betriebssystem in dem Sinne vorhanden ist, wie man es von einem PC kennt. Eigentlich schreibt man sich das selbst - denn es entspricht dem Anwenderprogramm. Beim Robo-Interface ist das Betriebssystem eigentlich nur eine Art Bibliothek, die die Verbindung zur Hardware vereinfacht. So werden die Schnittstellen initialisiert, Timer zur Verfügung gestellt etc., viel mehr auch nicht. Sobald ein Anwenderprogramm die Kontrolle übernommen hat, ist es verantwortlich für den richtigen Umgang mit der Hardware. Deshalb möchte ich auch nochmal die Warnung des Robo-Interface Entwicklers verdeutlichen:
Ein Fehler im Programm kann im ungünstigsten Fall einen Hardwaredefekt hervorrufen. Im günstigsten Fall hängt sich das Interface einfach nur auf.
Dies liegt vor allem an den Unzulänglichkeiten von C. Das, was C so schnell macht, ist gleichzeitig das größte Problem: Es gibt keinerlei Kontrollmechanismen. Variablen mit unterschiedlichen Datentypen können bunt gemischt werden, mit ungewissem Ausgang, bei Arrays kann ohne weiteres der Index überschritten werden, so dass andere Variablen oder wichtige Datenbereiche überschrieben werden. Über die Gefahren von Pointern garnicht zu reden.
Also: Wer das Robo-Interface direkt in C programmieren möchte, sollte genau wissen, was er tut. Vor allem sollte er wissen, was ein C-Compiler mit dem Code macht und notfalls auch mal etwas Assembler-Kenntnisse mitbringen, um den generierten Code zu überprüfen oder in einem Simulator laufen zu lassen.
Zum Erlernen der Programmiersprache C ist das Robo-Interface definitiv nicht zu empfehlen.
Auch Umsteiger von NQC sollten sich darüber im Klaren sein, dass NQC nur eine Teilmenge von C darstellt und bei weitem nicht so fehleranfällig ist.
Und zum Schluß noch etwas in eigener Sache:
Die hier von mir vorgestellten Programme wurden getestet und so weit als möglich überprüft. Dennoch muss ich jegliche Schadenersatzansprüche ablehnen - jeder muss selbst wissen, was er tut. Dies ist definitiv keine Anleitung für Anfänger in der C-Programmierung.

Wer die Programmierung eines µC in C erlernen will, dem möchte ich eine andere Vorgehensweise empfehlen:
Zunächst C lernen. Es gibt einen kostenlosen C-Compiler von Borland für DOS. Das reicht vollkommen, denn Windows-Anwendungen laufen auf einem µC sowieso nicht ;). Dann das Programmieren von z.B. einem Atmel-µC. Der kostet ca. 2-5 Euro, ein Programmiergerät nochmal 5 Euro und die restliche Software (programmiersoftware und C-Compiler) ist ebenfalls kostenlos erhältlich. Auch bei diesen µC wird man zum fehlerfreien Programmieren "erzogen". Entweder das Programm funktioniert - oder nicht. Wenn wirklich etwas schief geht, sind die Verluste auch eher zu verschmerzen als die Reparatur am Robo-Interface...
Noch ein Wort zu C++: Die meisten Compiler für µC unterstützen kein C++, da der Funktionsumfang von ANSI-C zur Programmierung eines µC im allgemeinen vollkommen ausreicht.



Wie beginne ich?



Die vom Entwickler des Robo-Interface mitgelieferte Anleitung zur Installation des Compilers, compilieren vorhandener Projekte und anlegen neuer Projekte ist vorbildlich. Deshalb werde ich dies auch garnicht weiter ausführen.

Nur ein paar Tipps zur Einrichtung des Renesas-Compilers:
Wer nicht unbedingt die Projekte auf C:Workspace speichern will, kann unter Setup -> Options -> Workspace das Defaultverzeichnis wechseln.

Um mit der Hardware des Robo-Interface in Kontakt zu treten, gibt es die sogenannte "Transfer-Area". Eine Beschreibung der Transfer-Area befindet sich in der Anleitung von ft.




Namenskonventionen



Um Programme von unterschiedlichen Programmierern verwenden zu können, sollte man sich auf gemeinsame Richtlinien zur Vergabe von Variablennamen einigen. Zwar unterscheidet sich die vom Robo-Interface Entwickler verwendete Verfahrensweise auch von meiner eigenen, aber mir erscheint es sinnvoll, diese Namenskonventionen zu übernehmen, denn dadurch ist es in zukunft einfacher, fremde Programmteile zu integrieren.
Mitgeliefert werden auch Verkürzungen Variablendeklarationen, so wird z.B. anstelle von "unsigned char" "UCHAR" verwendet. Diese Definitionen befinden sich in der Datei "ke_c.h".
Bei der Vergabe von Variablennamen stehen die ersten zwei Zeichen für den Variablentyp, z.B.:

ucVariable = unsigned char
ulVariable = unsigned long




Erste Programme



Einen guten Ansatz, sich mit der Programmierung des Robo-Interface vertraut zu machen, ist die Analyse der mitgelieferten Demo-Programme. Sinnvoll für die ersten Schritte: Einen neuen Workspace anlegen, ein vorhandenes Demo-Programm dort hineinkopieren und dann einzelne, kleinere Änderungen vornehmen oder auch kleinere Erweiterungen vornehmen. Wie schon erwähnt - Man bekommt keine Fehlermeldungen, wenn etwas schiefgeht.
Um einen Programmteil zu finden, der Ärger macht, gibt es z.B. die Möglichkeit, bestimmte Ausgänge mit LEDs zu bestücken und diese beim Erreichen bestimmter Programmteile ein- oder auszuschalten.
Da dies nicht gerade sehr Benutzerfreundlich ist, nutze ich inzwischen die Möglichkeit, per serieller Schnittstelle Nachrichten an den PC zu senden. Hierzu gibts später mehr.
Insgesamt gesehen erzieht die Programmierung von µC zu fehlerfreiem programmieren, denn eine Fehlersuche gestaltet sich teilweise sehr lästig. Von vornherein gut durchdachte und geplante Algorithmen ersparen so manchen Abend Fehlersuche.




Vereinfachung des I/O-Zugriffs



Berechtigterweise wurde im Forum moniert, dass der Zugriff auf die Ein- und Ausgänge sehr kryptisch ist.
Willkommen bei C!
Nein, im Ernst: Es gibt natürlich jederzeit die Möglichkeit, dies mit selbstgeschriebenen Funktionen zu ändern.

Bei der Programmierung von µC muss man sich mit einem Thema beschäftigen, mit dem man sonst nur sehr selten konfrontiert wird: Bitmanipulationen, in µC-Kreisen auch "Bitschubsen" genannt ;)
Aus dem o.g. Grund gibts nun einen Crash-Kurs in Bitarithmetik.
Ein Bit ist die kleinste Informationseinheit innerhalb eines Computers, die entweder 0 oder 1 sein kann. Da man damit noch nicht viel anfangen kann, werden die Bits zusammengefasst, z.B. zu einem Byte (= 8 Bit). Zu beachten ist, dass die Bits innerhalb eines Bytes mit 0 - 7 durchnummeriert werden.

Warum brauchen wir das? Beim Robo-Interface (wie auch bei vielen anderen Interfaces auch) werden die Ein- und Ausgänge durch einzelne Bits repräsentiert. Wenn ich eine Lampe an Ausgang 1 anschließe, dann leuchtet sie, wenn Bit 0 in sTrans.M_Main auf "1" gesetzt wird. (Vorsicht: Die Ausgänge werden von 1-8 gezählt, die Bits von 0-7).
Hinzu kommt noch, dass die Ausgänge mit unterschiedlicher Ausgangsspannung angesteuert werden können (das stimmt so nicht 100%, aber der Effekt ist der gleiche...). Das heißt also: Eine Lampe kann dunkler oder heller leuchten, ein Motor schneller oder langsamer laufen. Dies wird mit dem Array sTrans.MPWM_Main[] festgelegt. Dieses Array hat 8 Elemente, jedes Element kann Werte von 0 (= Stufe 1) bis 7 (= max. Spannung) annehmen. Hierbei ist dringend zu beachten, dass der Array-Index niemals ausserhalb des Wertebereichs 0..7 liegen darf. Sollte aus irgendeinem Grund z.B. der Index 8 verwendet werden, landet man im nachfolgenden Datenbereich - und das ist sTrans.MPWM_Sub1. Somit wird dann der Spannungswert eines der Extension-Module geändert. Bei anderen Indizies sieht es entsprechend aus.
Aus Sicherheitsgründen empfehle ich deshalb beim Zugriff auf die Geschwindigkeitsarrays folgendes Konstrukt:



sTrans.MPWM_Main[ucIndex & 0x07] = ucSpeed



Durch den Operator & wird die Variable ucIndex mit 7 Binär "UND" verknüpft. Die Zahl 7 ist Binär 00000111, deshalb sind im Ergebnis die oberen 5 Bits immer 0 - das heißt, der Index kann nur Werte 0 - 7 annehmen, egal, welcher Wert tatsächlich in ucIndex steht.





to be continued....
(thkais)




 

Aktuelle Version von thkais am 09.04.2006, 19:18:49 Uhr
Version 13 von thkais am 09.04.2006, 19:18:02 Uhr
Version 12 von thkais am 08.04.2006, 06:28:09 Uhr
Version 11 von thkais am 07.04.2006, 20:59:11 Uhr
Version 10 von thkais am 07.04.2006, 20:39:51 Uhr
Version 9 von thkais am 07.04.2006, 20:26:22 Uhr
Version 8 von thkais am 07.04.2006, 19:24:51 Uhr
Version 7 von thkais am 07.04.2006, 17:36:55 Uhr
Version 6 von thkais am 07.04.2006, 17:22:51 Uhr
Version 5 von thkais am 07.04.2006, 17:17:21 Uhr
Version 4 von thkais am 07.04.2006, 15:13:21 Uhr
Version 3 von thkais am 07.04.2006, 13:56:52 Uhr
Version 2 von thkais am 07.04.2006, 13:43:00 Uhr
Version 1 von thkais am 07.04.2006, 13:33:23 Uhr

 

Wenn sie sich einloggen, können Sie dieses Thema bearbeiten.

 

Zurück zur Übersicht