Hallo, Seit 4.7.0 kennt avr-gcc ja das Schlüsselwort "__flash", was den Umgang mit Daten im Flash stark vereinfacht. Davor musste man ja den Zugriff über verschiedene Funktionen regeln. Ich habe auf die schnelle nichts dazu gefunden. Gibt es so ein Äquivalent eigentlich auch für Daten im EEPROM?
bal schrieb: > Gibt es so ein Äquivalent eigentlich auch für Daten im EEPROM? Scheint Johann nicht implementiert zu haben. Da das Framework für die named address spaces jetzt da ist, wäre das ja vielleicht mal eine Übung für einen Compiler-Einsteiger. :-)
Ok, hab ich mir gedacht, aber ist ja auch nicht so tragisch :-) Noch eine Frage zu EEMEM: dadurch landet die Variable ja im EEPROM. Der Zugriff darauf erfolgt allerdings durch Funktionen. Angenommen ich ändere jetzt recht viel im Programm, sprich: neue c-Dateien kommen hinzu, die wiederum EEMEM-Werte beinhalten. Kann es denn vorkommen, dass sich die Adressen im EEPROM ändern? Nach einer großen Änderung und einem BUILD-ALL kann ja der Linker nicht mehr wissen, wo er eine Variable beim letzten Compilerlauf hingelegt hat. Wenn ich danach mein Programm flashe (ohne eep-Datei) dann kann es doch zu Inkonsistenzen kommen, weil vielleicht "foo" dort liegt wo letztesmal noch "bar" lag. Oder wird das irgendwie verhindert?
bal schrieb: > Kann es denn vorkommen, dass sich die Adressen im EEPROM ändern? Ja, kann. > Nach > einer großen Änderung und einem BUILD-ALL kann ja der Linker nicht mehr > wissen, > wo er eine Variable beim letzten Compilerlauf hingelegt hat. Du sagst es. > Oder wird das irgendwie verhindert? Nö. Ist dein Bier.
Karl Heinz Buchegger schrieb: > Ist dein Bier. Kann man dadurch umgehen, dass man genau eine große struct anlegt im EEPROM, in der man alles ablegt. Wenn man diese später am Ende erweitert, bleiben die bereits existierenden Daten an Ort und Stelle.
Ja so kenn ichs auch, bzw hab ich schonmal auf einer anderen Plattform so gehandhabt. Da war das EEPROM aber über SPI angebunden, also eh komplett "am Compiler vorbei", deswegen war ich mir hier nicht sicher. Danke!
Entweder du kümmerst dich selber darum, wie und wo die Daten im EPROM abgelegt werden oder lässt es den Compiler machen.
Jörg Wunsch schrieb: > bal schrieb: >> Gibt es so ein Äquivalent eigentlich auch für Daten im EEPROM? > > Scheint Johann nicht implementiert zu haben. Das gehört m.E. auch nicht in den Compiler, denn es würde viel zu viel explizites Wissen über das Derivat erfordern. Oder eine weitere Verzahnung mit der AVR-LibC, was pronzipiell nicht wünschenswert ist. Momentan sind Address Spaces (ISO/IEC TR 18037 Annex B.1.2) nicht vollständig im GCC umgesetzt, es fehlen nämlich die User Defined AS mit denen aus Applikationsebene neue AS eingeführt werden. Die Zugriffsfunktionen implementiert dabei ebenfalls die Anwendung. Diese User Defined AS in GCC einzubauen ist allerdings keine Anfängerübung...
Johann L. schrieb: > Das gehört m.E. auch nicht in den Compiler, denn es würde viel zu viel > explizites Wissen über das Derivat erfordern. Oder eine weitere > Verzahnung mit der AVR-LibC, was pronzipiell nicht wünschenswert ist. Naja, man könnte sich auf Funktionen wie __avr_eeprom_read_byte und __avr_eeprom_write_byte stützen, dies so dokumentieren und es dann dem Endanwender überlassen, auf welchem Wege er diese bereitstellt.
Wärs nicht möglich, das mit den user-defined AS dem Compiler beizubringen und __eeprom dann darüber, aber in der avr-libc, zu lösen?
Nils S. schrieb: > Wärs nicht möglich, das mit den user-defined AS dem Compiler > beizubringen Sicherlich wäre es. Ist halt nur eine Frage des Aufwands. Eine grundlegende Abschätzung diesbezüglich hat Johann ja implizit oben gegeben. ;-)
Ok, also doch eine Fingerübung für GCC Einsteiger... Freiwillige vor!
Gibt es eigentlich eine Aussicht auf Erbschaft der AS in Richtung g++?
Nein, noch nichma trübe Aussichten. Mit Bordmitteln von C++ lässt sich das doch bestimmt abbilden, genauso wie die Fixed-Point Arithmetik von Embedded-C. Ansonsten hat C++ m.E. versagt. Die Hauptarbeit in GCC sind momentan: - Neue Sprachfeatures wie C++11 und C++14. - Support für Transactional Memory - Bessere (Auto-)Vectorisierung Am "unteren" Ende in Richting Resource-beschränker Handware wird eigentlich nix mehr gearbeitet; die ENtwicklung geht komplett in Richtung der Boliden...
Johann L. schrieb: > Nein, noch nichma trübe Aussichten. > > Mit Bordmitteln von C++ lässt sich das doch bestimmt abbilden, genauso > wie die Fixed-Point Arithmetik von Embedded-C. Müsste gehen. Eine Klasse FlashPointer machen. Der dann den Dereferenzierungsoperator abbilden und was man sonst noch so an Konstruktoren braucht und man sollte damit im Rennen sein. (Arduino hats ja meines Wissens vorgemacht) > Am "unteren" Ende in Richting Resource-beschränker Handware wird > eigentlich nix mehr gearbeitet; die ENtwicklung geht komplett in > Richtung der Boliden... Wie üblich. Die Kleinen können sehen, wo sie bleiben.
Karl Heinz Buchegger schrieb: > Johann L. schrieb: >> Nein, noch nichma trübe Aussichten. >> >> Mit Bordmitteln von C++ lässt sich das doch bestimmt abbilden, genauso >> wie die Fixed-Point Arithmetik von Embedded-C. > > Müsste gehen. > Eine Klasse FlashPointer machen. Der dann den Dereferenzierungsoperator > abbilden und was man sonst noch so an Konstruktoren braucht und man > sollte damit im Rennen sein. > > (Arduino hats ja meines Wissens vorgemacht) Mit nicht-POD ist man aber aus dem Rennen, weil eine nicht-POD Klasse im RAM angelegt wird. Da schießt sich C++ dann selbst ins Knie. >> Am "unteren" Ende in Richting Resource-beschränker Handware wird >> eigentlich nix mehr gearbeitet; die Entwicklung geht komplett in >> Richtung der Boliden... > > Wie üblich. Die Kleinen können sehen, wo sie bleiben. Die Kleinen sind aber selbst schuld. Wer nicht mitarbeitet, braucht auch nicht zu erwarten, daß die ENtwiklung in die gewünschte Richtung geht und plötzlich Manna vom Himmel fällt :-/ Warum sollte z.B. Google oder IBM oder ARM Contributions machen, die µCs helfen mit ein paar k Flash und noch weniger RAM?
Johann L. schrieb: > Mit Bordmitteln von C++ lässt sich das doch bestimmt abbilden, genauso > wie die Fixed-Point Arithmetik von Embedded-C. Auch wieder wahr. Zumindest solange __flash nicht allgemein Einzug in alle möglichen Header findet. Okay, die Gefahr ist vermutlich noch lange eine theoretische. Karl Heinz Buchegger schrieb: >> Am "unteren" Ende in Richting Resource-beschränker Handware wird >> eigentlich nix mehr gearbeitet; die ENtwicklung geht komplett in >> Richtung der Boliden... > > Wie üblich. Die Kleinen können sehen, wo sie bleiben. Ein nicht unwesentlicher Grund, warum ich immer wieder gerne die kleinen Dinger nehme. Schöner Ausgleich zum sich den ganzen Tag mit den Produkten der Speicher-kost-ja-nix-Generation rumärgern, deren Hello World auf einem System mit 64 GiB RAM noch den OOM-Killer vollbeschäftigt kriegt :/
Hab schon mal versucht __eeprom in den GCC zu bekommen. Das es erkannt wird ist kein Problem, aber leider unterscheidet die aktuelle Implementierung an diversen Stellen nur "Standard" oder "irgend eine Art von Flash". Ich hätte mir da jeweils was case-artiges gewünscht, bei dem ich dann einfach "case EEPROM" ergänzen kann. So wird nun für alle nicht-RAM Zugriffe einfach FLASH Zugriff erzeugt. Leider reichen meine Fähigkeiten/Erfahrung nicht aus, die über die ganze AVR Code-Generierung verteilten Stellen erfolgreich anzupassen (Hut ab vor Gjlayde). Es müßte ja auch nicht unbedingt R/W sein, Lesen aus Eeprom ohne Funktions-Aufruf wäre ja auch schon ganz nett.
Bastler schrieb: > Hab schon mal versucht __eeprom in den GCC zu bekommen. > Das es erkannt wird ist kein Problem, aber leider unterscheidet die > aktuelle Implementierung an diversen Stellen nur "Standard" oder "irgend > eine Art von Flash". Ich hätte mir da jeweils was case-artiges > gewünscht, bei dem ich dann einfach "case EEPROM" ergänzen kann. > So wird nun für alle nicht-RAM Zugriffe einfach FLASH Zugriff erzeugt. Hier sind wohl die Funktionen avr_decl_flash_p (tree decl) avr_decl_memx_p (tree decl) avr_mem_flash_p (rtx x) avr_mem_memx_p (rtx x) avr_progmem_p (tree decl, tree attributes) avr_nonconst_pointer_addrspace (tree typ) aus avr.c zu erweitern, bzw. deren Caller. > Es müßte ja auch nicht unbedingt R/W sein, Lesen aus Eeprom ohne > Funktions-Aufruf wäre ja auch schon ganz nett. __eeprom zu unterstützen ohne die zugrundeliegenden Funktionen zu implementieren halte ich irgendwie für witzlos. Zumal die Funktion nicht in C stehen darf weil der Compiler von einem bestimmten ABI ausgehen muss. Alle call-clobbererd Register als zerstört anzusehen wäre der Overkill und zudem ein sekundärer Reload. Weiters ist auch movmem anzupassen, d.h. Struct- und Union-Zuweisungen.
daß das Ganze nur Sinn macht, wenn ALLES Notwendige Implementiert ist, war mir auch klar ;-) Zudem ist hoffenlich aus meinem Text zu entnehmen, daß ich das nicht als trivial ansehe und eigentlich nur beschreiben wollte, woran ich schon früh gescheitert bin. Wesentlich Erkenntnis war auch, daß das AVR-Backend offenbar anderst aufgebaut ist, als es für eine einfache Erweiterung notwendig wäre. (Völlig neutral betrachtet und ohne irgendeinen Vorwurf) Ich werde mir nochmal die genannten Stellen anschauen ;-)
Bastler schrieb: > Zudem ist hoffenlich aus meinem Text zu entnehmen, daß ich das nicht als > trivial ansehe und eigentlich nur beschreiben wollte, woran ich schon > früh gescheitert bin. Bei Tage betrachtet und bei Licht, ist nichts im GCC trivial... Falls du ernsthaft was zum GCC beitragen willst und nicht nur ein bisschen Rumspielen, ist m.E. was einfacheres angesagt. Genauso wie man bei einem µC nicht gleich mit ner eigenen Quadcopter-Steuerung anfängt sondern mit ner Binky-LED. Biespiel: PR57506 Das schwierigste beim Einstieg in die GCC-Entwicklung ist nämlich, die Änderung überhaupt in die Codebasis hinein zu bekommen, mal abgesehen vom Testing. Wie man __eeprom testen würde weiß ich auch nicht, denn der verwendete Simulator avrtest ist ein reiner Core-Simulator ohne Simulation der (internen) I/O. > Wesentlich Erkenntnis war auch, daß das AVR-Backend offenbar anderst > aufgebaut ist, als es für eine einfache Erweiterung notwendig wäre. Viele neurern Änderungen sind no-Op Änderungen, haben also keinen Einfluß auf die Codeerzeugung: Bessere Dokumentation, Build-Warnings beseitigen, Code aufräumen und besser strukturieren und kommentieren, etc. Da gibt's bestimmt noch viele verbesserungswürdige Stellen.
Johann L. schrieb: > denn der verwendete Simulator avrtest ist ein reiner Core-Simulator ohne > Simulation der (internen) I/O Wobei es sicher die Übung zum Warmwerden ist, ihm ein simples EEPROM-Handling noch beizubiegen. ;-)
Jörg Wunsch schrieb: > Johann L. schrieb: >> denn der verwendete Simulator avrtest ist ein reiner Core-Simulator ohne >> Simulation der (internen) I/O > > Wobei es sicher die Übung zum Warmwerden ist, ihm ein simples > EEPROM-Handling noch beizubiegen. ;-) Ist jetztz nicht dein Ernst. Simulation von 200 unterschiedlichen EE-SFRs der Myriaden von AVR-Derivaten? Ich klopp das da nicht rein.
Johann L. schrieb: > Simulation von 200 unterschiedlichen EE-SFRs der Myriaden von > AVR-Derivaten? Xmega müsste ich nachgucken (macht der avrsim das überhaupt schon?), aber bei normalen AVRs gibt's praktisch nur zwei verschiedene Implementierungen. Die ältere benutzt die Register auf 0x1c, 0x1d, 0x1e/0x1f für EECR, EEDR und EEAR, die neuere benutzt 0x1f, 0x20, 0x21/0x22. Hatten wir früher auch in der avr-libc so abstrahiert, aber dann hat mal jemand einen Heisenbug der Tatsache zugeordnet, dass damit auf sehr kleinen AVRs das dort undefinierte Register EEARH beschrieben wird und dass das ja wohl nicht gut sei, und dann wurde mit aller Gewalt eine per-device-Implementierung reingehämmert. Find' ich bis heute noch nicht gut so.
Jörg Wunsch schrieb: > Johann L. schrieb: >> Simulation von 200 unterschiedlichen EE-SFRs der Myriaden von >> AVR-Derivaten? > > Xmega müsste ich nachgucken (macht der avrsim das überhaupt schon?), avrsim sagt mir nix; avr-gcc verwendet avrtest. Und ja, er kann XMEGA. http://sourceforge.net/p/winavr/code/HEAD/tree/trunk/avrtest/ > aber bei normalen AVRs gibt's praktisch nur zwei verschiedene > Implementierungen. Die ältere benutzt die Register auf 0x1c, 0x1d, > 0x1e/0x1f für EECR, EEDR und EEAR, die neuere benutzt 0x1f, 0x20, > 0x21/0x22. Hatten wir früher auch in der avr-libc so abstrahiert, > aber dann hat mal jemand einen Heisenbug der Tatsache zugeordnet, Heisenbug lol, der ist gut! :-)) > dass damit auf sehr kleinen AVRs das dort undefinierte Register > EEARH beschrieben wird und dass das ja wohl nicht gut sei, und dann > wurde mit aller Gewalt eine per-device-Implementierung reingehämmert. Vorteil von avrtest ist, daß er schnell ist. Die gesamte Testsuite mit über 100.000 Tests durchzunudeln braucht auf einem Single-Core deutlich weniger als 1 Stunde. Bevor man exotoische Sachen wie EEPROM einbaut, sollten vielleicht erst mal IRQs unterstützt werden, etwa mit per Option vorgegebener IRQ-Last. Momentan ist avrtest noch schön einfach und schnell; i.w. eine C-Datei.
Johann L. schrieb: > avrsim sagt mir nix; avr-gcc verwendet avrtest. Und ja, er kann XMEGA. Ja, avrtest meinte ich natürlich. Ich habe bei Xmega noch nichts mit EEPROM gemacht. Wenn ich das richtig lese, kann man wohl dort im memory-mapped-Modus sogar den EEPROM wie SRAM beschreiben. Das wäre ja super einfach. > Heisenbug lol, der ist gut! :-)) Wenn du hinguckst, isser weg. :) Naja, das war völlig ominös, keiner hat das Verhalten jemals irgendwo nachvollziehen können, was da berichtet worden ist, aber es musste dann ganz plötzlich der undefinierte Zugriff auf EEARH schuld gewesen sein. > Vorteil von avrtest ist, daß er schnell ist. Gut, aber das würde der Sache ja keinen Abbruch tun.
Jörg Wunsch schrieb: > Ich habe bei Xmega noch nichts mit EEPROM gemacht. Wenn ich das > richtig lese, kann man wohl dort im memory-mapped-Modus sogar den > EEPROM wie SRAM beschreiben. Das wäre ja super einfach. Trifft das nicht auch auf den Flash zu? Damit käme man komplett ogne pgm_read und progmem und __flash aus -- zumindest auf den kleineren Derivaten, wo das genze Speicher-Geraffel in 64k passt. Einzig ein anderes Linkerscript, das .rodata richtig legt, wäre nötig. >> Vorteil von avrtest ist, daß er schnell ist. > > Gut, aber das würde der Sache ja keinen Abbruch tun. Doch, schon. Bei /jedem Speicherzugriff muss getestet werden, ob die Adresse vielleicht EECR ist. Oder EEDR. Oder EEAR. Teilweise gibt's auch Magie in den SFRs, nämlich für 4 Ticks IRQs sperren oder so, was weitere Zeit kostet -- und in 99.9% der Fälle nicht zutrifft.
Johann L. schrieb: > Trifft das nicht auch auf den Flash zu? Nein, denn der muss immer seitenweise gelöscht und neu beschrieben werden. >>> Vorteil von avrtest ist, daß er schnell ist. >> >> Gut, aber das würde der Sache ja keinen Abbruch tun. > > Doch, schon. Bei jedem Speicherzugriff muss getestet werden, ob die > Adresse vielleicht EECR ist. Da aber bereits andere SFRs emuliert sein müssen (SREG, SPL, SPH), sollte die Einführung weiterer keine zusätzlichen Performanceeinbußen bringen. So groß ist ja der SRAM eines AVRs nicht, man könnte also auch gleich für jede Adresse eine Zugriffsfunktion schreiben und dann ein Array von 64 Ki Einträgen damit füllen. ;-)
Jörg Wunsch schrieb: > Johann L. schrieb: > >> Trifft das nicht auch auf den Flash zu? > > Nein, denn der muss immer seitenweise gelöscht und neu beschrieben > werden. Meine Frage bezog sich auf den readonly-Teil. Wenn geschrieben wird, hätte das keinen Effekt.
Johann L. schrieb: > Meine Frage bezog sich auf den readonly-Teil. Meine Aussage oben jedoch auf das Schreiben des EEPROMs. Aber auf deine Frage: nein, der Flash muss aufgrund der Harvard-Architektur immer über gesonderte Befehle gelesen werden. Er lässt sich auch nicht auf den SRAM-Bereich abbilden.
Johann L. schrieb: > Jörg Wunsch schrieb: > >> Ich habe bei Xmega noch nichts mit EEPROM gemacht. Wenn ich das >> richtig lese, kann man wohl dort im memory-mapped-Modus sogar den >> EEPROM wie SRAM beschreiben. Das wäre ja super einfach. > > Trifft das nicht auch auf den Flash zu? Jörg Wunsch schrieb: > Johann L. schrieb: > >> Trifft das nicht auch auf den Flash zu? > > Nein, denn der muss immer seitenweise gelöscht und neu beschrieben > werden. Gerade im AVR Instruction Set gelesen: > LDS (16-bit) – Load Direct from Data Space > > Description: [...] For parts without SRAM, the data space > consists of the register file only. In some parts the Flash > memory has been mapped to the data space and can be read > using this command. Verstehe ich da was falsch? Analog für's Schreiben: > STS (16-bit) – Store Direct to Data Space > Description: [...] For parts without SRAM, the data space > consists of the Register File only. In some parts the Flash > memory has been mapped to the data space and can be written > using this command. Allerdings erlauben diese Instruktionen nur ein 7-Bit Argument für die zu lesende / schreibende Adresse, so daß abzüglich des I/O-Bereichs kaum was an via LDS / STS lesbarem / schreibbarem Flash übrig bleibt. Für GCC und Binutils ist das insoweit irrelevant als da keine 16-Bit LDS oder STS unterstützt werden, die gibt's ja nut bei den Register-kastrierten Tinys...
Johann L. schrieb: > Für GCC und Binutils ist das insoweit irrelevant als da keine 16-Bit LDS > oder STS unterstützt werden, die gibt's ja nut bei den > Register-kastrierten Tinys... Und gerade bei denen sind mir bislang nur welchen über den Weg gelaufen, deren Flash man gar nicht zur Laufzeit beschreiben kann (nur während der Programmierung, und dann auch nur mit Vcc = 5 V).
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.