Programmieren von Mikrocontrollern in ASM oder C & wie es gemacht wird

Nur zur Klärung dieser Themen:

Wenn ich einen Mikrocontroller in ASM programmieren würde, würde ich natürlich einen Assembler verwenden. Der Assembler würde den Code in Opcodes (Maschinencode?) (im Allgemeinen 1: 1-Verhältnis) kompilieren, die dann in eine HEX-Datei konvertiert würden. Ist es diese Datei, die tatsächlich in den Speicher eingelesen und zum Programmieren des Controllers verwendet wird? Ich habe gelesen, dass die HEX-Datei den tatsächlichen Ort enthält, an dem die Daten (Teil dieses Datenrahmens) im Speicher gespeichert werden sollen, sowie die Daten, die dort geschrieben werden sollen.

Wenn ich einen Mikrocontroller in C (oder einer anderen Sprache) programmiere, was sind die Einschränkungen? Es wäre natürlich notwendig, dass Sie einen C-Compiler verwenden. Aber müssen wir einen C-Compiler verwenden, der speziell für die Arbeit mit Mikrocontrollern oder einer bestimmten Architektur entwickelt wurde?

Ich weiß, dass verschiedene Architekturen unterschiedliche Befehlssätze haben, die mit anderen nicht kompatibel sind, aber wie wird damit umgegangen und wie bezieht sich all dies auf eine CPU, die in einem Computer vorhanden ist?

Ich habe hier sicherlich Themen verwechselt und mich möglicherweise in Verlegenheit gebracht, aber ich habe heute eine Weile in diesen Themen gelesen und wollte alles auf einen Blick klären, um weitere Verwirrung zu mildern.

Danke schön,

Antworten (2)

Ein Compiler kann (für den Zweck Ihrer Frage) in zwei Teile geteilt werden:

  • Der erste Teil liest Ihren Code, analysiert und prüft ihn auf Fehler und macht damit alle möglichen schlauen Sachen, die nichts mit dem Zielrechner zu tun haben

  • Der zweite Teil nimmt die Ausgabe des ersten Teils und übersetzt sie in eine Folge von Maschinenanweisungen (entweder in Textform oder in Binärform oder beides).

Der zweite Teil ist spezifisch für die CPU, auf der Ihr Programm laufen soll. Wenn Sie auf einem PIC 16F laufen möchten, müssen Sie über einen Compiler verfügen, der Maschinenanweisungen für diesen bestimmten Chip generiert, und häufig muss der Compiler den genauen Chip kennen, für den Sie kompilieren.

Für eine AVR-, ARM-, Cortex-, MIPs- usw. CPU benötigen Sie einen anderen Compiler. Es gibt Compiler, die den zweiten Teil (das Backend) für mehr als ein Ziel enthalten. In diesem Fall müssen Sie irgendwie angeben, welches der Backends verwendet werden soll.

Wenn ich einen Mikrocontroller in ASM programmieren würde, würde ich natürlich einen Assembler verwenden. Der Assembler würde den Code in Opcodes (Maschinencode?) (im Allgemeinen 1: 1-Verhältnis) kompilieren, die dann in eine HEX-Datei konvertiert würden.

Hängt vom jeweiligen Assembler ab. Am gasBeispiel, nein. Es erstellt eine ELF- Datei aus der Quelle und objcopywird dann verwendet, um die relevanten ELF-Abschnitte in HEX-Dateien zu extrahieren.

Ist es diese Datei, die tatsächlich in den Speicher eingelesen und zum Programmieren des Controllers verwendet wird?

Und dieser hängt vom Programmierer ab. Das genaue Dateiformat, das erforderlich oder möglich ist, variiert von Programmierer zu Programmierer.

Ich habe gelesen, dass die HEX-Datei den tatsächlichen Ort enthält, an dem die Daten (Teil dieses Datenrahmens) im Speicher gespeichert werden sollen, sowie die Daten, die dort geschrieben werden sollen.

Richtig.

Wenn ich einen Mikrocontroller in C (oder einer anderen Sprache) programmiere, was sind die Einschränkungen?

C erfordert die Verfügbarkeit eines Stacks, der SRAM auf dem Zielgerät erfordert, aber wenn das Gerät über genügend Register verfügt und leistungsfähig genug ist, ist es möglich, den C-Compiler so zu gestalten, dass er die Register als Ersatz für das im Stack verwendete SRAM verwendet .

Es wäre natürlich notwendig, dass Sie einen C-Compiler verwenden. Aber müssen wir einen C-Compiler verwenden, der speziell für die Arbeit mit Mikrocontrollern oder einer bestimmten Architektur entwickelt wurde?

Der Compiler muss in der Lage sein, für die Zielarchitektur spezifischen Maschinencode (oder Assemblercode, falls eine Weiterverarbeitung durch einen Assembler erlaubt/erforderlich ist) zu generieren. Außerdem können Geräte innerhalb derselben Architektur Unterschiede voneinander aufweisen, und der Compiler kann möglicherweise angewiesen werden, diese Unterschiede entweder auszunutzen oder zu ignorieren. Beispielsweise haben einige AVR-Geräte Hardware-Multiplikatoren, aber es ist nicht erforderlich, dass der C-Compiler sie verwendet, was die binäre Portabilität zwischen AVR-Geräten erhöht.

Sind alle verfügbaren Register (32 für mindestens den Atmega32) für den Programmierer verfügbar? Oder werden einige der Register ausschließlich von der CPU verwendet? Ich nehme an, Sie müssten den verwendeten Controller und den verwendeten Compiler kennen, da seltsame Dinge passieren würden, wenn Sie die Register zur Emulation eines Stapels verwenden und versuchen, sie selbst dynamisch zu steuern.
Ich wusste nicht, dass C die Verwendung eines Stapels erfordert. Ich dachte, es sei nur so, dass der C-Standard ein automatisches Speicherzuweisungssystem (normalerweise ein Stack) zusammen mit einem dynamischen Speicherzuweisungssystem (Heap) erfordert - aber die Implementierungen waren variabel.
@sherrellbc: Der Compiler definiert die Registerverfügbarkeit ( avr-gcc , IAR ).
@sherrellbc - Sie haben Recht. Der zielspezifische Compiler wird um die Beschaffenheit und die Fähigkeiten des betreffenden Mikrocontrollers herum entworfen. Wenn die Architektur einen Stack effizient unterstützt, wird der Compiler ihn höchstwahrscheinlich auf herkömmliche Weise verwenden. Es gibt auch einige nicht so freundliche Architekturen. Nehmen Sie zum Beispiel 8051. Die Verwendung des Stapels für Daten ist ziemlich ineffizient, sodass der Keil C51-Compiler den Stapel für Aufrufe und Rückgaben verwendet, aber Datenvariablen aus einem Speicherpool zuordnet, in dem sie ein Modell wie normale globale Variablen haben.
@sherrellbc: "Sind alle verfügbaren Register (32 für mindestens den Atmega32) für den Programmierer verfügbar?" Nein, in C verwenden Sie überhaupt keine Register. Sie schreiben einen High-Level-Code, in dem Sie Variablen verwenden, und der Compiler weist Register und Speicher für diese Variablen zu. Der Compiler weiß, welche Register wofür verwendet werden können, und es ist die Optimierungsphase während der Kompilierung, wenn der Compiler die Entscheidungen über die Zuordnung trifft. Wie gut der Compiler darin ist, hat einen enormen Einfluss auf den resultierenden Code.
Sie können jedoch versuchen, den Compiler zu zwingen, bestimmte Register für Variablen zu verwenden. Verwenden Sie jedoch nicht zu viele, oder Ihr Code wird möglicherweise nicht kompiliert.