Gast
#4888089
Vielleicht kann mir jemand helfen. Ich habe folgendes, kleines Programm:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
Aber leider wird die Variable "boot_reset" einfach weg optimiert. Wie kann ich das ändern?
|
Anzeige
|
AVR-GCC: Variable wir leider weg optimiert
Gast
#4888089
Vielleicht kann mir jemand helfen. Ich habe folgendes, kleines Programm:
Aber leider wird die Variable "boot_reset" einfach weg optimiert. Wie kann ich das ändern?
Gast
#4888091
ChrisMicro schrieb: > Wie kann ich das ändern? verwende sie doch einfach, dann wird sie nicht wegoptimiert.
Gast
#4888092
volatile davor packen.
Gast
#4888102
1. attribute used verwenden, siehe https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gcc/Variable-Attributes.html#Variable-Attributes 2. im Linkerscript schauen, was mit der section bootreset passiert
Gast
#4888152
Autor: Peter II (Gast)
>verwende sie doch einfach, dann wird sie nicht wegoptimiert.
Das habe ich schon probiert.
Wenn ich in der "Main" folgendes hinzu füge:
wird sie nicht weg optimiert. Es ist allerdings nicht so richtig schön, weil ich die Variable gar nicht brauche sondern den Boot-Vektor, den sie an der Adresse 0 erzeugt ( memory section .bootreset=0 ). >Autor: Benji (Gast) >volatile davor packen. Das habe ich schon probiert. Bringt nichts, wird trotzdem weg optimiert. >2. im Linkerscript schauen, was mit der section bootreset passiert Das linker command, welches Atmel Studio 7 erzeugt, sieht so aus: -Wl,-Map="$(OutputFileName).map" -Wl,--start-group -Wl,-lm -Wl,--end-group -Wl,--gc-sections -Wl,-section-start=.text=0x1800 -Wl,-section-start=.bootreset=0 -mmcu=attiny85 -B "D:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATtiny_DFP\1.1.102\gcc\dev\attiny85" .bootreset ist vorhanden, wie es aussieht. Da scheint also kein Fehler zu sein. ChrisMicro schrieb: >>Autor: Benji (Gast) >>volatile davor packen. > Das habe ich schon probiert. Bringt nichts, wird trotzdem weg optimiert. volatile sorgt dafür, dass Zugriffe auf die Variable nicht wegoptimiert, sondern so durchgeführt werden, wie sie im Code stehen. Es gibt aber keine Zugriffe. Deshalb bringt volatile hier nichts.
Gast
#4888166
Autor: ffggsd (Gast) >1. attribute used verwenden, siehe >https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gcc/Varia... Habe ich gerade mal probiert:
Wirt trotzdem weg optimiert.
Gast
#4888173
ChrisMicro schrieb: > wird sie nicht weg optimiert. Es ist allerdings nicht so richtig schön, > weil ich die Variable gar nicht brauche sondern den Boot-Vektor, den sie > an der Adresse 0 erzeugt ( memory section .bootreset=0 ). ich versteht immer noch nicht was du damit machst. Irgendwie musst du sie doch mal verwenden, sonst macht das doch alles keinen sinn.
Gast
#4888182
>ich versteht immer noch nicht was du damit machst. Irgendwie musst du >sie doch mal verwenden, sonst macht das doch alles keinen sinn. Sie wird als Reset Vector für einen Bootloader verwendet, genau wie hier im Abschnitt Speicherlayout beschrieben: http://www.mikrocontroller.net/articles/Konzept_f%C3%BCr_einen_ATtiny-Bootloader_in_C Man greift also nicht auf die Variable zu, sondern nur wenn der Prozessor einen Reset bekommt wird der Variablenwert als Code interpretiert ( RJMP ) und als Sprung zum eigentlichen Programm benutzt. Scheinbar funktioniert es aber nicht mehr so wie in dem Artikel beschrieben. Vielleicht hat sich in den neueren GCC Versionen etwas verändert, so dass das Prinzip nicht mehr funktioniert. ChrisMicro schrieb: > uint16_t boot_reset __attribute__((section(".bootreset")))= 0xCBFF; Wie soll denn der Wert 0xCBFF überhaupt in deine Variable reinkommen? Der normale .data-Loader im Startup-Code hat keine Ahnung, dass er das mit tun sollte.
Gast
#4888250
Hallo Jörg, das ganze Prinzip habe ich aus dem Bootloader Artikel übernommen und habe gehofft, dass es recht unproblematisch funktioniert: http://www.mikrocontroller.net/articles/Konzept_f%C3%BCr_einen_ATtiny-Bootloader_in_C In Atmel-Studio 7 habe ich folgendes gemacht und in Atmeo Studio 7 => Toolchain/AVR_GNU_Linker/Memory Settings/Flash-Segment .bootreset=0 Ich nehme an, dass die von Atmel-Studio erstellten Linker Parameter hier Beitrag "Re: AVR-GCC: Variable wir leider weg optimiert" -Wl,-section-start=.bootreset=0 die Variable ins richtige Segment schieben. Wenn ich in der Main den Code für den Variablenzugriff einfüge, steht auch im Flash an der richtigen Stelle der gewünschte Wert. Insofern löst der Variablenzugriff das Problem, aber es ist meiner Ansicht nach ein wenig Murks. Besser wäre, wenn man im C-Code gleich den RJMP an die richtige Stelle assemblieren könnte, anstatt eine Variable zu missbrauchen. ChrisMicro schrieb: > das ganze Prinzip habe ich aus dem Bootloader Artikel übernommen und > habe gehofft, dass es recht unproblematisch funktioniert Bei denen sind es aber Flash-Daten. Ich habe den Eindruck, dass du versuchst, das im RAM anzulegen (also wirklich als Variable). Da musst du dir schon die Frage stellen, auf welche Weise die Werte dann auch ins RAM gelangen. ChrisMicro schrieb: >>ich versteht immer noch nicht was du damit machst. Irgendwie musst du >>sie doch mal verwenden, sonst macht das doch alles keinen sinn. > > Sie wird als Reset Vector für einen Bootloader verwendet, genau wie hier > im Abschnitt Speicherlayout beschrieben: Das erscheint mir aber extrem hackish. Ich könnte mir vorstellen, dass dieser Trick mit irgendeiner alten Toolchain-Version funktioniert hat, aber nicht mehr mit der aktuellen. Warum nutzt du dafür nicht den Inline-Assembler? Dann musst du auch nicht den Hexcode für den RJMP-Befehl explizit in dein Programm schreiben. ChrisMicro schrieb: > Wie kann ich das ändern? Ich habe gerade ein Ähnliches Problem bei einem nrf52 gelöst, in dem ich den Wert einfach im linker script beschrieben habe:
Gast
#4888281
>Bei denen sind es aber Flash-Daten. Ich habe den Eindruck, dass >du versuchst, das im RAM anzulegen (also wirklich als Variable). Was mache ich im Vergleich zu denen falsch? Ich dachte, ich habe die "section" für die Variable ins Flash gelegt. Debug mit Debug-Wire zeigt, dass der Wert im Flash steht ( siehe Bild ). >Das erscheint mir aber extrem hackish. Das finde ich auch, es ist aber der Weg wie im Artikel beschrieben. Der Artikel selbst ist sehr gut gemacht, finde ich. ( Ein Lob an denjenigen, der sich die Arbeit gemacht hat ) >Warum nutzt du dafür nicht den Inline-Assembler? Ich weiß leider nicht, wie es geht. ChrisMicro schrieb: > Debug mit Debug-Wire zeigt, dass der Wert im Flash steht ( siehe Bild ). Dann verstehe ich deine Aussage („wird wegoptimiert“) nicht. Wenn der Wert im Flash liegt, dann ist er doch nicht „wegoptimiert“. Aber ehrlich gesagt, ist mir auch das gesamte Anliegen nicht so recht klar.
Gast
#4888290
>Ich habe gerade ein Ähnliches Problem bei einem nrf52 gelöst, in dem ich >den Wert einfach im linker script beschrieben habe: Danke für den Hinweis. Es scheint also kein so einfaches Problem zu sein. Tendenziell würde ich es lieber im Code haben und das Linker-Script eher weniger verändern.
Gast
#4888299
>Dann verstehe ich deine Aussage („wird wegoptimiert“) nicht. Wenn >der Wert im Flash liegt, dann ist er doch nicht „wegoptimiert“. Er wird nur dann nicht "wegoptimiert" wenn in der "main" dieser nicht benutzte Hilfszugriff steht:
ChrisMicro schrieb: > Er wird nur dann nicht "wegoptimiert" wenn in der "main" dieser nicht > benutzte Hilfszugriff steht: Dann wurde dir aber schon genannt:
Sag mal, benutzt du beim Linken sowas wie -Wl,--gc-sections? Dann müsstest du dich nicht weiter wundern … ChrisMicro schrieb: > Es scheint also kein so einfaches Problem zu sein. > Tendenziell würde ich es lieber im Code haben und das Linker-Script eher > weniger verändern. Naja, jetzt hast Du die Definition dieser Konstanten im Flash im Code und in den Linker-Parametern stehen. Wenn Du es im Linker-Script definierst. Aber wir Jörg auch schon festgestellt hat: Die Konstante wird nicht weg optimiert. Wenn irgend etwas nicht funktioniert, dann scheint es ein anderes Problem zu sein.
Gast
#4888315
>Dann wurde dir aber schon genannt: >__attribute__((used)) Ja, das habe ich hier schon so probiert: Beitrag "Re: AVR-GCC: Variable wir leider weg optimiert" Es hat aber nicht funktioniert. Ist es syntaktisch richtig? Es wurde kein Warning geworfen. ChrisMicro schrieb: >>Dann wurde dir aber schon genannt: >>__attribute__((used)) > Ja, das habe ich hier schon so probiert: > Beitrag "Re: AVR-GCC: Variable wir leider weg optimiert" > Es hat aber nicht funktioniert. Ist es syntaktisch richtig? Es wurde > kein Warning geworfen. Guck doch einfach mal ins Hex-File. Wenn es da drinnen steht, dann hat "es" funktioniert.
Gast
#4888335
>Guck doch einfach mal ins Hex-File. Wenn es da drinnen steht, dann hat >"es" funktioniert. Hat es nicht. Soweit ich es verstehe, ist kein Wert an der Stelle 0 sichtbar: :101800000EC015C014C013C012C011C010C00FC04C :101810000EC00DC00CC00BC00AC009C008C0112406 :101820001FBECFE5D2E0DEBFCDBF02D006C0E8CFFD :0E183000CF93DF93CDB7DEB7FFCFF894FFCF95 :0400000300001800E1 :00000001FF
Gast
#4888353
Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite >Sag mal, benutzt du beim Linken sowas wie -Wl,--gc-sections? Dann >müsstest du dich nicht weiter wundern … Tja Jörg, das ist es. Danke. Ohne -Wl, --gc-sections wird es nicht mehr weg optimiert. Allerdings würde ich nicht sagen, dass ich "--gc-sections" benutzt habe, sondern Atmel-Studio7. Dort ist nämlich per default ein kleines, leicht zu übersehendes, unschuldig aussehendes Häckchen bei ..Toolchain/AVR_GNU_C Compiler/Optimization/Garbage collect unuses sections macht man es weg, bleibt der Code. Rein vom Verfahren gefällt mir das Ganze nicht so recht, weil eigentlich eine Variable als Code missbraucht wird. Kann mir jemand sagen, wie man den Inline-Assembler dazu bringt, Code in eine bestimmte Section zu schreiben und danach den eigentlichen C-Code an eine andere Stelle? ChrisMicro schrieb: > Ohne -Wl, --gc-sections wird es nicht mehr weg optimiert. Dann macht der Linker genau das, was du ihm gesagt hast. Mich wundert allerdings, warum das "used"-Attribut nicht dagegen helfen sollte. > Allerdings würde ich nicht sagen, dass ich "--gc-sections" benutzt habe, > sondern Atmel-Studio7. Kann gut sein. Diese Optionen (zusammen mit -ffunction-sections) sind der Faulheit der Leute geschuldet, sauberen Code zu schreiben, bei dem man nur solche Dinge auch tatsächlich in den Quellen hat, die man am Ende benötigt. ChrisMicro schrieb: > Aber leider wird die Variable "boot_reset" einfach weg optimiert. > > Wie kann ich das ändern? Du brauchst dann ein passendes Linker Skript mit einem passenden KEEP() Statement. Deig mal dein aktuelles Linker Skript. ChrisMicro schrieb: >>Warum nutzt du dafür nicht den Inline-Assembler? > Ich weiß leider nicht, wie es geht. Ich habe den von dir velinkten Artikel nicht komplett gelesen, deswegen weiß ich nicht im Detail, worauf es bei dem Sprung genau ankommt. Es scheint aber so, dass er 1. an der Adresse 0 liegen muss (Reset-Vektor) und 2. an den Anfang der (in einen höheren Adressbereich verschobenen) Vektortabelle springen soll, wo ein von der Toolchain generierter Sprung zum eigentlich Programmstart steht. Beides erreichts du mit folgender Funktion:
Mit
Mit -Wl,--gc-sections hast du auch hier das Problem, dass der Linker die Section .bootreset wegoptimiert. Das used-Attribut wirkt sich nur auf den Compiler, nicht aber auf den Linker aus, weswegen es hier nicht den gewünschten Effekt hat. Du musst entweder die Option -Wl,--gc-sections weglassen, oder ins Linkerscript eine entsprechende KEEP-Anweisung einfügen. Jörg W. schrieb: > ChrisMicro schrieb: >> Ohne -Wl, --gc-sections wird es nicht mehr weg optimiert. > > Dann macht der Linker genau das, was du ihm gesagt hast. > > Mich wundert allerdings, warum das "used"-Attribut nicht dagegen > helfen sollte. Wirkt das used-Attribut nicht nur auf den Compiler und dessen Optimierer? Der Linker weiß doch davon garnichts. Oder? Steffen R. schrieb: > Wirkt das used-Attribut nicht nur auf den Compiler und dessen > Optimierer? Stimmt. Ich nahm an, dass er das auch dem Linker weiterreichen würde, aber das ist nicht der Fall. Damit ist klar, warum der Linker das bei --gc-sections rauskickt.
Gast
#4888492
Dein Ansatz, auf diese Weise eine Referenz auf den Speicher zu bekommen ist nur mit Vorsicht zu genießen. Die spätere, tatsächliche Adresse kann sich ändern, wenn der Linker ein paar Variablen (aus Bibliotheken) davor packt. Jörg W. schrieb: > ChrisMicro schrieb: >> Ohne -Wl, --gc-sections wird es nicht mehr weg optimiert. > > Dann macht der Linker genau das, was du ihm gesagt hast. > > Mich wundert allerdings, warum das "used"-Attribut nicht dagegen > helfen sollte. Weil "used" nur auf den Compiler wirkt: Das Objekt wird nicht verwendet, wegen "used" aber dennoch angelegt — eine used-Direktive für gas gibt es nicht. Da es nicht referenziert wird und nicht KEEP ist, wird es vom Linker entsorgt. Referenzieren bringt auch nur dann was, wenn es wirklich eine "Senke" für die Verwendung gibt, die der Compiler nicht wegoptimieren kann. Eine zu simple Verwendung kann durchaus ebenfalls vom Compiler als solche erkannt und somit entsorgt werden.
Gast
#4888572
Autor: Yalu X. (yalu) (Moderator) >Beides erreichts du mit folgender Funktion: .. Hallo Yalu, danke dafür. Das scheint mir sehr geeignet. Ich werde es mal auf die Art probieren. Autor: Amateur (Gast) >Dein Ansatz, auf diese Weise eine Referenz auf den Speicher zu bekommen >ist nur mit Vorsicht zu genießen. Der Bootloader sitzt mit .text=0x1800 an einer fixen Adresse. Das einzige worauf man achten muss, ist dass der Wert im Code und die Adresse der "section" Definition für den Linker konsistent sind. Die Zieladresse für den Programmstart muss sich der Bootloader irgendwo merken, da immer zuerst der Bootloader angesprungen wird. deklarier es als const (oder diese progmem Sache bei avr), sonst landet es nicht im Flash sondern irgendwo im RAM. Hier ist ein funktionierender Beispielschnipsel (aus nem ARM Startup code), es gibt keinen Grund warum das nicht auch bei AVR funktionieren sollte wenn man den Compiler davon überzeugen kann daß er die Konstante in den Flash legen soll:
Bernd K. schrieb: > deklarier es als const (oder diese progmem Sache bei avr), sonst landet > es nicht im Flash sondern irgendwo im RAM. "const" ist dafür völlig belanglos. Bei einem AVR landen auch "const" deklarierte Variable keineswegs automatisch im Flash. Aber das mit der Flash-Section hat er ja an sich hinbekommen, das unterscheidet sich bei ihm nicht großartig von deinem Vorschlag. Der Dreh- und Angelpunkt war halt die linker section garbage collection. Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|