Build your OS – Der Propellerchip

Mikrocontroller – Mikroprozessor

Wie schon im Hauptartikel angesprochen, wollen wir hier die Unterschiede zwischen einem Mikroprozessor und einem Microcontroller etwas genauer anschauen. Betrachten wir noch einmal die beiden Vergleichsbilder und versehen sie mit einer Legende:

„Sally“ 6502C – Der eigentliche 8Bit-Prozessor des Computers. (Wikipedia: „6502“)
8X8k RAM bank – 64kByte RAM Arbeitsspeicher, verteilt in acht Schaltkreisen.
ROM Basic – Der im Computer integrierte Basic-Interpreter.
ROM OS – Das Betriebssystem.
PIA 6520A – Ein Standart I/O-Schaltkreis mit 2x8Bit bidirektionalen Ports.  (Wikipedia: „6520“)
„ANTIC/GTIA“ – Diese beiden Schaltkreise dienen der Bildausgabe über TV. Beide arbeiten nur als Paar zusammen und sind so zwei Teile eines Ganzen. (Wikipedia: „Antic“ – Wikipedia: „GTIA“)
„POKEY“ – Soundchip, Tastaturcontroller, Timer (Wikipedia: „Pokey“)

Und nun noch etwas genauer der Propellerchip:

COG – In den acht COG’s befinden sich unsere RISC-Prozessoren, aber man sollte sie nicht mit einem Prozessor wie dem 6502 im Atari vergleichen, da es sich vielmehr um Subsystem handelt, die selbst aus CPU, Speicher, Timern und I/O bestehen. Jede COG ist also nochmal ein Miniatur-Mikrocontroller im Mikrocontroller. 🙂
ROM 32k – In diesem ROM befinden sich hauptsächlich der Zeichensatz, sin/cos/log-Tabellen und der Code des SPIN-Byteprozessors.
RAM 32k – Neben dem jeden der acht Prozessoren exklusiv zur Verfügung stehenden CogRAM, gibt es auch noch diesen globalen, für alle Prozessoren erreichbaren HubRAM.
I/O – In den Propellerchip ist ein universelles bidirektionales 32Bit-I/O-Port integriert – vergleichbar mit dem PIA-Chip.
Video – Es gibt im Propeller keine spezielle Video-Hardware, jede COG hat ein Video-Shifter integriert und kann mit den entsprechenden Routinen im CogRAM ein Videobild auf TV oder VGA erzeugen. Der Bildpuffer liegt dabei in der Regel im HubRAM – aber das ist schon mehr eine Sache der Software.
Sound – Eine spezielle Soundhardware gibt es im Propellerchip nicht, aber die RISC-Prozessoren sind auch hier schnell genug um zum Beispiel eine Soundausgabe mit 4 Kanälen durch Software in Echtzeit zu erzeugen.
Ser. Schnittstelle, Businterface, SPI… – Hier gilt das gleiche wie beim Sound. Mit der entsprechenden Software kann jede der universellen COG’s die Funktion einer solchen Hardware realisieren.
Timer – Jede COG hat zwei 32Bit-Timer integriert, über welche sie exklusiv verfügen kann. Insgesamt sind das also 16 Timer! Global gibt es noch einen Systemtimer.

Durch diese Übersicht sollte der Unterschied zwischen einem diskret aufgebauten Mikroprozessorsystem und einem Mikrocontroller schnell klar werden. Man kann vereinfacht sagen, dass ein Mikrocontroller ein kompletter Computer auf einem Chip ist.

Dieser Vergleich ist natürlich etwas unfair, da es sich ja um Technik aus sehr verschiedenen Zeitaltern der Computerkultur handelt. Es geht aber an diesem Punkt nicht um einen wertenden Vergleich, sondern einzig um die prinzipielle Unterscheidung. Zur damaligen Zeit hätte man ein solches Gerät nicht mit einem der damals verfügbaren Mikrocontroller aufbauen können, da diese natürlich in ihrer Leistungsfähigkeit viel zu beschränkt waren.  Auch die Leistungsfähigkeit heutiger PC’s ist mit dem Propeller nie erreichbar, obgleich die Grenzen momentan immer mehr verwischen, denn das Maximum des Wachstums scheint bei den CISC-Prozessoren erreicht zu sein, weshalb man nun auch massiv zu Mehrkernsystemen übergeht. Dabei wird aber schnell die geteilte Bandbreite zu einem Problem und so wird man wohl in nächster Zeit bald Prozessoren mit entsprechenden autarken Subsystemen finden, die ähnlich strukturiert sind wie der Propeller sind.

Mikrocontroller – Propeller

Aber es gibt ja auch noch andere Mikrocontroller, was also ist das besondere am Propellerchip? Mikrocontroller gibt es wirklich wie Sand am Meer, deshalb wollen wir schrittweise die Besonderheiten des Propeller-Designs herausstellen:

Stellen wir uns als erstes im Vergleich mit einem klassischen Mikrocontroller einen Propeller vor, welcher statt den acht COG’s nur eine normale CPU intern hat. Nun, wir werden feststellen, dass der Propeller sich dann prinzipiell nicht von einem AVR oder PIC unterscheiden würde. Selbst wenn die eine verfügbare CPU eine RISC-CPU wäre, würde sich das Konzept kaum von einem klassischen Mikrocontroller unterscheiden. Gehen wir jetzt einen Schritt weiter und stellen uns vor, dass der Propeller ein RISC-Subsystem als CPU hat. In einem Subsystem hat die RISC-CPU neben dem Hauptspeicher noch einen eigenen universellen Speicher, der als Registerbank oder Programmspeicher nutzbar ist. Im Propellerchip hat jede COG einen eigenen CogRAM von 512x64Bit und diverse Hardware wie Timer, Videoshifter und I/O zur Verfügung. Wie schon erwähnt, kann man sich die COG’s wie acht minimalistische Mikrocontroller im Mikrocontroller „Propeller“ vorstellen. In diesem Fall ist schon ein deutlicher Unterschied erkennbar, denn unsere RISC-CPU ist nun durch eine Art Microcode in dem Subsystem sehr flexibel. Mit dem entsprechenden Mikrocode wird aus dem RISC-Subsystem ein Video-Prozessor, oder ein Keyboard-Prozessor, oder ein Prozessor, der SPIN oder Basic verarbeiten kann. Das ganze macht natürlich nur wirklich Sinn, wenn wir den letzten Schritt wagen und acht RISC-Subsysteme integrieren – unsere COG’s. Jede Untereinheit kann nun parallel ihre eigene Aufgabe ausführen: Eine  COG ist Grafikprozessor und gibt das Bild aus, eine COG kümmert sich um die PS/2-Schnittstelle und ist Tastaturprozessor, eine COG arbeitet den in SPIN geschriebenen Kommandointerpreter ab usw.

Dieses Konzept ist schon ziemlich mutig in seinen großer Unterschieden zu klassischen Konzepten und das offenbart sich in einigen Eigentümlichkeiten:

  1. Interrupts: So gibt es im Propeller zum Beispiel keine Interrupts. Das hat schon viele sehr verwundert, da sie innerlich noch nicht wirklich das Konzept verstanden haben. Wozu brauche ich ein Interrupt? Wenn ich nur einen Prozessor zur Verfügung habe und dennoch auf zeitkritische Ereignisse reagieren will, muß ich eine Möglichkeit schaffen, wie ein linearer Programmfluss durch ein solchen Ereignis unterbrochen werden kann – halt durch ein Interrupt. Der eine Prozessor kümmert sich kurzzeitig um das Ereignis und setzt seine normale Arbeit danach fort. Aber wozu brauchen wir im Propeller ein Interrupt? Wenn es ein zeitkritisches Ereignis gibt, dann gib ihm doch auch eine eigene CPU die sich darum kümmert! Der Propellerchip hat dafür die Maschinencodebefehle „wait*“  zur Verfügung, um stabil innerhalb von 50 ns auf ein Ereignis zu reagieren.
  2. Peripheriefunktionen: Konsequent dem Konzept von universellen programmierbaren Einheiten (den COG’s) folgend, findet man im Propeller auch keine speziellen Baugruppen wie SPI-Interface, DAC oder SIO – alle diese Einheiten werden bei Bedarf durch Software in einer COG realisiert. Mit diesem Konzept ist man sehr flexibel. Dieser Umstand hat oft zu Verwirrungen geführt, wenn man von einem Controller anderer Bauart zum Propeller wechseln wollte – man muß halt einige Gewohnheiten über Bord werfen.
  3. Maschinencode: Ganz streng betrachtet wird der Maschinencode im Propellerchip nur aus dem CogRAM in jeder COG abgearbeitet. Maschinencode kann ohne weiteres nicht direkt im HubRAM ausgeführt werden, sondern muß immer in die COG übertragen werden, bevor der entsprechenden RISC-Prozessor ihn ausführen kann.  Mit einer kurzen Maschinencodesequenz (LMM) kann man aber auch das umgehen. An sich ist dieser Umstand auch in sich schlüssig, denn mit dem Mikrocode in der COG mache ich aus einer universellen Einheit einen ganz speziellen Prozessor. Ist dieser Prozessor Hardwarebezogen (Video) ersetzt er eine entsprechende Hardwareeinheit (Bildschirmsteuerung), ist der spezielle Prozessor aber mehr universell, so wird daraus halt ein Z80 (ZiCOG) oder ein 6502 (MoCOG), ein SPIN oder Forth-Prozessor usw.
  4. SPIN-Bootstrap: Der Propellerchip bootet in der Hochsprache SPIN. Beim Systemstart oder Reset wird also in die erste COG der SPIN-Tokenprozessor geladen und der SPIN-Code im HubRAM gestartet. Das ist in Hardware so realisiert und daran führt kein Weg vorbei. Aber man kann problemlos einen eigenen Bootloader in SPIN/Assembler schreiben, welcher die vollständige Kontrolle an den eigenen ???-Code übergibt.
  5. Ressourcenzugriff: Wenn mehrere Prozessoren parallel arbeiten, muß der Zugriff auf die verschiedenen Ressourcen geregelt sein. So haben die COG’s einige Ressourcen (CogRAM, Videoshifter, IO-Port) auf welche sie exklusiv und ohne Beeinflussung durch andere COG’s zugreifen können. Dabei ist die Geschwindigkeit maximal. Andere Ressourcen müssen sich alle COG’s untereinander teilen. Dazu gehört der HubRAM und der ROM.Um den Zugriff zu steuern kann jede COG nur über den Hub zugreifen, was natürlich die Geschwindigkeit verringert, je mehr Einheiten Zugriff verlangen.
  6. IO-Port: Alle 32 IO-Leitungen sind von jeder COG exklusiv zu erreichen, also mit maximaler Geschwindigkeit und ohne über einen Hub. Dabei sind die einzelnen Leitungen der COG’s mit Oder-Gattern verbunden. Im Normalfall wird man jeder COG ihre spezifischen Leitungen zuordnen, aber prinzipiell ist es möglich, dass auch zwei oder mehr COG’s Ausgaben auf den gleichen Leitungen machen. Das kann sinnvoll sein oder zum totalen Chaos führen – je nachdem ob der Programmierer shizophren genug ist, um den gleichzeitigen Zugriff selbst zu koordinieren.

Links zum Thema: