Ich habe kürzlich angefangen, Assembler zu lernen, und habe etwas über Linkerskripte und andere grundlegende Details der Hardware-Programmierung gelernt. Ich unterrichte mich auch selbst in Computerarchitektur, und irgendwann fürchtete ich, dass mein Bild vom Speichermodell die ganze Zeit falsch gewesen sein könnte.
Nach meinem derzeitigen Kenntnisstand befinden sich der gesamte Code und die gesamten Daten im nichtflüchtigen Speicher, unmittelbar nachdem wir die Binärdatei auf einen Prozessor "gebrannt" haben - der flüchtige RAM enthält beim Zurücksetzen nichts. Wenn das Programm mit der Ausführung beginnt, geschieht dies ab der Adresse 0x0000, die fast immer (AFAIK) die niedrigste Adresse in Flash ist. Anweisungen werden also auf dem Bus zwischen Flash und CPU-Kern zwischengespeichert, und dort findet die eigentliche Ausführung statt. Wenn wir jedoch davon sprechen, dass die CPU Daten aus dem Speicher abruft oder speichert, sprechen wir normalerweise von RAM. Mir ist bewusst, dass wir auch Daten aus dem Programmspeicher lesen / schreiben können (ich habe dies bei AVRs gesehen). aber ist es nicht so häufig? Liegt es daran, dass RAM schneller als ROM ist, dass wir Daten dort speichern möchten?
Die akzeptierte Antwort auf diese Frage besagt, dass die meisten Codeteile im RAM ausgeführt werden.
Bedeutet dies, dass der Start-Runtime-Code (der selbst von Flash ausgeführt wird) alle Programm-Opcodes von Flash in den Arbeitsspeicher kopieren muss und die Adressen in Flash irgendwie so zuordnet, dass sie auf den Arbeitsspeicher verweisen, sodass die CPU von dort Opcodes abruft? Entspricht es dem Vorgang, bei dem die .data-Abschnitte beim Start vom ROM in den RAM verschoben werden?
Ich kann mir vorstellen, dass dies in von Neumann-Architekturen einfacher ist, in denen sich Programm- und Datenspeicher einen Bus teilen. Aber in Harvard-Architekturen bedeutet dies nicht, dass der gesamte Code und die gesamten Daten zuerst die CPU-Register passieren müssen.
Wie Sie wahrscheinlich erraten können, bin ich ein bisschen zu verwirrt von dieser ganzen Angelegenheit. Ich habe immer auf einer höheren Abstraktionsebene programmiert und bin leicht mit solchen Details konfrontiert. Jede Hilfe wird geschätzt.
quelle
Antworten:
Dies hängt vom Gerät ab.
RAM kann schneller als Flash erstellt werden; Dies beginnt im Bereich von etwa 100 MHz wichtig zu werden.
Einfache Mikrocontroller
Kleine langsame Mikrocontroller werden direkt aus Flash ausgeführt. Diese Systeme haben normalerweise auch mehr Flash als SRAM.
Midrange-Systeme
Sobald Ihr Gerät schneller wird, sieht die Situation etwas anders aus. Midrange-ARM-Systeme können dies ebenfalls tun, oder sie verfügen über einen Masken-ROM-Bootloader, der intelligentere Funktionen bietet: Möglicherweise wird Code von USB- oder externen EEPROMs in den internen SRAM heruntergeladen.
Große Systeme
Größere, schnellere Systeme verfügen über externen DRAM und externen Flash. Dies ist typisch für eine Mobiltelefonarchitektur. Zu diesem Zeitpunkt ist genügend RAM verfügbar und es ist schneller als das Flash, sodass der Bootloader es kopieren und ausführen wird. Dies kann beinhalten, dass es durch die CPU-Register geschaufelt wird, oder es kann eine DMA-Übertragung beinhalten, wenn eine DMA-Einheit verfügbar ist.
Harvard-Architekturen sind normalerweise klein, also kümmern Sie sich nicht um die Kopierphase. Ich habe einen ARM mit "Hybrid Harvard" gesehen, bei dem es sich um einen einzelnen Adressraum handelt, der verschiedene Speicher, aber zwei verschiedene Abrufeinheiten enthält. Code und Daten können parallel abgerufen werden, sofern sie nicht aus demselben Speicher stammen. Sie können also Code aus Flash und Daten aus SRAM oder Code aus SRAM und Daten aus DRAM usw. abrufen.
quelle
RAM ist im Allgemeinen schneller als Flash, aber es spielt keine Rolle, bis Sie Taktraten von über 80-100 MHz erreichen. Solange die Flash-Zugriffszeit kürzer ist als die Zeit, die zum Ausführen eines Befehls erforderlich ist sollte keine Rolle spielen.
Die physische Konstruktion des RAM ermöglicht es uns, sehr schnelle Geräte zu bauen. viel schneller als der Blitz. An dieser Stelle ist es sinnvoll, Codeblöcke vor der Ausführung in den Arbeitsspeicher zu kopieren. Dies bringt dem Entwickler auch zusätzliche Vorteile, z. B. die Möglichkeit, den Code zur Laufzeit zu ändern.
Nicht unbedingt. Hier wird virtuell Adressierung ins Spiel. Anstelle von Programmcode, der sich auf die RAM-Rohadressen der Hardware bezieht, wird tatsächlich ein virtueller Adressraum referenziert. Blöcke des virtuellen Adressraums werden physischen Speichergeräten zugeordnet, die RAM, ROM, Flash oder sogar Gerätepuffer sein können.
Wenn Sie beispielsweise auf einem Mikro auf die Adresse 0x000f0004 verweisen, lesen Sie möglicherweise die Adresse 0x0004 aus dem Flash. Die virtuelle Adresse ist 0x000f0004, aber die physische Adresse ist nur 0x0004 - der gesamte Adressraum 0x000fxxxx ist einem physischen 4-KB-Speichergerät zugeordnet. Dies ist natürlich nur ein Beispiel, und die Methode zum Verwalten und Organisieren des virtuellen Adressraums unterscheidet sich in den Architekturen erheblich.
Wenn Sie also sagen, dass "das Programm mit der Ausführung von [...] der Adresse 0x0000 beginnt, die fast immer die niedrigste Adresse in Flash ist", ist die Richtigkeit nicht garantiert. Tatsächlich starten viele Mikrocontroller bei 0x1000.
quelle
Was Sie sagen, ist nicht ganz wahr oder falsch. Hierfür gibt es verschiedene Szenarien.
Dies hängt davon ab, ob Sie auf der Rohhardware oder der mit dem Betriebssystem installierten Hardware programmieren.
Ihr Betriebssystem, das auf dem Allzweckcomputer ausgeführt wird, ruft Code von der Festplatte ab und speichert ihn für einen schnelleren Zugriff im RAM. Wenn Ihr Prozessor ständig versucht, Daten direkt von der Festplatte abzurufen, ist der Betrieb aufgrund der Geschwindigkeitsinkongruenz zwischen zwei sehr viel langsamer. So kommt Ihr RAM ins Spiel, in dem Teile Ihres sich wiederholenden Codes für einen schnelleren Zugriff gespeichert werden. Und das wird im Cache-Speicher des Prozessors noch weiter zur Verfügung gestellt, um ihn noch schneller zu machen.
Wenn Sie nun an einem Mikrocontroller arbeiten, hängt es ganz von Ihnen ab, wo Sie Ihre Daten auf dem Chip ablegen. Wenn die Daten statisch sind, möchten Sie sie möglicherweise im Codespeicher ablegen, wodurch Ihr RAM gespeichert wird, der vergleichsweise viel kleiner als der Codespeicher ist. In der Sprache C werden beim Initialisieren des Datentyps mit static oder in einigen Compiler-Konstanten Präfixdaten im Codespeicher oder im RAM gespeichert. Und in der Assembly verwenden Sie direkt DB (Define Byte im Fall von Basic 8051), um Daten an dem bestimmten Speicherort zu initialisieren. Jetzt können Sie sogar in einigen Controllern wie PIC ARM ROM in der Laufzeit schreiben, aber das Abrufen von Daten wird viel Zeit in Anspruch nehmen.
Außerdem gibt es Bootloader-Hardware für mittelgroße und hochentwickelte Steuerungen, die den Steuerungen oder dem Prozessor mitteilen, von wo aus der Startcode ausgeführt werden soll, oder es handelt sich um den Startcode, der tatsächlich in den Speicher segmentiert ist Ich würde eher hybrides Advnacement in der Industrie sagen, das das gesamte Konzept von konventionellem RAM ROM & Memories durcheinanderbringt. Grundsätzlich gilt also Ihre Verwirrung.
quelle