text: In diesem Artikel geht es darum, eine LED zu aktivieren und sie blinken zu lassen. Für ein besseres Verständnis ist es ratsam das BCM2835 Peripherie Datenblatt zur Hand zu haben, da für die Lösung der Aufgabenstellung einige Registeradressen benötigt werden.
  Es kann außerdem nicht schaden, wenn ihr zusätzlich das ARM Befehlsdatenblatt offen habt. In diesem Dokument sind alle verfügbaren ARM Befehlscodes vermerkt.
  Für die spätere Kompilierung wird ein Makefile benötigt, welches der Cross Compiler verwendet. Alle benötigten Dateien sind in diesem Ordnertemplate zu finden. Das Template kann heruntergeladen und als Ausgangsverzeichnis verwendet werden.
  In diesem Ordner findet ist ein Verzeichnis mit dem Namen source zu finden. Hier werden alle Assemblerdateien abgelegt und der Inhalt dieses Verzeichnisses wird dann während des Compilierens durch das Tool make des abgearbeitet und zu einem Kernelimage gelinkt.
  Diese Datei kann z. B. mit Programmer´s Notepad geöffnet werden. Wirklich wichtig sind für uns nur die ersten paar Punkte, da ich (noch) nicht so tief in den Aufbau eines Make-Files einsteigen will:
  Der erste Punkt gibt den verwendeten Compiler an. In diesem Fall ist es der Compiler arm-none-eabi für eine sogenannte bare metall Programmierung. Als bare Metall Programmierung wird das Programmieren ohne Betriebssystem bezeichnet. Man startet ohne jegliche Software und Schnittstellen und baut sich alles selber zusammen.
  Der zweite und der dritte Punkt gibt das Verzeichnis für die kompilierten Objekte bzw. Sourcefiles an. Dabei wird das Verzeichnis des Makefiles als Ausgangspunkt verwendet.
  Im vierten Punkt legt man den Namen des erzeugen Kernelimages fest. Der Name muss immer kernel.img heißen!
  Die nächsten beiden Punkte geben die Dateinamen des Listingfiles und des Mapfiles an und interessieren uns nicht wirklich.
  Und der letzte Punkt gibt den verwendeten Linker an. Der Linker sorgt dafür, dass alle verwendeten Programmteile zu einem ausführbaren Programm zusammen gesetzt werden.
  Für das erste Programm wird im Programmer´s Notepad eine neue Assemblerdatei angelegt und als main.s gespeichert. Ziel ist es, dass wir eine LED an GPIO 24 aktivieren.
  Dazu wird das Datenblatt der BCM2835 Peripherie zu benötigt. Auf S. 89 beginnt die Sektion über die GPIO, die für die Ansteuerung der GPIO benötigt wird und auf S. 90 befindet sich die Registerübersicht. Zu allererst wird der GPIO über die Register GPFSELn als Ausgang konfiguriert. Wenn man das Datenblatt etwas weiter liest, sieht man ab S. 92 das die GPIO unterteilt sind. Register 0 deckt die GPIO 0 – 9 ab, Register 1 die GPIO 10 – 19, usw.
  Da der GPIO 24 angesteuert werden soll wird das Register GPFSEL2 benötigt. Ok, also wieder zurück scrollen auf die S. 90 für die Registerübersicht. Dort lässt sich entnehmen, dass das Register GPFSEL2 bei der Adresse 0x20000008 anfängt. Das Datenblatt zeigt eine genaue Auflistung der Unterteilung des Registers für GPIO 24. Um den GPIO 24 als Ausgang zu deklarieren, muss also in den Bereich FSEL24 der Wert 0x01 stehen.
  Nachdem der GPIO als Ausgang deklariert wurde, kann der Ausgang über das GPSETn-Register gesetzt werden. In diesem Register repräsentiert jedes Bit für einen einzelnen I/O.
  Das Thema Registeradressen ist leider etwas komplizierter. In der Registerübersicht des GPIO-Controllers steht, dass die Startadresse des GPIO-Controllers bei 0x7E200000 liegt. Bei dieser Adresse handelt es sich um eine virtuelle Speicheradresse, die üblicherweise von einem Betriebssystem genutzt und durch eine MMU auf eine physische Adresse gemappt wird. Ohne Betriebssystem ist man an die physikalischen Adressen des Chips gebunden. Eine Übersicht dazu findet sich auf S. 5 des Peripheriedatenblattes:
  Da keine MMU genutzt wird, gelten die Adressen aus dem mittleren Adressbereich. Daraus ergibt sich die Adresse 0x20200000 und nicht 0x7E200000 für den GPIO-Controller (das 7E wird mit 20 ersetzt). Nun sind aber alle Komponenten vorhanden. Zeit um aus diesen Erkenntnissen Code zu generieren…
  Die ersten drei Zeilen müssen immer gleich bleiben. Sie dienen quasi als Einstigspunkt für den Prozessor:
  Im nächsten Schritt wird die Basisadresse bzw. die Anfangsadresse des GPIO Controllers im Register r0 gespeichert. Diese lautet 0x20200000 und ist in der Tabelle auf S. 90 zu finden (das Umrechnen der Adresse nicht vergessen!).
  Dieser Befehl kopiert den Wert von Register r1 zu der in Register r0 und um den Wert 8 erhöhte Adresse.
  Der nächste Schritt besteht darin, den Ausgang auf High zu setzen. Der Chip verfügt für diesen Fall über ein GPIO Pin Output Set Register (GPSETn). Jedes Register deckt bis zu 32 GPIO ab, wobei jedes Bit für den jeweiligen GPIO steht (Register 0 Bit 0 → GPIO 0, Register 0 Bit 1 → GPIO 1, etc.).
  Es muss jetzt allerdings der Adressoffset auf 28 und die Anzahl der zu schiebenden Stellen auf 24 angepasst werden. Als letztes wird noch eine Endlosschleife eingefügt, damit der Prozessor was zu tun hat:
  Die Datei wird nun als main.s im source-Verzeichnis des Verzeichnistemplates abgespeichert. Der Kompiliervorgang kann nun über die Konsole und dem Befehl make gestartet werden:
  Wenn der Kompiliervorgang erfolgreich beendet wurde, ist in dem Verzeichnis eine Datei namens kernel.img zu finden. Alles was jetzt noch benötigt wird ist eine SD-Karte mit einem bereits installierten Betriebssystem. Auf dieser SD-Karte wird die vorhandene Datei kernel.img durch die von euch erzeugte Datei kernel.img ersetzt.
  Nun kann der Raspberry Pi eingeschaltet werden und kurz nach dem Einschalten leuchtet die LED an GPIO 24 auf.
  Im nächsten Schritt soll die LED blinken. Dazu wird das erstellte Programm geringfügig abgeändert und die Endlosschleife erweitert:
  Die neue Endlosschleife besteht aus einem Verzögerungsblock, wo der Wert 0x3F0000 in das Register r2 geladen und dann in einer Schleife so lange um 1 reduziert wird, bis der Wert 0x00 erreicht wird:
  Sobald die Schleife durchgelaufen ist, wird die LED entweder an oder aus geschaltet. Es resultiert eine Blinkfrequenz von (etwa) 2 Hz.
  leider werde ich aus dieser fehlermeldung auch nicht schlau, da hier irgendwie garnicht angegeben ist, welche datei denn nun fehlt….
  Danach öffnest du die Konsole, wechselst in das Verzeichnis und gibst “make” ein (musst den build-Ordner vorher aber löschen).
  vielen Dank für die wirklich schnelle Antwort und entschuldige bitte, dass ich schon wieder störe. Aller Anfang ist schwer. Beim Compiilieren erhalte ich folgende Fehlermeldungen:
  Ich habe die 3 Tools mehrmals neu installiert und habe dabei nie eine Fehlermeldung erhalten. Was habe ich falsch gemacht? Im Ordner ASM liegen 3 Dateien und der Ordner source mit der Datei main.s .
  make – version wird beantwortet mit “Incorrect command line argument: – version” und ca. 20 Optionen zur Syntax.