CCBAS2MT.S19
Echtes Multitasking auf dem
C-Control/BASIC-Mikrokontrollersystem

Autor: Dietmar Harlos


Datum: 15. Januar 2005
Für: C-Control-1 Version 1.1

Was ist Multitasking?

Unter Multitasking versteht man die Fähigkeit eines Computersystems, mehrere Aufgaben (Tasks) quasi-gleichzeitig zu erledigen. Genaugenommen werden die Begriffe Multitasking und Multithreading unterschieden. Beim Multitasking laufen zwei Programme weitgehend unabhängig voneinander ab, als ob sie auf zwei verschiedenen Computern ausgeführt würden. Dagegen werden beim Multithreading sogenannte Threads ("Fäden") eines Programms parallel ausgeführt, teilen sich somit einen gemeinsamen Adreßraum und können über Variablen sehr einfach Daten austauschen. Der normalerweise sequentielle Programmfluß wird aufteilt und quasi-parallel ausgeführt. Quasi-parallel bedeutet, daß der Computer zwar immer nur einen Thread ausführt, zwischen den Threads wird aber sehr schnell hin- und hergeschaltet. Die Rechenleistung wird also aufgeteilt.

Wie ist das Multitasking auf der C-Control-1 realisiert?

Der Programmfluß eines CCBASIC-Programms wird in zwei Threads aufgeteilt, die von einem Multitasking-Interpreter ausgeführt werden. Es handelt sich bei diesen Threads im Prinzip um zwei getrennte Programme, die aber die gleichen Variablen und Systemressourcen verwenden und im gleichen CCBASIC-Sourcecode stehen. Zwischen den Threads wird standardmäßig einige hundert Mal pro Sekunde hin- und hergeschaltet, wodurch jeder Thread mit ungefähr der halben Geschwindigkeit abläuft. Falls ein Thread weniger Leistung benötigt, kann er Rechenleistung freigeben, die dem anderen Thread zugute kommt.

Jeder Thread besitzt seinen eigenen Programm-Counter, Rechenstack und GOSUB-Stack, welche vom Multitasking-Interpreter bei jedem Taskwechsel ausgetauscht werden müssen. Dafür werden 12 Bytes des DCF77-Buffers verwendet, so daß weder ein DCF77-Empfänger noch eine andere Signalquelle am DCF/FREQ1-Pin der C-Control angeschlossen werden darf! BASIC-Interruptroutinen werden vom Multitasking-Interpreter ebenfalls nicht unterstützt, denn da der DCF77-Buffer bereits belegt ist, läßt er sich nicht mehr zum Zwischenspeichern des Rechenstacks bei Verwendung einer Interruptroutine verwenden (siehe ONTIMER.ZIP auf C-Control-intern).

Wieviel Leistung geht durch das Multitasking verloren?

Obwohl jeder Taskwechsel relativ aufwendig ist, entsteht durch das Multitasking praktisch kein Leistungsverlust. Laufen beide Threads ungebremst, erreicht jeder Thread ziemlich genau die halbe Geschwindigkeit im Vergleich zum Ablauf ohne Multitasking. Ein Thread, der augenblicklich wenig Leistung benötigt, kann einen Großteil der Rechenzeit freigeben, wodurch der andere Thread bis auf seine volle Normalgeschwindigkeit kommt. Damit die Vorteile des Multitaskings voll zum Tragen kommen, ist es sinnvoll, die C-Control mit einer höheren Taktgeschwindigkeit auszustatten. Der standardmäßige 4-MHz-Quarz kann durch eine 8-, 12-, 16-, oder sogar 24-MHz-Version ausgetauscht werden. Ab 16 MHz muß allerdings auch das externe I2C-EEPROM (24C65) durch eine Version ausgetauscht werden, die einen schnelleren I2C-Bus-Takt unterstützt. Siehe FAQs.

Was ist gegenüber der herkömmlichen Singletask-Programmierung zu beachten?

Für den normalen CCBASIC-Programmierer ändert sich trotz der unterschiedlichen Programmausführung nur sehr wenig. Zu beachten ist in erster Linie, daß einige CCBASIC-Befehle, die den Programmfluß lahmlegen, mit Vorsicht verwendet werden sollten, da diese auch die Taskumschaltung hemmen. Vor allen Dingen sind das die beiden Befehle GET und INPUT, die so lange warten, bis passende Daten von der seriellen Schnittstelle gelesen werden können. Vor dem Einsatz dieser Befehle sollte deshalb zum Beispiel mittels RXD geprüft werden, ob überhaupt Daten an der seriellen Schnittstelle zur Verfügung stehen. Darüberhinaus ist innerhalb einer mit SYS aufgerufenen Assemblerroutine systembedingt kein Taskwechsel möglich.

Hat ein Thread seine Aufgaben vorerst erledigt, kann er mittels PAUSE-Befehl Rechenzeit freigeben. Ein PAUSE-Befehl bewirkt ein vorzeitiges Umschalten zum anderen Thread. Außerdem kann im PAUSE-Parameter übergeben werden, wieviele 20-ms-Zeiteinheiten der andere Task anschließend mindestens ausführen darf, bevor der nächste Taskwechsel stattfindet. Erlaubte Werte liegen im Bereich von 0 bis 255. Der BEEP-Befehl enthält übrigens einen versteckten PAUSE-Befehl. Die maximal mögliche Rechenleistung wird dem verbliebenen Thread zugewiesen, falls sich ein Thread mittels END beendet.

Falls Systemressourcen (z.B. die Datendatei) von beiden Threads verwendet werden dürfen, ist es notwendig, mit Hilfe eines Flags zu signalisieren, das die entsprechende Systemressource augenblicklich belegt ist. Ansonsten kann es zu sehr unschönen Effekten bis hin zu Datenverlusten kommen.

Ich habe sieben kleine Beispielprogramme erstellt, die zeigen, wie einfach Multitasking-Programme in CCBASIC erstellt werden können. Die Textausgaben der Programme werden auf der seriellen Schnittstelle übertragen, deshalb sollte auf dem PC ein Terminalprogramm benutzt werden. Außerdem verwenden einige Programme den BEEP-Ausgang. Hier sollte, falls noch nicht geschehen, ein Piezo-Schallwandler angeschlossen werden.

Kann man noch einen zusätzlichen, dritten Thread ins System integrieren?

Noch einen weiteren Thread hinzuzufügen, also drei Threads gleichzeitig zu unterstützen, ist recht schwierig, da noch einmal mindestens 12 Bytes im RAM zum Zwischenspeichern des BASIC-PC, des Rechenstacks und des GOSUB-Stacks benötigt werden. Bei einer C-Control, die auf einem 68HC705-Mikrokontroller basiert, wäre das kein Problem, denn dieser Kontrollertyp besitzt 176 zusätzliche RAM-Bytes. Auf der Standard-C-Control könnte man höchstens einen Teil des Hardwarestacks verwenden. Aber der ist vorgesehen, um in selbstgeschriebenen Assemblerprogrammen Unterprogrammaufrufe durchzuführen. Deshalb könnten keine eigenen Assemblermodule mehr verwendet werden. Aber das ginge in diesem Fall ohnehin nicht, da das interne EEPROM komplett mit dem Multitasking-Interpreter belegt sein würde. Auch hier böte sich wieder der 68HC705 an, denn der besitzt ein 16 kB großes EPROM zur Aufnahme des Betriebssystems und für zusätzliche Assemblerprogramme wie den Multitasking-Interpreter. Siehe CC1-OS-Project.
 

Viel Spaß beim C-Controllern!

Dietmar Harlos
http://ccintern.dharlos.de