Das kann man aber nicht der Harvard Architektur als solche anlasten, sondern der Umsetzung im AVR-Core. Man hätte auch grössere Pointer einbauen können. Und auch in nicht Harvard CPU gibt es sowas, z.B. beim 8086 mit seinem segmentieren Speicher.
Das kann man aber nicht der Harvard Architektur als solche anlasten, sondern der Umsetzung im AVR-Core. Man hätte auch grössere Pointer einbauen können. Und auch in nicht Harvard CPU gibt es sowas, z.B. beim 8086 mit seinem segmentieren Speicher.
"kombiniert" spielt keine Rolle. Flash und SRAM haben je einen eigenen Adressraum. Da die AVR RISC-Befehle 16-Bit groß sind wird das Flash auch so adressiert, d.h. die 16-Bit Pointer taugen ohne Krücken für 128KiByte Flash plus 64KiByte SRAM. Für so eine vergleichsweise langsame (max. 33MHz) 8-Bit Architektur ist das eigentlich ausreichend. Wer mehr Speicher braucht, dem dürfte i.d.R. auch die begrenzte Rechenleistung nicht ausreichen.
Ack. Das hätte dann aber etwas gekostet (Performance, Stromverbrauch, Chipfläche, etc.). Eine kleine MCU ist eigentlich immer ein Kompromiss.
Sicherheitstechnisch hat diese Architektur auch Vorteile. Daten im Hauptspeicher (wo üblicherweise auch der Stack liegt) sind z.B. per Definition nicht als Code ausführbar. Auch ein verbogener Pointer oder eine verbogene Rücksprungadresse auf dem Stack kann nie auf Code des Angreifers zeigen. Die Tür bleibt offen für Sachen wie ROP [1], aber die einfachen Angriffe funktionieren nicht.
______________ [1]
Doch, tut es. Denn wenn du die Adressräume vermischst und per "unified" Pointer drauf zugreifen willst, dann kannst du das mit einem Pointer, der groß genug ist, problemlos machen. Also Beispiel: 32 Bit pointer, bei dem das MSB angibt, ob jetzt SRAM oder Flash gemeint ist.
Dann "funktioniert" alles so wie einer nicht-Harvard-Architektur gewohnt, aber ist natürlich arschlangsam, weil der Compiler bei jeder Indirektion wieder schauen muss und eine Fallunterscheidung machen müsste. Wäre aber /theoretisch/ denkbar.
Wenn die Pointer aber kleiner sind als die kombinierte Größe, ist es /nichtmal/ theoretisch denkbar.
Falsch. Adressierung in einem AVR erfolgt byteweise, d.h. jeweils auch nur bis 64 kiB Flash. Für 128 kiB Flash brauchst du eben also Krücken (siehe pgm_read_byte_far() im Vergleich zu pgm_read_byte_near()).
Ein größerer Cortex-M hat mit einer MPU und Privilegienseparierung sicherlich deutlich mächtigere Mittel, die Laufzeitumgebung abzusichern. Und eben nicht die krückigen Nachteile von dem Murks-AVR.
Gruß, Johannes
Größere Pointer würden erlauben, einen "normalen" UMA Zugriff zu emulieren, aber das wäre immernoch nicht performant.
Stell dir vor, der AVR hätte ein 64-Bit breites Pointerregister. Unglaublich viel Platz um alles unterzubrigen. Trotzdem gibt es jede Adresse zweimal: 0x0 kann entweder also an den Start des Flashes zeigen oder an den Start des SRAMs. Wegen Hardvard. Du hast also dasselbe Problem, dass du in den Funktionen jeweils wissen musst, was "gemeint" ist, wenn du mit Pointern handtierst.
Die Segmentselektoren zusammen mit dem Offset ergeben aber auch beim
8086 jeweils eine lineare Adresse, x + 16y. Und 0123:4567 zeigt immer auf dasselbe Byte und das gibt die nicht einmal im RAM und ein anderes Mal, durch andere Befehle zugegriffen, irgendwo anders.Gruß, Johannes
Naja, wir reden erstens hier von AVRs. Und klar kannst du mit beliebig viel Abstraktionsebenen und entsprechendem Overhead für den Nutzer alles "schön" erscheinen lassen, aber es wird dann halt echt lahm. 32-Bit Pointer auf einem AVR zu emulieren ist überhaupt kein Problem und dann kannste in deinen virtuellen Adressraum auch den EEPROM einblenden und sogar Schreibzugriffe auf den einfach so "magisch" erledigen lassen.
Ich kenne zu FORTH interessanterweise keine Performance-Benchmarks. Aber würde mich mal interessieren, z.B. das hier:
- Den Key Schedule zu machen
- 128 Bytes Strom zu generieren
Würde mich echt interessieren. Wenn das einer von den FORTHlern mal misst und die Ergebnisse schreibt, mach ich das auch in C und poste die Ergebnisse. Bin gespannt wie weit die auseinander liegen, ob das jetzt
25, 50, 200 oder 1000% Unterschied in der Laufzeit sind.Gruß, Johannes
Ich habs mirs mal für den (MC68HC908)-GP32 8 Bit Controller den ich normalerweise verwende angesehen:
Der läuft mit seinem normalen 2,54MHz CPU-Takt. Die 10MHz würden über Portpin einen 16 Bit Timer takten. Dessen Endwert ist 0001... FFFFh per Register einstellbar, dann startet er wieder ab 0000. Er kann also einen krummen Teiler machen. Hier wäre das 16000d. Der Softwareteiler um auf 1Hz zu kommen ist dann 625d. Also auch ein 16 Bit Zähler. Der Interrupt des Timers kommt alle 1,6msec. Dieser Zähler wäre also ein kurzes Assemblerprogramm im Interrupt das ein 1Hz Flagbyte setzt. Das Flag wird in der Endloschleife die in HLL programmiert ist ausgelesen.
Ausgabe der Hauptschleife wäre z.B. ein LCD-Display mit HD44780 bei dem die Sekunden mit diesen 1Hz geschrieben werden.
MfG JRD
Der avr-gcc macht das intern auch in der Art, s.u.
C ist für von Neumann Architektur vorgesehen und die verschiedenen Adressräume sind dort eigentlich prinzipiell eine Krücke. Wirklich schön wird das nie sein.
Wenn man via avr-objdump aus einem ELF-Binary die Symbol-Table anzeigen lässt, stehen die Offsets für SRAM und EEPROM dort noch drin. Der Compiler macht es intern also im Prinzip so und erst am Ende wird alles zerlegt.
Du hast Recht. Für SPM wird der Z-Pointer wordweise (wie hardwaremäßig implementiert¹), für LPM aber byteweise interpretiert. Allgemein ist das Limit also für das Flash auch 64KiByte.
Dass etwas prinzipiell nicht funktioniert hat IMHO schon auch seinen Reiz.
Ich wollte die für "große" AVRs nötigen Krücken nicht schönreden. Unterhalb dieser Limits empfinde ich die Architektur an sich aber deutlich weniger schlimm als du beschrieben hast.
______________ ¹ Zitat aus einem AVR-Datenblatt: "Since all AVR instructions are 16 or 32 bits wide, the Flash is organized as [Anzahl Words] x 16 bits."
Ist natürlich richtig.
Ja, ich dramatisiere. Man muss die AVRs halt auch im Kontext ihrer Zeit sehen. Als ich mit µC Programmierung angefangen habe war das 6800 und
8051, mit fast komplett externer Peripherie. Die ersten AVRs die ich dann in der Hand hatte, AT90S1200 und AT90S2313, waren dagegen eine ECHTE Offenbarung. Der 2313 hatte sogar ein UART mit drin, das war schon ziemlich cool und tonnenweise RAM. Das ist jetzt aber halt auch 14 Jahre her und für damals war das echt bahnbrechend. Ein Open-Source Compiler noch dazu, echt krass.Mittlerweile hat aber ja auch Atmel/Microchip auf Cortex-M umgesattelt, dagegen konvergiert der Embedded-Bereich offenbar komplett -- und nicht ohne Grund. Das ist nämlich auch eine extrem sauber durchdachte, tolle Architektur.
Aber ich werde mir deinen Tipp zu Herzen nehmen und versuchen, wohlwollender gegenüber den AVRs zu sein. :)
Viele Grüße, Johannes
Am 14.08.2019 um 12:44 schrieb Wolfgang Allinger:
Du hast atomare Zugriffe nicht verstanden :-(
DoDi
Am 14.08.2019 um 13:15 schrieb Wolfgang Allinger:
Im DIY als Vorsatz vor den Oszi :-)
In Echtzeit (nebenläufige Prozesse...) kann man mit FORTH genausoviel Mist bauen wie mit anderen Sprachen.
DoDi
Am 14.08.2019 um 17:42 schrieb Rafael Deliano:
Das geht bei den Atmels nicht, wenn die ihre Eingänge (typischerweise) mit dem Systemtakt synchronisieren.
DoDi
Am 14.08.2019 um 17:29 schrieb Johannes Bauer:
Das ist nicht ganz richtig. Die Segmentregister werden in eigenen Befehlen gesetzt, die übrigen Befehle greifen dann auf denjenigen Speicherbereich zu, der (zufällig?) gerade im Segmentregister steht.
Dafür hat beim 8086 jedes Byte 16 verschiedene Adressen - was für 'ne Verschwendung ;-)
DoDi
Das mag sein, aber war gar nicht meine Aussage. Sondern eben, dass die Adresse 0123:4567 immer der linearen Adresse 0x5797 im RAM entspricht, ganz gleich wo das passiert. Wenn im Segmentselektor-Register oder Offset, der in der Instruktion codiert ist, jeweils was drin steht, das eben nicht 0x0123 respektive 0x4567 ist, landest du natürlich möglicherweise woanders.
Es gibt da natürlich aber auch viele Adressen, die auf dasselbe Byte zeigen aber nie zwei *identische* Adressen, die auf unterschiedliche Bytes zeigen. Und das ist bei einer Harvard-Archtitektur anders und darum ging's mir.
Ja, die Vorteile einer solchen Segmentierung erschließen sich mir ehrlichgesagt auch nicht so ganz. War damals bestimmt sinnvoll, die werden sich schon was gedacht haben dabei :-)
Viele Grüße, Johannes
snipped-for-privacy@aol.com (Hans-Peter Diettrich) am 15.08.19 um 05:44:
Dann ist es aber nicht billiger, denn er kommt ja zum Oszi /hinzu/.
Meine Hobbyprojekte sind freilich zwölf Nummern kleiner, weshalb ich nie über die zusätzliche Anschaffung eines LA nachgedacht habe. Um herauszufinden, an welcher Stelle sich mein Progrämmchen verläuft, reichte mir die Portpin/LED/Oszi-Methode bislang immer.
Rainer
Ja das ist das Problem wenn man als "Alter Experte" womöglich immer am gewohnten Controller kleben bleiben will, weil man da womöglich Forth einsetzen kann ;-)
Liest man doch z.B. im KEA128Ref manual bei Real-Time-Counter , der genau fuer diesen Zweck als Software Calendar fungiert (genau was Ralph braucht mit Bsp. code), dass als Quelle ein externer Pin ohne Bus-sync eingesetzt werden kann :)
Benutzt man einen ext Pin als Quelle für z.B. ein Timer-Module, dann wird der externe Takt mit dem Bus Takt synchronisiert. Hinweis im Manual, "This clock signal must not exceed 1/4 of system clock frequency."
Josef
Der 1200er war mit dem Hardwarestack auch noch arg beschränkt. SRAM hatte er auch keines. Im realen Einsatz kam es auch öfter vor, dass er seine Signature "vergessen" hat und dann vom Programmiergerät nicht mehr erkannt wurde. AT90S2313 und AT90S8515 waren gut.
Ja, was anderes wollte ich auch nicht unterstellen.
8-Bit MCUs nimmt man meistens auch gar nicht wegen der Architektur. Wenn man eine Schaltung mit 5V laufen lassen möchte (z.B. weil 3.3V für die InGaN-LEDs nicht ausreichen), dann ist es schon nett wenn die MCU das direkt kann. Mit 32-Bit MCUs ist üblicherweise bei 3.3V Ende.Dass alle AVRs teuer wären, wie oft zu lesen, stimmt auch nicht: Ein ATtiny402 kostet z.B. 30¢@100.
schon 10a als Ren(n)tier voll habe :)
Wolfgang
Egal, für mich ist Theorie nicht (mehr) wichtig. Muss(te) damit keine Brötchen (mehr) verdienen. Ich musste meine Sachen immer rechtzeitig und gut zur Tür rausbringen. Was mir eigentlich lt. meinen Kunden immer gut gelungen ist.
Wolf(wenigTheorieaber)gan(zvielPraxis)g
Saludos (an alle Vernünftigen, Rest sh. sig) Wolfgang
Sooo klein ist die Auswahl von 32bit ARM 5.5V Vcc nun auch wieder nicht.
z.B. Farnell KE0x Cortex M0+ 2.7-5.5V ca. 1 EUR/st (including RTC)
als die MCU bei 3V3 oder kleiner ?
Have something to add? Share your thoughts — no account required.
Ask the community — no account required