Mikrocomputertechnik Thema: Embedded Softwareentwicklung Maschinensprache & Opcode Ein Programm für einen Prozessor besteht aus sequenziellen Folgen binärer Bitmuster, den sogenannten Maschinenbefehlen. Alle Maschinenbefehle zusammen ergeben die Maschinensprache des Prozessors. Der Maschinenbefehl ist vom Prozessor direkt ausführbar, d.h. er muss zuvor nicht übersetzt werden. Maschinensprache ist für den Menschen kaum bzw. nur schwer lesbar. Der Maschinencode wird von einem Assembler oder einem Compiler erzeugt. Beim 8051 besitzen die Befehle eine Breite von 8-Bit. Somit sind bis zu 256 Befehle (Bit-Kombinationen) möglich. Der Befehl wird aus dem Programmspeicher über den Datenbus direkt in den Befehlsdekodierer des Prozessors geladen, der daraufhin bestimmte Aktionen ausführt. Mit Hilfe des Hexadezimalsystems kann man den Maschinencode etwas lesbarer gestalten. Folie 2 30.03.2012, Dipl.-Ing.(FH) Ralf Hanke, E-Mail: [email protected] Maschinensprache & Opcode Ein Befehl setzt sich aus mehreren Teilen zusammen: Opcode (Operation Code): Er beschreibt die Art des Befehls (was ist zu tun) Optionale Datenbytes: Benötigt der auszuführende Befehl zusätzliche Daten, werden diese an den Opcode hinten angehängt. Ein Maschinenbefehl kann folglich aus einem oder auch mehreren Bytes bestehen. Folie 3 30.03.2012, Dipl.-Ing.(FH) Ralf Hanke, E-Mail: [email protected] Assemblersprache Die Assemblersprache repräsentiert die Maschinenbefehle in einer für den Menschen lesbaren Form. Die Opcodes des Prozessors werden mithilfe sogenannter Mnemonics dargestellt. Mnemonics sind kurze Buchstabenkombinationen, die den jeweiligen Befehl beschreiben. Beispiel: MOV A, #13 74 OD 01110100 00001101 Assemblerbefehl (2 Byte) lade Akku mit Konstante 13 Maschinenbefehl hex. (Opcode=74h, Operand=13) Maschinenbefehl bin. Heutzutage werden Mikrocontroller meist in Hochsprachen wie C programmiert. Assembler findet jedoch noch immer Einsatz bei der Programmierung zeitkritischer Aufgaben oder bei Projekten bei denen der Programmcode möglichst schlank gehalten werden muss. Folie 4 30.03.2012, Dipl.-Ing.(FH) Ralf Hanke, E-Mail: [email protected] Quelltext ↔ Programmierdaten Beispiel: LED_CTRL.ASM. Nachfolgende Tabelle zeigt die Programmierdaten im Intel Hex Format. Der untere Abschnitt zeigt einen Teil der zugehörigen Assembler-Befehle. Start Code Anz. Bytes Adr Typ : 02 0000 00 21 00 * DD : 10 0100 00 D2 B2 30 91 05 30 92 06 80 F8 C2 B2 80 F4 D2 B2 F9 : 02 0110 00 80 F0 7D : 00 0000 01 Folie 5 Datenfeld Compiler generiert aus jmp-Befehl 30.03.2012, Dipl.-Ing.(FH) Ralf Hanke, E-Mail:*[email protected] Chk FF einen ajmp-Befehl Der Befehlssatz des 8051 Alle Derivate der 8051-Familie besitzen die gleichen Maschinenbefehle und somit den gleichen Befehlssatz. Besonderheit beim 8051-Befehlssatz: Bei Befehlen mit Quell- und Zielangabe wird immer erst das Ziel und danach die Quelle angeführt. Opcode Ziel Quelle Die Befehle können z.B. nach der Art ihrer Funktion gegliedert werden in… Transportbefehle, Arithmetische und logische Befehle, Sprungbefehle und Befehle für Unterprogramme. Folie 6 30.03.2012, Dipl.-Ing.(FH) Ralf Hanke, E-Mail: [email protected] Der Befehlssatz des 8051 Erklärungen zum Dokument Befehlssatz_8051.pdf Anhand des Befehls „mov A, Rr“, sollen die Tabellenspalten im Dokument Befehlssatz_8051.pdf erläutert werden. Mnemonic: Enthält den für den Menschen lesbaren Maschinenbefehl als Mnemonic Buchstabenkürzel. Register: Welche Register werden verwendet bzw. können verwendet werden. Im Beispiel r=0-7 bedeutet dies, dass die Register R0-R7 verwendet werden können. Incoding Binary: Binärcodierter Maschinenbefehl. Im Beispiel 11101rrr repräsentiert der Buchstabe r die Bits, mit denen die Registernummer codiert wird. R3 würde somit den Code 11101011 ergeben. Folie 7 30.03.2012, Dipl.-Ing.(FH) Ralf Hanke, E-Mail: [email protected] Der Befehlssatz des 8051 Incoding HEX: Maschinencode im hexadezimalen Format. Auch hier steht r für die noch zu addierende Registernummer. Im Beispiel E8+r und R4 würde sich somit der Code EC ergeben. Affectet Flags: Gibt an, welche Flags des Statusregisters von dem Befehl beeinflusst werden. Im Beispiel wird das Parity-Flag P als beeinflußtes Flag aufgeführt. Bytes: Gibt die länge des Befehls in Bytes an. Im Beispiel handelt es sich um eine 1-ByteBefehl. Cycles: Gibt an, wie viele Maschinenzyklen notwendig sind, um den Befehl auszuführen. Der Befehl im obigen Beispiel benötigt zwei Maschinenzyklen. Folie 8 30.03.2012, Dipl.-Ing.(FH) Ralf Hanke, E-Mail: [email protected] Der Befehlssatz des 8051 Function: Englische Beschreibung des Befehls. Funkionsbeschreibung: Deutsche Beschreibung des Befehls. Folie 9 30.03.2012, Dipl.-Ing.(FH) Ralf Hanke, E-Mail: [email protected] Programmierung in Hochsprachen Zu den sogenannten Hochsprachen zählen beispielsweise Programmiersprachen wie C / C++ oder Pascal. Hochsprachen enthalten abstrakte Elemente wie z.B. bedingte Anweisungen (if, else) oder Schleifen (for, while, …etc.). Hierdurch kann mittels „weniger“ Programmcode mehr Logik umgesetzt werden. Hochsprachen bieten außerdem die Möglichkeit ein Programm in mehrere Unterprogramme zu unterteilen (Prozeduren, Modularisierung). Hierdurch kann ein Programm von mehreren Entwicklern gleichzeitige bearbeitet werden. Im Vorfeld müssen lediglich die Schnittstellen zwischen den einzelnen Prozeduren bzw. Modulen beschrieben werden. Welche Vorteile gibt es noch in Bezug auf die Programmierung in Assembler? Zeitlich schnellere Programmerstellung Leichtere Lesbarkeit des Quelltextes Quelltexte sind auf andere Zielplattformen (andere Prozessoren mit anderem Befehlssatz) portierbar Es existieren Kontroll- (if, else, for, while, … etc.) und Datenstrukturen (Array, Structs, … etc.) Folie 10 30.03.2012, Dipl.-Ing.(FH) Ralf Hanke, E-Mail: [email protected] Programmierung in Hochsprachen Aber es gibt auch einige Nachteile in Bezug auf die Programmierung mit Assembler. Größerer Speicherplatzbedarf für den Programmcode Ggf. langsamere Programmabarbeitung Zeitkritische Vorgänge können nicht kontrolliert beschrieben werden (was steckt z.B. hinter einer for-Schleife?) I.d.R. werden heute größere SW-Projekte in Hochsprachen programmiert. Viele Hochsprachen-Compiler bieten die Möglichkeit Assemblerquellcode direkt in die Hochsprache einzuarbeiten („Inline Assembler“), wodurch z.B. zeitkritische Teilaufgaben in Assembler gelöst werden können. Folie 11 30.03.2012, Dipl.-Ing.(FH) Ralf Hanke, E-Mail: [email protected] Cross-Compiler & Linker Compiler (allgemein) Der Compiler übersetzt ein in einer Programmiersprache geschriebenes Programm in eine bestimmte Zielsprache. Die Zielsprache ist oftmals Assemblercode oder Maschinensprache. Handelt es sich bei der Programmiersprache um Assemblersprache und bei der Zielsprache um Maschinensprache, wird der Compiler auch „Assembler“ genannt. Der Kompiliervorgang kann in mehrere Phasen gegliedert werden. Teilphasen können z.B. sein: Analyse des Quellcodes Zwischencode-Erzeugung Optimierung Code-Erzeugung Nach dem Kompiliervorgang liegt das Programm als Objekt-Code vor. Es kann sich hierbei auch um mehrere Objektdateien handeln (für jedes Modul eine separate Datei). Folie 12 30.03.2012, Dipl.-Ing.(FH) Ralf Hanke, E-Mail: [email protected] Cross-Compiler & Linker Der Cross-Compiler Wird ein Compiler auf einer bestimmten Hostplattform ausgeführt, erzeugt jedoch Code für eine andere Plattform, so spricht man von einem CrossCompiler. Compiler für Mikrocontrollersysteme sind daher oftmals Cross-Compiler. Der Linker Der Linker ist ein Programm, welches die vom Compiler erzeugten Objektdateien zu einem lauffähigen Programm verbindet. Wurden innerhalb der Programmierung Bibliotheken verwendet, werden auch diese mit eingebunden. Der Linker übernimmt überdies die Umwandlung symbolischer Adressen von Funktionen und Variablen in reelle Speicheradressen. Folie 13 30.03.2012, Dipl.-Ing.(FH) Ralf Hanke, E-Mail: [email protected] Debugger Ein Debugger ist ein Tool, mit welchem ein Programm schrittweise nachverfolgt werden kann. Es dient zur Auffindung von Fehlern in Soft- und Hardware. Der Entwickler kann das Programm in Einzelschritten nachverfolgen (SingleStep). Es ist möglich das Programm mit sogenannten Breakpoints (Haltepunkten) an bestimmten Codestellen anzuhalten. Debugger bieten die Möglichkeit Registerinhalte und Variableninhalte einzusehen und zu verändern (Watch-Funktion). Einige wenige Debugger bieten auch die Möglichkeit des Tracings an. Hierbei können Daten für eine spätere Auswertung über einen bestimmten Zeitraum aufgezeichnet werden. Debugger sind meist ein Bestandteil von Entwicklungsumgebungen (z.B. Keil µVision, Microsoft Visual Studio, etc.) oder können dort eingebunden werden (z.B. GDB). Folie 14 30.03.2012, Dipl.-Ing.(FH) Ralf Hanke, E-Mail: [email protected] In-Circuit-Emulator In-Ciruit-Emulatoren (ICE) werden bei der Entwicklung von komplexeren und / oder extrem zeitkritischen Systemen eingesetzt. Ein Emulator ermöglicht die vollständige Beobachtung des Verhaltens von einem Prozessor auf der Zielhardware ohne Beeinträchtigung des Zeitablaufs (das Testprogramm läuft in Echtzeit ab). Bei ICEen wird der eigentliche Prozessor von der Zielhardware entfernt und durch einen Adapter (Pod) ersetzt. Dieser Adapter verbindet die Schaltung mit dem Emulator. Ausgewählte Signale (Adressen, Daten, Steuersignale) können während der Emulation „abgegriffen“ und ihr zeitlicher Verlauf in einem sogenannten TraceSpeicher für die nachfolgende Analyse aufgezeichnet werden. Folie 15 30.03.2012, Dipl.-Ing.(FH) Ralf Hanke, E-Mail: [email protected] In-System-Debugger Werden auch In-System-Programmer (ISP) genannt. ISP bieten nicht die Kontrolltiefe über den Prozessor wie ICE. Es fehlen meist Trace-Speicher und auch zeitkritische Probleme lassen sich mit ISP nur bedingt analysieren. ISP sind im Verhältnis zu ICE sehr viel günstiger. ICE liegen preislich meist zwischen 5000 - 20000 Euro. ISP erhält man stattdessen bereits unter 100 Euro. Bei ISPn befindet sich auf dem Zielprozessor eine On-Chip-Debug-Einheit. Diese übernimmt den Datentransfer zum Hostrechner sowie den Zugriff auf Speicher und Register des Zielsystem. Außerdem steuert sie den Programmablauf (Start, Stop, Breakpoints, etc.). Als HW-Schnittstelle wird heutzutage vermehrt die genormte JTAG-Schnittstelle oder die von Freescale entwickelte BDM-Schnittstelle eingesetzt. Folie 16 30.03.2012, Dipl.-Ing.(FH) Ralf Hanke, E-Mail: [email protected]