Programmieren für Fortgeschrittene - Assembler - Teil 1 - AZ-Delivery

Die Software für ihre bisherigen Mikroelektronik Projekte haben sie höchstwahrscheinlich in der Arduino IDE in der Programmiersprache C geschrieben. Die Befehle der Arduino IDE sind relativ intuitiv und einsteigerfreundlich.
Falls Sie sich schon einmal gefragt haben, wie der Mikrocontroller intern funktioniert, lernen Sie in dieser Blogreihe den Aufbau und die Assembler Sprache kennen. Diese ist eine low level Programmiersprache und somit deutlich Hardware näher als zum Beispiel C++.

Die Assembly Programmiersprache ist nicht nur nützlich, um die Funktionsweise der Prozessoren zu  verstehen, sondern bietet auch den Vorteil, dass nur minimal Speicher benötigt wird und die einzelnen Befehle deutlich schneller abgearbeitet werden können.

Deshalb findet die Assemblersprache auch noch heute Verwendung in Zeitkritischen Systemen oder wenn nur wenig Speicherplatz zur Verfügung steht, wie zum Beispiel in Compilern oder Embedded Systems.

 

Einführung

Die Assemblersprache wurde 1947 von der Britin Kathleen Booth entwickelt. In den 1980er Jahren wurde diese aufgrund leistungsstärkerer Rechnern weitgehend durch hohe Programmiersprachen wie C abgelöst.

In Assembler ist der Aufruf von direkten Prozessorbefehlen möglich, dies umfasst hauptsächlich das Schreiben und Lesen von Speicherregistern, Programmfluss Steuerung und auch logische und mathematische Operationen.

 

Das Problem dieser Programmiersprache ist aber, dass für die Programmierung vertiefte Kenntnisse wie zum Beispiel über den Speicheraufbau notwendig sind und die Befehle anfangs komplex wirken können.

Aufbau ATmega328P

 

Am Anfang des Adressraums befinden sich die 32 allgemeinen Register (R0 bis R31). Diese Register sind direkt zugänglich und werden für alle arithmetischen und logischen Operationen sowie für den Datentransfer verwendet.

Unmittelbar danach folgt der I/O-Registerbereich, der alle spezialisierten Steuer- und Statusregister enthält, mit denen Peripherieeinheiten (wie Ports, Timer, UART usw.) konfiguriert und kontrolliert werden.

 

Anschließend beginnt der SRAM-Bereich (Statischer RAM), der als Datenspeicher dient. In diesem Speicherbereich werden temporäre Variablen und der Stack abgelegt.

 

Der Flash-Speicher ist ein getrennter Speicherbereich, in dem unter anderem das Programm selbst gespeichert wird. Der ATmega328P verfügt über 32 Kilobyte Flash.

 

Daneben besitzt der ATmega328P auch 1 Kilobyte EEPROM, einen nichtflüchtigen Speicher, der separat adressiert ist.

 

Abbildung 1: Blockdiagramm Aufbau ATmega328P

Die Register R0 bis R31, welche in den Beispielen für arithmetische Operationen verwendet werden, befinden sich in der Grafik im "AVR CPU".

Zahlensysteme

Wir benutzen im Alltag Zahlen wie 180 oder 2380. Dabei handelt es sich um sogenannte Dezimalzahlen, was heißt, dass wir Potenzen der Zahl 10 verwenden.

Abbildung 2: Dezimalsystem

 

Dies hat unter anderem den Hintergrund, dass wir 10 Finger haben.

 

Binärsystem

Da der Speicher und alle Prozesse im Computer binär ablaufen, ist hierfür das geläufige Dezimalsystem nicht geeignet, da im Speicher nur zwei Zustände (Spannung bzw. keine Spannung) möglich sind. Hierfür wurde das Binärsystem entwickelt. Dieses arbeitet mit Vielfachen der Zahl 2.

Zum Beispiel:

Abbildung 3: Binärsystem

 

Die Programmschreibweise der Binärzahlen sieht wie folgt aus:
0b10110100

 

Hexadezimalsystem

Um auch komplexere Operationen verstehen zu können, ist die Kenntnis der verschiedenen Zahlensysteme wichtig. Neben dem Binär- und Dezimalsystem gibt es noch das Hexadezimal- und Oktal-System.

Wie am Namen schon zu erkennen ist, arbeiten das Oktalsystem mit 8er und das Hexadezimalsystem mit 16er Potenzen.

Das relevanteste ist das Hexadezimalsystem, wobei in diesem System Buchstaben für alle zweistelligen Zahlen verwendet werden. Das heißt A=10; B=11; … ; F=15

Abbildung 4: Hexadezimalsystem

 

Die Programmschreibweise der Hexadezimalzahlen sieht wie folgt aus:

0xB4

 

Dennoch bieten im Alltag Hilfsmittel wie ein Wissenschaftlicher Taschenrechner oder eine Umrechnungswebsite den Vorteil einer schnelleren Umrechnung von dem uns bekannten Dezimalsystem in die anderen Systeme.

 

16bit

Da der ATmega 328P ein 8 bit Prozessor ist, hat ein Speicher Register nur eine Länge von 8 bit, was einem Zahlenraum von 0-255 entspricht.
Dieser Zahlenraum ist nicht immer ausreichend. Wenn Sie zum Beispiel einen Pointer auf eine Speicheradresse speichern wollen, würde dies bereits zu Problemen führen, da die Adressen einer Länge von 16 bit entsprechen.

 

Um diese trotzdem speichern zu können, ist es möglich, die oberen beziehungsweise unteren 8 bit in zwei separate Registern zu speichern.

Somit kann eine Zahl

0000111111110000

auf die Register wie folgt aufgeteilt werden:

00001111 (high)

und

11110000 (low)

Programme

Software Tools Download:

Es werden zwei Software-Tools benötigt. Zum einen ein Assembler, um den Code in eine kompilierte Datei umzuwandeln und ein Programmer, um die kompilierte Hex- Datei auf das Board zu übertragen.

 

Assembler

Als Assembler empfiehlt sich die Software avra welche manuell auf ihrem Computer kompiliert werden muss.


Linux:

Unter Linux ist die Installation einfach, da die meisten Betriebssysteme, wie Ubuntu; Fedora; Manjaro, den make Befehl bereitstellen.

Erstellen Sie zuerst ein Abbild der Dateien des GitHub Repository auf Ihrem Computer. Hierfür können Sie den Git-Clone- Befehl benutzen.

cd Downloads

git clone https://github.com/Ro5bert/avra.git

Alternativ können Sie die Dateien auch direkt vom Github Repository herunterladen.

 

Nachdem sich die Dateien auf ihrem Computer befindet, wechseln Sie in den Ordner über das Terminal, wie folgt:

cd Downloads/avra

 

Führen Sie im Anschluss den Behl

make

 

aus.

Zuletzt muss die kompilierte Datei noch installiert werden. Hierfür kann einfach der

sudo make install

 

Befehl ausgeführt werden.

 

Jetzt ist die Kompiler Software erfolgreich auf ihrem Rechner installiert. Das weitere Vorgehen finden Sie im Abschnitt Anwendung

Windows:

Natürlich können Sie das Programm auch unter Windows installieren, hierfür muss aber wie auch unter Linux das Programm erst kompiliert werden. Hierfür wird die MS Visual Studio 2019 IDE empfohlen, welche in der Community Version kostenlos verfügbar ist.

Eine detaillierte Beschreibung der Schritte ist in einer Anleitung auf dem GitHub Repository verfügbar.

 

AVRDUDE

Für das Übertragen der kompilierten Dateien auf den Mikrocontroller eignet sich die Software AVRDUDE.
Diese wird normalerweise mit der Arduino IDE bereits installiert, da diese die Software ebenfalls zur Datenübertragung benutzt.

 

Sollten Sie die Software trotzdem selbst installieren wollen, ist dies natürlich auch möglich.

Linux

Führen Sie folgenden Befehl im Terminal aus:
sudo apt-get install avrdude

 

Windows

Im GitHub repository können Sie die aktuelle Software für Ihren Prozessor herunterladen.

Anwendung

Nach erfolgreicher Installation können Sie mit einem Texteditor oder Code Editor eine Datei mit Dateiendung .asm erstellen. Zum kompilieren führen Sie im Terminal folgenden Befehl im Verzeichnis der Datei aus:
avra Programmname.asm

 

Nun wurde ein Programmname.hex Datei erzeugt. Diese Binärdatei kann nun auf das Board geladen werden.

Dies kann mit folgendem Befehl ausgeführt werden:

avrdude -c arduino -p m328p -P <Port> -b 115200 -U flash:w:"Path/File.hex":a

 

Passen Sie hier den Seriellen Port und den Dateipfad entsprechend an.
Den Seriellen Port können Sie entweder in Windows im Gerätemanager ermitteln und unter Linux mit dmesg | grep tty oder alternativ in der Arduino IDE.

 

Alternativ können Sie hierfür auch die grafische Benutzeroberfläche AVRDUDESS benutzen. Diese verwendet denselben Befehl wie die Kommandozeilenversion, aber die Konfiguration und Auswahl der Parameter ist deutlich intuitiver und dadurch auch angenehmer.

Abbildung 5: Grafische Benutzeroberfläche AVRDUDESS

Fazit

Nachdem in diesem Blogbeitrag die ersten Grundlagen geschaffen wurden, geht es im nächsten Teil um die Anwendung in einem kurzen Beispielprojekt.

 

Viel Spass beim Nachbauen :)

 

Referenzen der Blog Reihe:

https://de.wikipedia.org/wiki/Assemblersprache

https://www.instructables.com/Command-Line-AVR-Tutorials/

Projekte für fortgeschrittene

2 comentarios

Leopold Gann

Leopold Gann

Bezugnehmend auf ihr Umrechnungsbeispiel binär/dezimal – 10110100=180 ist zwar richtig, aber die 2er-Potenzen sind jedoch verkehrt rum angegeben …

Roman

Roman

Vielen Dank für diesen anschaulichen Einstieg in die Assembler‑Programmierung mit dem ATmega328P.

Ich freue mich sehr auf die nächsten Teile des Kurses!

Eine kleine Rückmeldung zum Blockdiagramm:
Beim ersten Lesen war ich irritiert, weil ich die 32 allgemeinen Register (R0–R31) und den I/O‑Registerbereich nicht direkt im Bild verortet habe. Mir wurde erst später klar, dass beide Registerarten fest im AVR‑CPU‑Block stecken und deshalb nicht als eigene Kästchen auftauchen. Vielleicht hilft künftigen Leserinnen und Lesern ein kurzer Hinweis im Text (oder eine kleine Markierung im Diagramm), dass das Register‑File und der I/O‑Registerraum „im Inneren“ der CPU bzw. entlang des Datenbusses liegen.

Ansonsten gefällt mir der Kurs bislang sehr gut – weiter so!

Deja un comentario

Todos los comentarios son moderados antes de ser publicados