Nabend, wie war noch die Formulierung wenn ich ein Feld aus Festwerten nicht im RAM beim Atmega haben möchte sondern im Programmspeicher? uint8_t Feld[10]; Finde das gerade so ad hoc nicht. Danke
:
Bearbeitet durch User
Daniel S. schrieb: > Finde das gerade so ad hoc nicht. C, oder C++? Wenn C, dann: __flash uint8_t __flash Feld[10]; Ist bequemer, als der Alte, bzw. der C++ Weg über PROGMEM.
Daniel S. schrieb: > jo, Ich programmiere in c aufm arduino. Sicher? Nutzt Du die Arduino-IDE und das ganze zugehörige Zeug? Dann glaubst Du nur, in C zu programmieren.
Ja, ich glaube es nur. Die Frage sollte wohl auch eher lauten welcher compiler da werkelt...oder? Arduino F. schrieb: > Wenn C, dann: __flash Das uint8_t __flash test[2]={1,2}; geht in der IDE jedenfalls nicht. Ist ja aber auch die Arduino IDE.
:
Bearbeitet durch User
Daniel S. schrieb: > Die Frage sollte wohl auch eher lauten welcher compiler da > werkelt...oder? Nein. Der Compiler wird in diesen Fällen eh immer GCC sein. In C hat Johann aber __flash implementiert; damit kannst du Daten im Flash ohne weitere Umstände direkt benutzen. Der Compiler puzzelt für dich beim Zugriff aus, ob er das via LPM machen muss oder einen der anderen LP*-Befehle, ohne dass du den Zugriff in besondere Makro-Aufrufe kapseln musst. Bei C++ gab es zumindest lange Zeit eine Tendenz, die zugrunde liegenden Prinzipien (type qualifier) nicht haben zu wollen, weshalb das dort trotz gleichen Compilers nicht implementiert ist. Ich bin mir nicht ganz sicher, ob das inzwischen sogar möglich wäre.
Daniel S. schrieb: > Ist ja aber auch die Arduino IDE. Die setzt auf C++ auf, auch wenn es manchmal nicht danach aussieht.
Harald K. schrieb: > Sicher? Nutzt Du die Arduino-IDE und das ganze zugehörige Zeug? Dann > glaubst Du nur, in C zu programmieren. *.ino Dateien werden zu *.cpp umgebaut. Aber *.c bleiben *.c und werden auch als C kompiliert. Daniel S. schrieb: > geht in der IDE jedenfalls nicht. Doch geht, wenn man will. Spätestens nach einem Compiler update.
Arduino F. schrieb: > Aber *.c bleiben *.c und werden auch als C kompiliert. Nö. g++ main.c ... übersetzt als C++ weil der C++ Compiler cc1plus aufgerufen wird. Guckst du g++ -v main.c ... | grep cc1 Damit main.c als C übersetzt wird braucht's explizit g++ -x c main.c ... Jörg W. schrieb: > Bei C++ gab es zumindest lange Zeit eine Tendenz, die zugrunde liegenden > Prinzipien (type qualifier) nicht haben zu wollen, weshalb das dort > trotz gleichen Compilers nicht implementiert ist. Ich bin mir nicht > ganz sicher, ob das inzwischen sogar möglich wäre. Möglich wäre es, GCC ist ja nur Software. Die Frage ist nur, ob 1) das jemand wirklich implementieren will und 2) ob die Maintainer das haben wollen. clang kann's ja auch: Das dortige address_space Attribut agiert nämlich wie ein Qualifier. Wobei soweit ich weiß clang nur 16-Bit Address-Spaces hat, also weder __memx noch __flashx.
:
Bearbeitet durch User
Johann L. schrieb: > Nö. Einspruch! xy.ino:
1 | // total leer
|
main.c:
1 | #include <arduino.h> |
2 | |
3 | const uint8_t __flash test[2]={1,2}; |
4 | |
5 | int main() |
6 | {
|
7 | return test[0] + test[1]; |
8 | }
|
Beide Dateien in einem Ordner, übersetzt ohne Fehler! Der Aufruf:
1 | "E:\\Programme\\arduino\\portable\\avr-gcc\\avr-gcc-15.2.0_mingw32_binutils2.45_avrLibc2.2.1\\bin\\avr-g++" -c -g -Os -w -std=gnu++23 -fno-exceptions -fpermissive -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -fmodules -Wall -Wextra -Wno-volatile -isystem "E:\\Programme\\arduino\\portable\\avr-libstdcpp2\\include" "-IE:\\Programme\\arduino\\portable\\packages\\arduino\\hardware\\avr\\1.8.6\\cores\\arduino" "-IE:\\Programme\\arduino\\portable\\packages\\arduino\\hardware\\avr\\1.8.6\\variants\\standard" "E:\\temp\\Arduino\\sketch\\main.c" -o nul |
Interessant! Natürlich sehe ich das -std=gnu++23 und auch das -x c++ Lasse ich das const in der main.c weg meldet es:
1 | main.c:3:18: error: variable 'test' must be const in order to be put into read-only section by means of '__flash' |
2 | 3 | uint8_t __flash test[2]={1,2}; |
3 | | ^~~~ |
Was auf jeden fall so richtig ist. Ändere ich die Endung auf main.cpp kommt folgende Meldung:
1 | main.cpp:3:23: error: expected initializer before 'test' |
2 | 3 | const uint8_t __flash test[2]={1,2}; |
3 | | ^~~~ |
Und jetzt du! Wie kommt es, dass in der *.c kein Fehler geworfen wird, wenn sich da ein __flash befindet. Und natürlich auch funktioniert, denn das habe ich vorher schon ein paar mal verwendet. Ich weiß es nicht.
:
Bearbeitet durch User
Arduino F. schrieb: > Der Aufruf: Da wird doch garnichts übersetzt, d.h. da sind keine TUs angegeben?
Keine Ahnung was Arduino da macht. Wenn du
1 | avr-g++ simple.c -v 2>&1 | grep cc1 |
Ist die Ausgabe:
1 | $prefix/bin/../libexec/gcc/$target/$version/cc1plus -quiet -v -iprefix $prefix/../lib/gcc/$target/$version/ simple.c ... |
Oder kommt bei dir cc1 statt cc1plus?
Johann L. schrieb: > Und wie ist da __flash definiert / implementiert? Gar nicht! Wird da nur für das uint8_t gebraucht. (könnte man auch anders erreichen) Johann L. schrieb: > Wenn du avr-g++ simple.c -v 2>&1 | grep cc1 Kein linux, kein grep Johann L. schrieb: > Keine Ahnung was Arduino da macht. Dürfte mit Arduino nix zu tun haben. Der Compiler ist nachträglich eingebunden. Arduino dümpelt noch bei GCC 7.3 oder so, und C++11 Ich nutze Gcc 15.2 mit C++23 mit der IDE Die gezeigte Zeile ist die einzige, in der main.c vorkommt. Johann L. schrieb: > TUs Aha... Was ist das? Kenne mindestens 10 TU Dinger, glaube aber, du meinst was anderes.
:
Bearbeitet durch User
Arduino F. schrieb: >> TUs > > Aha... > Was ist das? Wenn du etwas mehr zitiert hättest, wäre dir wohl aufgefallen, dass es in diesem Zusammen nur "translation unit" heißen kann.
Was hat diese Compiler- und IDE Diskussion mit Mikrocontrollern zu tun? Bitte verschieben!
Rainer W. schrieb: > Was hat diese Compiler- und IDE Diskussion mit Mikrocontrollern zu tun? Dass named address spaces (um diese geht es letztlich) vorrangig etwas für den Anwendungsfall "Mikrocontroller" sind. Bei einem Compiler für einen PC braucht man das nicht.
:
Bearbeitet durch Moderator
Arduino F. schrieb: > Johann L. schrieb: >> Wenn du avr-g++ simple.c -v 2>&1 | grep cc1 > Kein linux, kein grep Dann halt
1 | avr-g++ simple.c -v |
und du musst eben selber nach "cc1" suchen weil du nicht danach filtern kannst. > Johann L. schrieb: >> Keine Ahnung was Arduino da macht. > Dürfte mit Arduino nix zu tun haben. > Der Compiler ist nachträglich eingebunden. > Arduino dümpelt noch bei GCC 7.3 oder so, und C++11 > Ich nutze Gcc 15.2 mit C++23 mit der IDE GCC verhält sich konsistent; das Verhalten ändert sich ja nicht in jeder Version. GCC 5 macht das gleiche wie GCC 15: "g++ main.c" übersetzt als C++. Um das als C zu übersetzen brauch man "gcc main.c" oder "g++ -x c main.c". > Die gezeigte Zeile ist die einzige, in der main.c vorkommt. Das Kommando compiliert nicht sondern präprozessiert lediglich, weil -E angegeben ist! Du hast den COMPILERaufruf für main.c also noch nicht gefunden...
Johann L. schrieb: > Du hast den COMPILERaufruf für main.c also noch nicht gefunden... Noch mal nachgesehen. Du hast wahr. Ist mir gestern durch die Lappen gegangen.
1 | "E:\\Programme\\arduino\\portable\\avr-gcc\\avr-gcc-15.2.0_mingw32_binutils2.45_avrLibc2.2.1\\bin\\avr-gcc" -c -g -Os -Wall -Wextra -std=gnu11 -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IE:\\Programme\\arduino\\portable\\packages\\arduino\\hardware\\avr\\1.8.6\\cores\\arduino" "-IE:\\Programme\\arduino\\portable\\packages\\arduino\\hardware\\avr\\1.8.6\\variants\\standard" "E:\\temp\\Arduino\\sketch\\main.c" -o "E:\\temp\\Arduino\\sketch\\main.c.o" |
Johann L. schrieb: > Nö. g++ main.c ... übersetzt als C++ weil der C++ Compiler cc1plus > aufgerufen wird. Damit hast auch du dich geirrt. Jörg W. schrieb: > Wenn du etwas mehr zitiert hättest, wäre dir wohl aufgefallen, dass es > in diesem Zusammen nur "translation unit" heißen kann. Ein seltsamer Vorwurf... Anständig wäre: Die erste Verwendung einer Abkürzung mit einer Erklärung versehen. Merke: Lesen und verstehen, klappt manchmal. Zitieren ist eine andere Baustelle. Dass es deine TU ist, die da fehlt, ist mit nicht in den Sinn gekommen, da ja die main.c.o Datei klar vor meinen Augen liegt. Also im Endeffekt doch eine TU vorhanden.
Arduino F. schrieb: > Johann L. schrieb: >> Nö. g++ main.c ... übersetzt als C++ weil der C++ Compiler cc1plus >> aufgerufen wird. > Damit hast auch du dich geirrt. Wieso? Hast du ein Gegenbeispiel? > Noch mal nachgesehen. > Du hast wahr. Ist mir gestern durch die Lappen gegangen. > ...avr-gcc -c ... main.c -o ...main.c.o Also wird gcc verwendet, nicht g++. Und mithin nicht automatisch Arduino = C++.
:
Bearbeitet durch User
Johann L. schrieb: > Und mithin nicht automatisch Arduino = C++. Richtig! Viel von dem Basis Kram steckt in *.c Dateien, und wird auch so übersetzt. Weniges steckt in *.S Dateien, also Assembler. Der Rest, wie *.ino, Print, Serial und quasi alle Libraries sind C++ Aus dem 3er Pool, an Sprachen, kann man sich jeweils das raus suchen, was einem am besten schmeckt.
Johann L. schrieb: > Arduino F. schrieb: >> Aber *.c bleiben *.c und werden auch als C kompiliert. > > Nö. Johann L. schrieb: > Wieso? Hast du ein Gegenbeispiel? Das "Nö" ist an der Stelle falsch. Ein Gegenbeispiel habe ich geliefert, wenn auch etwas holperig.
Hallo, wie ist das denn nun auf dem Arduino zu machen, das wäre auch für mich mal interessant, oder geht es dort gar nicht? Ich stecke in diesem speziellen Thema kaum drin, und verstehe hier nur sehr wenig von der Materie - arbeite aber ab und an auch mit dem Arduino Zeug ...
Thorsten S. schrieb: > wie ist das denn nun auf dem Arduino zu machen, In *.c Dateien, ja. In *.cpp oder *.ino nicht. Thorsten S. schrieb: > oder geht es dort gar nicht? Den Beweis, dass es geht habe ich geliefert.
:
Bearbeitet durch User
Thorsten S. schrieb: > wie ist das denn nun auf dem Arduino zu machen Ist in den ersten Beiträgen besprochen worden. Bist du zu faul die paar Beiträge dieses Threads zu lesen?
Wastl schrieb: > Ist in den ersten Beiträgen besprochen worden. Bist du zu > faul Das Problem ist, dass die "Besserwisser" jede Antwort zerreden, auch wenn sie völlig richtig war. Es hat einen guten Grund, warum Arduino weiterhin auf das PROGMEM Makro setzt: Es funktioniert auf allen von Arduino unterstützten Plattformen ebenso, da es dort komoatibel implementiert wurde.
Nemopuk schrieb: > "Besserwisser" Du meinst dich? Nemopuk schrieb: > Es funktioniert auf allen von Arduino unterstützten Plattformen > ebenso, da es dort komoatibel implementiert wurde. Es ist auf allen Plattformen völlig Sinnfrei, außer AVR. Zu "komoatibel": Ja, man muss schon nahe am Koma sein, um Progmem auf ARM usw. nutzen zu wollen. Es ist eine reine AVR Krücke. Und selbst da gibt es mit dem __flash in C eine Abhilfe.
Warum landet hier eigentlich "const" ohne weitere Krücken nicht automagisch im Flash? Bin das vom armcc so gewöhnt.
Arduino F. schrieb: > In *.cpp oder *.ino nicht. okay, also im *.ino gehts also gar nicht - okay. Wastl schrieb: > Bist du zu > faul die paar Beiträge dieses Threads zu lesen? Ja, ich bin sehr faul. Nemopuk schrieb: > Es funktioniert auf allen von Arduino unterstützten Plattformen Also im *.ino dann doch? Arduino F. schrieb: > nahe am Koma sein, um Progmem auf > ARM usw. nutzen zu wollen. Also doch nicht im *.ino? @Wastl: merkst de wat? Arduino F. schrieb: >Ja, man muss schon nahe am Koma sein... Mir ist das völlig egal wie das intern gelöst ist, Hauptsache es geht - kann ich ja sowieso wohl eher nichts dran ändern... Random .. schrieb: > Warum landet hier eigentlich "const" ohne weitere Krücken nicht > automagisch im Flash? Bin das vom armcc so gewöhnt. Das war auch zu meinen AVR-Studio Zeiten mal eine Frage von mir - fände es auch "logischer" aber der Hintergrund von const geht wohl nicht soweit - checkt nur ob es Zugriffe gibt, welche die Variable verändern, nicht wo sie wie abgelegt ist - hoffe habe das richtig ausgedrückt mit meinem eher laienhaften Wissen an der Stelle...
:
Bearbeitet durch User
Thorsten S. schrieb: > okay, also im *.ino gehts also gar nicht - okay. Die PROGMEM Geschichte geht, auch auf AVR Arduino in *.ino oder *.cpp die __flash Geschichte nur in *.c Dateien. Random .. schrieb: > Warum landet hier eigentlich "const" ohne weitere Krücken nicht > automagisch im Flash? Bin das vom armcc so gewöhnt. ARM hat nur einen Adressbus. AVR hat 2 Adressbusse. Darum der "Sonderzugriff" AVR ist halt mehr Harvard als ARM https://de.wikipedia.org/wiki/Harvard-Architektur
:
Bearbeitet durch User
Arduino F. schrieb: > Die PROGMEM Geschichte geht Danke, okay - wie muss ich denn die Headerdatei einbinden: #include <avr/pgmspace.h> bzw. gibt es die dort überhaupt oder heißt sie andern? Arduino F. schrieb: > AVR ist halt mehr Harvard als ARM Habe früher mit PICs in Assembler gearbeitet, dort wird alles mit Takt/4 betrieben. Als ich mit den AVR anfing, war ich überrascht dass sie das Hiolen von zwei Operaden, deren Addition und die Ablage des Ergebnisses in einem Haupttakt schaffen... Wahnsinn, wenn man vorher mit PICs gearbeitet hat...
:
Bearbeitet durch User
Thorsten S. schrieb: > bzw. gibt es die dort überhaupt oder heißt sie andern? Was soll die Frage? Über welchen µC redest du da?
Random .. schrieb: > Warum landet hier eigentlich "const" ohne weitere Krücken nicht > automagisch im Flash? Bin das vom armcc so gewöhnt. Weil man mit anderen Befehlen auf den Flash zugreifen muss. puts() kann z.B. nur Strings aus dem RAM ausgeben.
Thorsten S. schrieb: > #include <avr/pgmspace.h> > bzw. gibt es die dort überhaupt oder heißt sie andern? Mal ein ganz schräger Vorschlag: Lies die Doku von Arduino! https://docs.arduino.cc/language-reference/de/variablen/utilities/PROGMEM/
Random .. schrieb: > Warum landet hier eigentlich "const" ohne weitere Krücken nicht > automagisch im Flash? Eine Erklärung fundes sich zum Beispiel in der AVR-LibC FAQ: Why do all my string literals eat up the SRAM? https://avrdudes.github.io/avr-libc/avr-libc-user-manual-2.3.0/FAQ.html#faq_flashstrings
Arduino F. schrieb: > Was soll die Frage? Es ging nicht, ich hatte immer eine Fehlermeldung das "Progmem" unbekannt ist, dachte ich. Nemopuk schrieb: > Mal ein ganz schräger Vorschlag: Lies die Doku von Arduino! Der Fehler lag zwischen meinen Ohren, dich hatte das "const" vergessen. Danke Euch, für die Geduld.
Thorsten S. schrieb: > in einem Haupttakt schaffe Es war mir eh ein Rätsel, wie man das Holen von Operanden in einem Takt schafft, man muss ja eine Adresse auf den Bus legen, an den Speicher anlegen, der Wert der Zelle muss auch auf den Datenbus und dann in die Arbeitsregister der ALU usw... das geht ja dann alles nur mit einer Taktvervielfäligung. Wenn man also den Atmega mit einem 20 Mhz Quarz bestückt, muss er intern schon mit 80 Mhz arbeiten... https://microcontrollerslab.com/wp-content/uploads/2017/05/pic-microocntroller-architecture-block-diagram.gif https://www-user.tu-chemnitz.de/~heha/hs/chm/ATmegaX8.chm/7.htm Dazu kommt das Problem, dass man beim PIC alles erstmal über das W-Register bewegen muss - im Gegensatz zum AVR noch ein gravierender Leistungsnachteil... warum auch immer man das beim PIC so macht/gemacht hat - eine Zeile Assembler im AVR entspricht damit nochmals schnell min. vier Zeilen Assembler beim PIC... Aber das ist ein anderes Thema...
:
Bearbeitet durch User
Thorsten S. schrieb: > Es war mir eh ein Rätsel, wie man das Holen von Operanden in einem Takt > schafft, man muss ja eine Adresse auf den Bus legen, an den Speicher > anlegen, der Wert der Zelle muss auch auf den Datenbus und dann in die > Arbeitsregister der ALU usw... das geht ja dann alles nur mit einer > Taktvervielfäligung. Sieh Dir mal einen 6502 an. Der kann in einem Takt ein Operand aus dem Speicher in ein Register laden. In der ersten Hälfte des Takts wird die Adresse auf den Bus gelegt und in der zweiten Hälfte des Takts der vom Speicherbaustein an den Datenleitungen angelegte Wert übernommen. Da braucht es keine Taktvervielfältigung. Und das ist der Grund, warum ein mit 1 MHz getakteter 6502 geschwindigkeitsmäßig mit einem mit 4 MHz getaktetem Z80 vergleichbar war - letzterer zerlegte einen Buszyklus in mehrere Takte.
Thorsten S. schrieb: > Es war mir eh ein Rätsel, wie man das Holen von Operanden in einem Takt > schafft, man muss ja eine Adresse auf den Bus legen, an den Speicher > anlegen, der Wert der Zelle muss auch auf den Datenbus und dann in die > Arbeitsregister der ALU usw... das geht ja dann alles nur mit einer > Taktvervielfäligung. Wenn man also den Atmega mit einem 20 Mhz Quarz > bestückt, muss er intern schon mit 80 Mhz arbeiten... AVRs haben eine 2-stufige Pipeline. In Stage 1 geschieht Instruction-Fetch, in Stage 2 Execute
1 | Takt1 Takt2 Takt3 ... |
2 | Fetch1 Exec1 |
3 | Fetch2 Exec2 ... |
4 | Fetch3 ... |
Johann L. schrieb: > In Stage 1 geschieht > Instruction-Fetch, in Stage 2 Execute Ach so geht das... jau, daran habe ich gar nicht gedacht...wieder was gelernt. Aber auch die mehrfachen Arbeitsregister und das diese direkt für beide Eingänge der ALU greifbar sind, sind ein wesentlicher Vorteil... Die Anordnung im PIC ist dagegen eine echte Krücke... wie ich finde. Gibt es für diese internen Strukturen eigentlich irgendeine Art Fachbezeichung? Stimmt das so: Ein-Adress-Architektur / PIC Zwei-Adress-Architektur Drei-Adress-Architektur / AVR
:
Bearbeitet durch User
Thorsten S. schrieb: > Wenn man also den Atmega mit einem 20 Mhz Quarz > bestückt, muss er intern schon mit 80 Mhz arbeiten... Johann L. schrieb: > AVRs haben eine 2-stufige Pipeline. In Stage 1 geschieht > Instruction-Fetch, in Stage 2 Execute Dazu kommt, das der Programmspeicher 16 Bit breit ist. Ein "Fetch" liest zwei Byte am Stück. Eeil der AVR zwei interne Busse hat, kann zudem gleichzeitig einen Operanden aus dem RAM Laden und den nächsten Befehl aus dem Flash.
:
Bearbeitet durch User
Nemopuk schrieb: > Aber er hat halt zwei Busse Jau, Harvard, das hat der PIC auch. Nemopuk schrieb: > und der Programmspeicher ist zudem auch > noch 16 Bit breit. Der Mikrocode wäre interessant... aber damit geht sicher kein Hersteller hausieren... Nemopuk schrieb: > Eeil der AVR zwei interne Busse hat, kann zudem gleichzeitig einen > Operanden aus dem RAM Laden und den nächsten Befehl aus dem Flash. Heiße Kiste
:
Bearbeitet durch User
Thorsten S. schrieb: > Der Mikrocode wäre interessant.. Ich bezweifle, das AVR Mikroconde haben. Wenn sie welchen haben, dann höchstens für das Beschrieben des Flash Speichers.
Thorsten S. schrieb: > Der Mikrocode wäre interessant... Vielleicht hilft ja FPGA Soft Core: AVR. Ist aber immer noch die Frage, ob eine FPGA-Implementierung analog zu einem echten AVR ist.
Nemopuk schrieb: > Ich bezweifle, das AVR Mikroconde haben Mikrocode = Befehldekoder... Johann L. schrieb: > Vielleicht hilft ja FPGA Soft Core: AVR. Eine witzige Idee - aber FPGAs sind nicht mein Fachgebiet, leider nie programmiert, genutzt. In der Darstellung: https://www-user.tu-chemnitz.de/~heha/hs/chm/ATmegaX8.chm/7.htm Fehlt irgendwie das Pipelining, ist wohl ebenso Teil der Befehlsdekodierung... Es müssen ja immer zwei Befehle zeitgleich dekodiert werden, da müssten dann eigentlich zwei Dekoder sein, und ggf. gibt es ja Befehle die nicht zeitgleich ausgeführt werden können, vielleicht so etwas wie eine Addition und ein Shift...da steckt richtig Schmalz in der Logik... total interessant... Da bin ich wirklich froh, dass man diese Technik auf dem heutigen Niveau einfach für 3€ kaufen und direkt nutzen kann...auch wenn die allgemeine Ehrfurcht sicher sehr darunter leidet...
:
Bearbeitet durch User
Thorsten S. schrieb: > Mikrocode = Befehldekoder... Nee. Microcode, wenn vorhanden, übernimmt die Aufgabe des Befehlsdecoders, aber ein Befehlsdecoder ist kein Microcode, sondern normalerweise einfach ein Gattergrab. Sieh Dir den 6502 an - der besteht aus gerade mal 4500 Transistoren ... Microcode kann nach der Herstellung der CPU verändert werden (wie die bei Intel-CPUs mittlerweile üblichen Microcodeupdates deutlich zeigen), das Gattergrab klassischer Befehlsdecoder hingegen nicht.
Arduino F. schrieb: > Thorsten S. schrieb: >> okay, also im *.ino gehts also gar nicht - okay. > > Die PROGMEM Geschichte geht, auch auf AVR Arduino in *.ino oder *.cpp > die __flash Geschichte nur in *.c Dateien. > > Random .. schrieb: >> Warum landet hier eigentlich "const" ohne weitere Krücken nicht >> automagisch im Flash? Bin das vom armcc so gewöhnt. > ARM hat nur einen Adressbus. > AVR hat 2 Adressbusse. Darum der "Sonderzugriff" > AVR ist halt mehr Harvard als ARM > https://de.wikipedia.org/wiki/Harvard-Architektur Klar, nur sollte das nicht im Compiler lösbar sein?
Random .. schrieb: > Klar, nur sollte das nicht im Compiler lösbar sein? Nicht in C. Ich nehme mal wieder puts() als Beispiel. Die puts() Funktion erwartet die Adresse des Strings im RAM, denn so ist die Funktion im C Standard spezifiziert. Um stattdessen auf FLASH zuzugreifen hat man folgende Möglichkeiten: a) RAM und Flash lassen sich anhand unterschiedlicher Adressbereiche unterscheiden. Das haben wir bei ARM Cortex-M Controllern. b) Man führt einen zusätzliches Funktions-argument zur Unterscheidung ein. Innerhalb der Funktion könnte dann ein if/else je nach Parameter auf RAM oder FLASH zugreifen. Dann ist es aber nicht mehr zum Standard kompatibel. c) Man bietet eine zweite Variante der Funktion an, die auf den FLASH Speicher zugreift. Diesen Weg geht die AVR Libc: puts_P() In C++ haben wir eine Möglichkeit mehr: d) Wir stellen mehrere Varianten der Funktion/Methode bereit, und der Compiler wählt die passende anhand des Typs des Zeigers aus. Diesen Weg geht Arduino.
:
Bearbeitet durch User
Nemopuk schrieb: > Random .. schrieb: >> Klar, nur sollte das nicht im Compiler lösbar sein? > > Nicht in C. Geht auch in C, kostet dann aber: "generic pointers", d. h. jeder Zeiger wird extra so verändert, damit er den Adressraum, zu dem er gehört, noch mit transportieren kann. Überall da, wo über den Zeiger zugegriffen wird, muss dann als erstes eine Fallunterscheidung gemacht werden. Da sich AVR mittlerweile angesichts der Konkurrenz der 32bitter eher auf kleinere Controller konzentriert, gibt es dort dann auch tatsächlich wieder einen unified address space, mit dem es ohne weitere Umstände möglich wäre, mit nur einer einzigen Art 16-bit-Zeiger auszukommen. Aber das war historisch eben anders.
Jörg W. schrieb: > Da sich AVR mittlerweile angesichts der Konkurrenz der 32bitter eher auf > kleinere Controller konzentriert, gibt es dort dann auch tatsächlich > wieder einen unified address space, mit dem es ohne weitere Umstände > möglich wäre, mit nur einer einzigen Art 16-bit-Zeiger auszukommen. Wie ist "gibt es" zu verstehen? Gibt es neue AVRs, die das so machen? Oder meintest Du "könnte es geben"?
Harald K. schrieb: > Gibt es neue AVRs, die das so machen? Ja, gibt es. Schau dich einfach mal um. Schon ATtiny817 und Verwandte können das, auch ATmega4809 (hier passt jeweils der komplette Flash in den Adressraum). Bei den neueren AVR-Serien (DA, DB und wie sie alle heißen) hängt es von der Flash-Größe ab: nur maximal 32 KiB Flash lassen sich in den normalen Adressraum abbilden, alles darüber hinaus ist nur traditionell zugreifbar.
Harald K. schrieb: > Gibt es neue AVRs, die das so machen? Ja. Siehe zum Beispiel die Tabelle in https://avrdudes.github.io/avr-libc/avr-libc-user-manual-2.3.0/FAQ.html#faq_flashstrings Die AVR Tools unterstüzten 97 Devices mit 100% linearem Adressraum, d.h. der komplette Programmspeicher ist per LDD/LDS erreichbar. Außerdem werden 36 Devices unterstützt, die lediglich 32 KiB des Programmspeichers im LDD/LDS-Adressraum sehen. Auf diesen Devices liegt rodata im Flash, ist aber auf 32 KiB limitiert. (Es sei denn man verwendet -mrodata-in-ram, was rodata ins RAM lokatiert wie auf den alten Devices. In diesem Fall ist rodata nicht auf 32 KiB limitiert, und rodata kann 32 KiB Segmentgrenzen überschreiten, was mit rotata-in-flash nicht möglich ist.) AVRs mit linearem Adressraum gibe es seit ca. 2016 mit Release der AVRrc (Reduced Core).
:
Bearbeitet durch User
Nemopuk schrieb: > d) Wir stellen mehrere Varianten der Funktion/Methode bereit, und der > Compiler wählt die passende anhand des Typs des Zeigers aus. Diesen Weg > geht Arduino. Naja, braucht dann aber Inline Asm; in C++ die einzige Möglichkeit, ein LPM zu bekommen.
Random .. schrieb: > Klar, nur sollte das nicht im Compiler lösbar sein? Wunsch und Realität gehen manchmal auseinander. Der Gcc tuts für Unmengen an Prozessoren, jeglicher Größe. AVR ist da eher ein unwichtiger Sonderfall, welcher weder vom C als auch vom C++ Standard abgehandelt wird
Arduino F. schrieb: > welcher weder vom C als auch vom C++ Standard abgehandelt wird Ich glaube mich zu erinnern, dass named address spaces in C zumindest vorgeschlagen wurden (N3723). Hab's aber nicht verfolgt. Autor ist (wen wundert's :) Philip Klaus Krause, Maintainer des SDCC.
Arduino F. schrieb: > Random .. schrieb: >> Klar, nur sollte das nicht im Compiler lösbar sein? > > Der Gcc tuts für Unmengen an Prozessoren, jeglicher Größe. > AVR ist da eher ein unwichtiger Sonderfall, welcher weder vom C als auch > vom C++ Standard abgehandelt wird Die aktuelle AVR Implementation des GCC für AVR (ohne GNU-Erweiterungen) entspricht dem C/C++ Sprachstandard. (Ok, es gibt Ausnahmen die Exceptions, STL, 32-Bit double etc.) Und die möglichen, aber nicht gewählten Implementationen, die Jörg erwähnte, wären ebenfalls kompatibel mit dem C/C++ Standard. C/C++ spezifizeren eine abstrakte Maschine, die auf mehr als eine Weise implementiert werden kann, und dass der tatsächlich beschrittene Weg "weder vom C noch vom C++ Standard abgehandelt" wird, ist Käse.
Jörg W. schrieb: > Ja, gibt es. Schau dich einfach mal um. Johann L. schrieb: > Ja. Siehe zum Beispiel die Tabelle ... Danke an Euch beide. Das bedeutet, daß auf denen der ganze "pgmspace.h"-Kram restlos entfallen kann, oder könnte.
Johann L. schrieb: > "weder vom C noch vom C++ Standard abgehandelt" wird, ist Käse. C als auch C++ gehen von einem linear adressierten Speicher aus. Die AVR spezifische Flash Abhandlung ist nicht im Sprachstandard behandelt.
Harald K. schrieb: > Das bedeutet, daß auf denen der ganze > "pgmspace.h"-Kram restlos entfallen kann, oder könnte. Ja. Wobei das von den Tools unterstützt werden muss. Für die x-Series Devices zum Beispiel ab GCC 8, also seit ca. 2018. Für die Devices, die nur einen Teil des Flashs im LD-Adressraum sehen, braucht man https://sourceware.org/PR31124, also Binutils 2.42 oder neuer. Der vom Compiler erzeugte Code ist wie gesagt der selbe. Zum Vergleich PROGMEM vs. open-coded C/C++ ist anzumerken: * Mit PROGMEM / __flash muss das Z-Register verwendet werden, ohne PROGMEM hat der Compiler mehr Adressregister und -modi zur Verfügung, was sich positiv auf die Codedichte auswirken kann. Z.B. kann Indirek+Offset Adressierung verwendet werden; mit PROGMEM / __flash geht das nicht. * PROGMEM ist nicht transparent, open-coded C/C++ hingegen schon. * Teilweise ist der Code ohne PROGMEM schlechter, etwa wenn man per __flash eine 64-Bit Variable liest. Das ist der Grund, warum es in der AVR-LibC Funktionen wie flash_read_u64() gibt: https://avrdudes.github.io/avr-libc/avr-libc-user-manual-2.3.0/group__avr__flash.html#ga368f51c58ca62b924e33046666512d92 (AVR-LibC 2.3 ist noch nicht released) Arduino F. schrieb: > Johann L. schrieb: >> "weder vom C noch vom C++ Standard abgehandelt" wird, ist Käse. > C als auch C++ gehen von einem linear adressierten Speicher aus. Und das ist genau das, was die AVR Tools implementieren. Nicht optimal, aber Optimalität ist keine C/C++ Anforderung.
:
Bearbeitet durch User
Danke für die weiteren Hintergrundinformationen. Johann L. schrieb: > open-coded ? Meinst Du damit "ganz normal"?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.