Werden die Anweisungen aus dem RAM oder ROM in einem ARM-Mikrocontroller abgerufen?

In vielen Tutorials zu ARM-CPU-Registern wird das Befehlsregister so erwähnt: "Register R15 im ARM-Mikrocontroller ist der Programmzähler und zeigt auf den nächsten Befehl, der aus dem Speicher abgerufen werden soll."

Aber ich habe auch gelesen, dass es in der Harvard-Architektur einen Befehlsspeicher und einen Datenspeicher gibt. Was ich davon verstanden oder missverstanden habe, war, dass die Befehlscodes im Flash-ROM gespeichert sind und die Daten im RAM gespeichert sind.

Aber wenn ich mehr darüber lese, habe ich den Eindruck, dass die Anweisungen auch aus dem RAM statt aus dem ROM geholt werden.

Hat ROM außer dem Speichern des Maschinencodes nichts mit der gesamten Operation zu tun?

Bearbeiten: Die Frage setzt kein Betriebssystem voraus, nur einen eigenständigen ARM-Mikrocontroller.

Die Harvard-Architektur wird nur in "kleinen" Geräten wie Mikrocontrollern oder in den CPUs selbst verwendet. Große Architekturen mit viel RAM verwenden niemals vollständige Harvard-Architekturen

Antworten (4)

ARM-Kerne sind eigentlich das, was man modifizierte Harvard-Architektur nennt . In diesem Fall befinden sich ROM und RAM im selben Adressraum, sodass ein ARM-Prozessor Code aus beiden ausführen oder auf beide als Daten zugreifen kann. In der modifizierten Harvard-Architektur ist der Verarbeitungskern direkt mit zwei separaten Befehls- und Datencaches verbunden. Dies ermöglicht eine hohe Leistung, da gleichzeitig auf Befehle und Daten zugegriffen werden kann. Auf hoher Ebene lässt der kombinierte Adressraum das gesamte System wie eine Von-Neumann-Architektur wirken.

Die Struktur des Adressraums wird durch die physikalischen Verbindungen zwischen dem Verarbeitungskern selbst und allen Speichern und Peripheriegeräten bestimmt. Zum größten Teil wird das Layout des Adressraums mit bestimmten Bereichen festgelegt, die speicherabgebildeten Peripheriegeräten, Masken-ROM, Flash, RAM usw. entsprechen. Es kann jedoch eine gewisse Möglichkeit geben, bestimmte Abschnitte des Adressraums neu zuzuordnen oder Peripheriegeräte zu konfigurieren oder externe Speicher, die in bestimmten Bereichen des Adressraums sitzen.

"ROM und RAM sitzen im selben Adressraum" Was meinst du? Ist Flash-ROM nicht eine andere Hardware als RAM?
Ich sehe das oft, aber es stimmt nicht: Einen separaten I-Cache zu haben, verwandelt eine von Neumann-Maschine NICHT irgendwie in eine Harvard-Maschine. Es ist immer noch ein einheitlicher Adressraum, und Sie müssen sich um die Kohärenz zwischen den beiden Caches kümmern.
Unter dem Gesichtspunkt der Leistung wird es zu einer Harvard-Maschine, da der Kern in der Lage ist, Anweisungen und Daten gleichzeitig über separate Ports zu lesen. Aufgrund des einheitlichen Adressraums verhält es sich jedoch auf hoher Ebene wie eine Von-Neumann-Maschine. Ich würde sagen, es ist eher eine Mischung aus beidem.
Aha, dafür gibt es einen Fachbegriff: modifizierte Harvard-Architektur: en.wikipedia.org/wiki/Modified_Harvard_architecture .
@alex.forencich, damit ARM gleichzeitig Daten und Anweisungen lesen kann, was es zu Harvard macht. Aber einheitlicher Adressraum macht es Neuman. Für mich ist es eine Harvard-Maschine.
ROM und RAM können sich im selben Adressraum befinden, aber (normalerweise) nicht in überlappenden Adressen in diesem Raum. In einem alten System, das ich verwendet habe (Intel 8085), belegte das ROM die Adressen 0x0000 bis 0x7fff, während sich das RAM an den Adressen 0x8000 - 0x9fff unmittelbar nach dem Ende des ROM befand (wir verwendeten 8-KB-RAM und ROM-Chips). In diesem System befand sich der Programmcode im ROM (eigentlich UVPROM) und die Daten im RAM.
@ Peter Bennett Ich dachte, das gleiche gilt für ARM. Der Befehlscode befindet sich im ROM und die Daten im RAM; und das CPU-Befehlsregister R15 zeigt auf die Adresse im ROM, um die nächsten Befehle abzurufen. Aber einige sagen hier, dass Anweisungen auch im RAM sein können. Sehr verwirrend..
Das CPU-Befehlsregister kann überall im Adressraum zeigen. Wenn es zufällig auf RAM zeigt, ruft es Anweisungen aus dem RAM ab. Wenn es zufällig auf das ROM zeigt, ruft es Anweisungen vom ROM ab. Nun ist es durchaus möglich, dass Ihr Programm die Ausführung niemals in den Arbeitsspeicher leitet, was wahrscheinlich bei vielen eingebetteten ARM-Prozessoren der Fall ist.
@alex.forencich sorry für meine Unwissenheit aber wer entscheidet das? Programmierer?
Nun, der Programmierer bestimmt direkt oder indirekt den Programmablauf, also ja, es wäre letztendlich Sache des Programmierers.
@ user16307: Meine Anwendung war ein eingebetteter Controller - einzelnes Programm, kein Betriebssystem, also befand sich das Programm im ROM. Der 8085-Mikroprozessor wurde auch in frühen Personalcomputern mit dem CP / M-Betriebssystem verwendet - in diesem Fall befand sich ein kleines Boot-Programm im ROM, während sich das Betriebssystem und die Benutzerprogramme im RAM befanden - aber sowohl RAM als auch ROM waren vorhanden denselben Adressraum von 64 KB. Ich denke, diese letztere Anordnung würde eher den normalen ARM-Prozessoranwendungen ähneln.
@PeterBennett Meine Frage bezog sich auf ARM-Mikrocontroller ohne Betriebssystem, auch nicht auf PCs. Ich denke, in diesem Fall werden Anweisungen aus dem ROM abgerufen. Sind Sie einverstanden?
@ user16307 Anweisungen können aus dem ROM oder RAM oder irgendwo anders im Adressraum abgerufen werden.
Der Prozessorkern selbst kennt kein RAM von ROM von Peripherie, sie sind nur Adressen. Der Cortex-M hat einige Regeln darüber, welche Adressbereiche Sie für Dinge verwenden können, aber es ist der Chipentwickler, der bestimmt, wo sich die Dinge tatsächlich befinden. Soweit Anweisungen leben können, können sie überall dort leben, wo der Kern ausführen darf, was so viel wie der gesamte Adressraum sein kann. Natürlich müssen Sie von Flash/ROM booten, da es nicht flüchtig ist, aber danach können Sie auf einem Arm vom RAM laufen, wenn Sie den Code dorthin kopieren und dorthin verzweigen
Wie Alex erwähnte, behaupten sie, Harvard, aber es ist nicht wirklich im reinen Sinne, da sich die Befehls- und Datenadressräume überschneiden. Sie können einen Code kopieren, der mit XYZ im RAM beginnt (Datenzugriffe) und die Verzweigung dorthin und den Code dort (Befehlszugriff) unter Verwendung derselben XYZ-Adresse ausführen. Zweifellos könnte Ihr 8085 dies auch tun, wenn Sie wollten, nur weil Sie sich vielleicht dafür entschieden haben und nur weil es oft nicht auf einem Arm-Mikrocontroller gemacht wird, heißt das nicht, dass Sie es nicht können.
Der verlinkte WP-Artikel hat viele Probleme dokumentiert, und es ist nicht klar, was die Bedingung für die Qualifizierung als "Modified Harvard Architecture" überhaupt ist. Wenn einfach nur ein separater icache/dcache benötigt wird (und ansonsten eine von Neumann-Architektur ist), ist dies eine unsinnige Klassifizierung und sehr verwirrend, da aus Programmiersicht überhaupt nichts "Harvard" daran ist.
Aus Programmiersicht ist es von neumann. Aber aus der Perspektive des digitalen Designs ist der Kern selbst Harvard, da er den Vorteil nutzt, gleichzeitig von verschiedenen Ports auf Anweisungen und Daten zugreifen zu können. Ich glaube, dass die meisten modernen Hochleistungsprozessoren aufgrund der Leistungsvorteile intern eine ähnliche Architektur verwenden.

Die ARM-Architektur ist eine von Neumann-Architektur , keine Harvard-Architektur. Das bedeutet, dass sowohl für Anweisungen als auch für Daten ein einheitlicher Adressraum verwendet wird. Ob eine bestimmte Adresse RAM oder ROM enthält, hängt vom Systemdesigner ab. Anweisungen können von beiden abgerufen werden.

Meinen Sie, EEPROM und RAM werden beide als Speicher bezeichnet, indem Sie "einheitlicher Adressraum" sagen? Ich dachte, Datenvariablen werden im RAM gespeichert und Anweisungen befinden sich im ROM. Was meinst du mit Systemdesigner?
Nein, nicht alle Anweisungen sind im ROM. Der Systemdesigner ist derjenige, der entscheidet, welche Art von Speicher für welchen Zweck in einer bestimmten Anwendung verwendet werden soll. Einige tief eingebettete ARMs haben alle ihre Anweisungen im ROM, während andere nur einen Bootloader im ROM haben und den eigentlichen Anwendungscode aus einer Art Sekundärspeicher in den RAM laden. Der Vorteil ist, dass RAM in vielen Fällen viel schneller sein kann als ROM.
Nur um sicherzugehen, dass "Systemdesigner" nicht der Typ ist, der einen C-Code schreibt und in den Mikrocontroller kompiliert, oder? Er ist der Typ, der den Mikrocontroller selbst entwirft? Wenn ja, kann ich dem Datenblatt des Mikrocontrollers entnehmen, ob die Anweisungen aus RAM oder ROM geholt werden?
Und ich denke, in einigen Fällen ist das ROM tatsächlich so etwas wie ein SPI-Flash, den Sie überhaupt nicht ausführen können (ganz zu schweigen davon, dass der Zugriff darauf sehr langsam ist); Stattdessen wird der Inhalt des SPI-Flash-Chips beim Booten in den RAM kopiert und von dort ausgeführt.
Ja, SPI-Flash ist ein Beispiel für „Sekundärspeicher“.
@ user16307 Alle ARM-Prozessoren können Anweisungen von überall in ihrem Adressraum ausführen. Wenn das ROM in den Adressraum abgebildet wird, können Befehle von dort ausgeführt werden. Gleiches gilt für RAM. Der einzige Fall, in dem Sie keinen Code aus dem ROM ausführen können, ist, wenn ein MMU- oder NX-Bit den Zugriff im aktuellen Kontext verhindert oder wenn auf das ROM über ein Peripheriegerät wie SPI oder SDIO/MMC zugegriffen werden muss Controller, in diesem Fall müssten die Anweisungen zuerst in den RAM kopiert werden.
@alex.forencich Wenn man den kompilierten Code auf den Mikrocontroller hochlädt. Lass uns Zeitlupe haben. Wird dieser Maschinencode nicht zuerst an das Flash-ROM gesendet?
Kann sein, muss aber nicht. Ich hatte vor einiger Zeit einige Debug-Skripte, die den Code tatsächlich per JTAG direkt ins RAM geladen und von dort aus ausgeführt haben, um den Flash zu schonen. (Dies war auf einem Atmel SAM7 ARM-Mikrocontroller)
@alex.forencich Interessant zu hören. Wenn der Code also irgendwann in den RAM statt in den ROM ging und Sie den Mikrocontroller ausschalten, verlieren Sie dann nicht den Code, wenn Sie ihn wieder einschalten? RAM speichert den Code nicht. Was ist passiert?
Wie gesagt, das war nur zum Debuggen. Verbinden Sie sich mit GDB, laden Sie den Code in den RAM, setzen Sie den Befehlszeiger auf den Code im RAM, setzen Sie einige Haltepunkte, führen Sie ihn aus usw. Ja, der Code würde nach einem Aus- und Wiedereinschalten verloren gehen. Es ist auch nicht so nützlich, da der RAM auf diesem Chip nur 32 KB groß ist, während er 512 KB Flash hat. Aber ich erwähne es als ein spezifisches Beispiel für das Ausführen von Code aus dem RAM.
@alex.forencich Okay, also sollte der Programmcode im Allgemeinen in das ROM geladen werden, oder? Andernfalls müssen Sie es bei jedem Neustart des uC neu laden.
hast du meinen Punkt und meine Verwirrung jetzt verstanden?
Manchmal laden Sie es jedes Mal, wenn Sie den uC neu starten. Das habe ich mit dem Bootloader und dem "sekundären Speicher" beschrieben. Genau so funktioniert auch Ihr Desktop-/Laptop-PC.
Generell ja. Normalerweise wird der Code in etwas nicht flüchtiges geladen. In einigen Fällen ist dieser nichtflüchtige Speicher jedoch möglicherweise nicht speicherzugeordnet, sodass Sie nicht aus ihm heraus ausführen können. Einige Chips verfügen über einen Bootloader im Masken-ROM (kann nach der Herstellung des Chips nicht geändert werden), der für das Laden von Code aus einem externen Speicher wie einem SPI-Flash-Chip, einer SD-Karte usw. verantwortlich ist, ihn möglicherweise dekomprimiert oder entschlüsselt und hineinkopiert RAM und Ausführen.
"Im Allgemeinen ja." Bedeutet das im Allgemeinen, dass R15 die Anweisung aus dem ROM holt?
Vielleicht. Kommt auf den Prozessor an. Für einige ist es wahrscheinlich, dass sich der gesamte Code im ROM befindet und die CPU daher immer außerhalb des ROM ausgeführt wird. Für andere, die keinen wiederbeschreibbaren nichtflüchtigen Speicher haben, der dem Adressraum zugeordnet ist (dh sie laden Code von einem SPI-Flash, einer SD-Karte usw.), nachdem der Masken-ROM-Bootloader ausgeführt und das Programm in den RAM kopiert hat, dann die CPU wird immer ohne RAM ausgeführt.
@alex.forencich "Für andere, die keinen wiederbeschreibbaren nichtflüchtigen Speicher im Adressraum abgebildet haben (dh sie laden Code von einem SPI-Flash, einer SD-Karte usw.), nachdem der Masken-ROM-Bootloader ausgeführt und das Programm kopiert hat RAM, dann wird die CPU immer ohne RAM ausgeführt." Meinst du, wenn es OS gibt?
Nicht genau. Auf vielen ARM-Chips gibt es ein bisschen Masken-ROM, das einen fest codierten Bootloader enthält. Sie können das Programm in diesem ROM nicht ändern; Es wird vom Hersteller festgelegt, wenn der Chip hergestellt wird. Diese werden manchmal verwendet, um Möglichkeiten zum Laden von Code über eine serielle Schnittstelle oder über USB bereitzustellen. Einige Geräte haben jedoch überhaupt keinen internen Flash-Speicher. In diesem Fall kopiert der Code im ROM das Programm aus einem externen Speicher in den RAM. Nach dem Starten des Codes im RAM hängt dieses Bit des Startcodes nicht herum und tut nichts. Es ist also kein Betriebssystem, nur ein Lader.
Mikrocontroller-ARMs verwenden die Harvard-Architektur, im Gegensatz zu größeren ARMs, zum Beispiel ARM9 oder Cortex-M3/4/7

ARM-Mikrocontroller, die neueren Cortex-M-Controller, haben Modi, um entweder vom RAM oder vom ROM aus zu arbeiten. Überprüfen Sie beispielsweise die BOOT0- und BOOT1-Bits im STM32-Referenzhandbuch . Dies konfiguriert so ziemlich die Startadresse der Ausführung, indem die tatsächlichen Speicheradressen tatsächlich in ein festes Speicheradresssegment ( 0x0000 0000to 0x0007 FFFF) umgewandelt werden.

Der Cortex-M-Kern hat vier Arten von "Speicher": RAM, ROM (Flash und Systemspeicher), FSMC und Peripherie. RAM ist, nun ja, internes statisches RAM. ROM ist internes Flash oder der nicht beschreibbare eingebettete Bootloader. FSMC ermöglicht die Verwendung von externem Speicher (sowohl RAM als auch ROM, je nach externer Hardware). Peripherer Speicher sind spezifische Register, die peripheren Funktionen wie UARTs, ADCs usw. zugeordnet werden. Die Hardware für den Zugriff darauf ist separat, um die Geschwindigkeit zu erhöhen (Harvard-Stil), insbesondere weil Flash langsamer als SRAM ist.

All diese sind jedoch in einem einzigen Adressraum (von Neumann-Stil) vereint, was den Zugriff auf sie aus der Sicht eines Programmierers vereinfacht. Sie unterscheiden sich nur durch ihre Adressbereiche (implementierungsabhängig). Die BOOT-Pins ermöglichen die Konfiguration zwischen drei Startadressen: eine im RAM, eine im ROM (Nur-Lese-Bootloader) und eine weitere im ROM (Flash). Dadurch ist es möglich, Ihre Frage mit "beides" zu beantworten . Ich habe es nie versucht, aber es scheint möglich zu sein, von einem Segment zum anderen zu springen.

Denken Sie jedoch daran, dass diese Erinnerungen immer noch nicht gleichermaßen behandelt werden können. Sie können nicht beliebig in das ROM schreiben. Es ist Flash, wodurch sie wiederbeschreibbar sind, aber Sie müssen ein spezielles Verfahren verwenden, um darauf zu schreiben (es wird normalerweise als "Flash als EEPROM verwenden" zum Speichern von Programmdaten oder als "Bootloader" bezeichnet, wenn Programmcode gespeichert wird, normalerweise beim Start).


Kuriose Infos:

Wenn man vom Flash (ROM) ausführt, werden die Anweisungen direkt vom ROM abgerufen. Normalerweise gibt es einen Startcode , der Daten vom ROM in den RAM kopiert (initialisierte globale Variablen, normalerweise im Datenabschnitt gespeichert ) . Das Referenzhandbuch enthält diese Informationen ebenfalls

Beim Booten vom SRAM müssen Sie im Initialisierungscode der Anwendung die Vektortabelle im SRAM verschieben, indem Sie die NVIC-Ausnahmetabelle und das Offset-Register verwenden.

was normalerweise durch den Startup-Code durchgeführt wird.

Die Boot-Modi hier verdeutlichen, was los ist. Der Benutzer kann (hier mit Pin-Einstellungen) das Speichergerät auswählen, das durch Codezugriffe auf die Adressen 0x0 und 0x04 beim Zurücksetzen gelesen wird. Dies ändert tatsächlich die Adressdecodierung, und ja, Sie können von 0x04 (Rücksetzvektor) zu 0x08000008 springen, um von der nächsten Anweisung im Flash ausgeführt zu werden, oder zu 0x20000000, um zum SRAM zu gelangen.
Normalerweise ist das Ausführen von Code von FLASH auf den kleineren MCU-Geräten genauso schnell wie das Ausführen von SRAM oder ROM. Möglicherweise gibt es jedoch Bibliotheksfunktionen im maskierten ROM (aus Platz- / Kostengründen oder zum Schutz - und dann würden Datenabrufe aus dem ROM wahrscheinlich auf der Soc-Design-Ebene blockiert).
ist der Opcode der nächsten Anweisung immer bei R15?

Ungeachtet der Architektur hält R15 die Programmzähleradresse. Die nächste (hoffentlich gültige) Anweisung wird von dieser (hoffentlich gültigen) Adresse geholt. Beachten Sie, dass beides problematisch sein kann.

1) ungültige Operationscodes. 2) Speicher jeglicher Art dürfen für die Adresse nicht installiert werden.

Ja, es ist wünschenswert, dass für Daten reservierte Bereiche nicht als Programmcode ausgeführt werden. Der Adressraum, von dem wir sprechen, ist begrenzt (es ist kein Adressraum mit Fenstern, wie er in PCs, Midrange, Mainframe usw. verwendet wird) und kann RAM, ROM, Peripherieports enthalten.

Es sollte sicherlich möglich sein, Anweisungen aus dem RAM abzurufen, wenn wir RAM für die Adressen haben, die wir für gültig für Anweisungen halten, sodass Code geladen werden kann, wenn wir dies wünschen, im Overlay-Stil. Auch ohne Betriebssystem.