Hi. Ich habe ein Problem mit einer eff Datei. Avr und avrstudio 4.18. Etliche variabeln werden nicht aufgelöst. Im map file sehe ich das die Adressen auf komischen werten stehen. H Kann man das irgendwie ändern? Klaus
Was ist eine "eff Datei"? Wann ist ein Wert "komisch"?
JA JA, wenn man unterwegs was schreibt. .ELF ist gemeint! Sollte beim GCC aber auch nicht so schwer sein das zu vermuten. Wenn ich eine Variable auf 0x0712 erwarte und im MAP File steht sie auf 0x81000712 oder so Ähnlich dann ist was für mich komisch. Ich bin halt auf der Suche warum, wahrscheinlich wegen der Adressen, die Variablen nicht angezeigt werden können. Schaue ich mir den RAM Bereich an wo die Variable drin steht sehe ich den Inhalt. Ist in dem einen Fall recht reinfach zu erkennen da es der Inhalt von meinem Angeschlossenden Display ist. Nur der Debugger sagt halt immer so was die Falsche Adresse und zeigt die mir nicht an. Viele Grüsse, Klaus
Klaus schrieb: > Hi. > Ich habe ein Problem mit einer eff Datei. > Avr und avrstudio 4.18. > Etliche variabeln werden nicht aufgelöst. > > Im map file sehe ich das die Adressen auf komischen werten stehen. > H > Kann man das irgendwie ändern? > Ja, im Linker Control File oder per ld-Option. Näheres dazu im GNU Linker Manual. > Klaus
Klaus schrieb: > Wenn ich eine Variable auf 0x0712 erwarte und im MAP File steht sie auf > 0x81000712 oder so Ähnlich dann ist was für mich komisch. Ist aber korrekt; die Binutils linearisieren lediglich den Adressraum. Im Linker Description File für -mmcu=avr51 sieht das z.B. so aus:
1 | MEMORY |
2 | { |
3 | text (rx) : ORIGIN = 0, LENGTH = __TEXT_REGION_LENGTH__ |
4 | data (rw!x) : ORIGIN = 0x800100, LENGTH = __DATA_REGION_LENGTH__ |
5 | eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = __EEPROM_REGION_LENGTH__ |
6 | fuse (rw!x) : ORIGIN = 0x820000, LENGTH = __FUSE_REGION_LENGTH__ |
7 | lock (rw!x) : ORIGIN = 0x830000, LENGTH = __LOCK_REGION_LENGTH__ |
8 | signature (rw!x) : ORIGIN = 0x840000, LENGTH = __SIGNATURE_REGION_LENGTH__ |
9 | user_signatures (rw!x) : ORIGIN = 0x850000, LENGTH = __USER_SIGNATURE_REGION_LENGTH__ |
10 | } |
Die Ardesse ist also ungültig; vermutlich meinst du aber 0x810712, was eine Adresse im EEPROM darstellt.
Johann L. schrieb: > Die Ardesse ist also ungültig; vermutlich meinst du aber 0x810712, was > eine Adresse im EEPROM darstellt. Und dann haben wir da auch noch die Optimierung des GCC. Wenn eine Variable einen file-static scope hat und außer der Intialisierung in der Deklaration nur gelesen wird, dann ist GCC so schlau, das Ding in die readonly-Sektion zu verfrachten, um RAM zu sparen. Das ist blöd, wenn man eine solche Variable aber im RAM haben will wegen der Zugriffszeit. Dann muß man GCC mit attributes anweisen, das Ding in die Data-Sektion zu packen. Merkwürdigerweise geht das aber dann nicht mehr zusammen mit dem const-Attribut, weil GCC da aus unerfindlichen Gründen glaubt, const heiße "in die readonly-Sektion linken". Nichts dergleichen sagt der C-Standard, aber der GCC glaubt das halt.
Also ist das mit den komischen Adressen richtig. Aber warum sagt mit dann das AVRStudio immer das die Adresse nicht stimmt? Im Watch fenster steht so was wie "location not valid". Also ist da doch was nicht richtig! Das der GCC hier was bei einem AVR sperren kann halte ich für äussert schwierig. Bessonders wenn ich mir den RAM Inhalt ansehe und ich da alles sehe. Bei einem String ist das noch machbar, aber bei einer Struktur mit etlichen Werten wird es schon sehr schwer. Viele Grüsse, Klaus
Nop schrieb: > Johann L. schrieb: >> Die Ardesse ist also ungültig; vermutlich meinst du aber 0x810712, was >> eine Adresse im EEPROM darstellt. > > Und dann haben wir da auch noch die Optimierung des GCC. Wenn eine > Variable einen file-static scope hat und außer der Intialisierung in der > Deklaration nur gelesen wird, dann ist GCC so schlau, das Ding in die > readonly-Sektion zu verfrachten, um RAM zu sparen. .rodata ist aber auch Teil des RAM. Einfach mal ein Blick ins Linker Description File wagen. Übrigens können file-static Variablen auch komplett wegoptimiert werden; ditto für andere Variablen im Static Storage, welche nur lesend zugegriffen werden. > Das ist blöd, wenn man eine solche Variable aber im RAM haben will wegen > der Zugriffszeit. Dann muß man GCC mit attributes anweisen, das Ding in > die Data-Sektion zu packen. Kommt auf die Architektur an; bei avr-gcc ist es nicht nötig. Wenn man mit Zugriffszeiten jonglieren muss, dann hat das aber i.d.R. wenig mit RAM oder nicht-RAM zu tun, sondern eben mit den Zugriffszeiten. Es gibt durchaus Architektiren, deren Data-Flash schneller zugreifbar ist als bestimmte RAM-Bereiche. Und ja, wenn du das händisch zuordnen willst, dann wird's eine Schlacht mit Section-Attributen oder anderen Features wie #pragma. > Merkwürdigerweise geht das aber dann nicht mehr zusammen mit dem > const-Attribut, const ist ein Qualifier, kein Attribut. Und const in .data tut nicht weh; umgekehrt aber schon :-) > weil GCC da aus unerfindlichen Gründen glaubt, const > heiße "in die readonly-Sektion linken". Nichts dergleichen sagt der > C-Standard, aber der GCC glaubt das halt. Der C-Standard sagt nichts über's Binärformat, korrekt. Das steht in der ABI, aber nicht im Standard, weil letzterer lediglich eine abstrakte Maschine beschreibt. Ebensowenig wirst du im Standard finden, ob und in in welchen Registern Funktionsparameter zu übergeben sind und viele andere Sachen. Die beste Section für readonly-Daten im Static Storage ist nun mal .rodata; und warum .rodata bei avr-gcc ins RAM lokatiert werden muss sollte evident sein. Bei anderen Architekturen wird man .rodata natürlich ins Daten-Flash legen.
Klaus schrieb: > Also ist das mit den komischen Adressen richtig. > Aber warum sagt mit dann das AVRStudio immer das die Adresse nicht > stimmt? > Im Watch fenster steht so was wie "location not valid". 0x81000712 ist nun eben mal UNGÜLTIG. Du musst also untersuchen, wer wo wann diese Adresse erzeugt. Hilfreich ist z.B. ein Blick ins Map-File. > Das der GCC hier was bei einem AVR sperren kann halte ich für äussert > schwierig. Hä? Was soll der GCC "sperren" können?
Johann L. schrieb: > const ist ein Qualifier, kein Attribut. Und const in .data tut nicht > weh; Dem GCC schon. Auf STM32 schmeißt (ARM-)GCC mir nämlich einen Error raus, wenn ich eine const-Variable per attribute nach Data legen will. Einzige Abhilfe: auf const verzichten, wenn ich aus Geschwindigkeitsgründen eine readonly-Variable wie Lookuptabellen zur Laufzeit im RAM haben will. Bei AVR hat man das Problem nicht, wird eh ins RAM geladen, das stimmt.
Nop schrieb: > Auf STM32 schmeißt (ARM-)GCC mir nämlich einen Error raus, wenn ich eine > const-Variable per attribute nach Data legen will. Ich bekomme für diesen Eins-fix-drei-Versuch lediglich eine Warnung des Assemblers:
1 | const int lut[] __attribute__((section(".data"))) = {1, 2, 4, 7, 14, 27, 51, 100}; |
2 | int mumble = 42; |
bringt:
1 | % arm-none-eabi-gcc -mthumb -mcpu=cortex-m0 -Os -c foo.c |
2 | /tmp/ccAGlIhp.s: Assembler messages: |
3 | /tmp/ccAGlIhp.s:24: Warning: ignoring changed section attributes for .data |
foo.o enthält aber die korrekten Daten, beide in .data:
1 | % arm-none-eabi-objdump -ds foo.o |
2 | |
3 | foo.o: file format elf32-littlearm |
4 | |
5 | Contents of section .data: |
6 | 0000 2a000000 01000000 02000000 04000000 *............... |
7 | 0010 07000000 0e000000 1b000000 33000000 ............3... |
8 | 0020 64000000 d... |
9 | Contents of section .comment: |
10 | 0000 00474343 3a202847 4e552054 6f6f6c73 .GCC: (GNU Tools |
11 | 0010 20666f72 2041524d 20456d62 65646465 for ARM Embedde |
12 | 0020 64205072 6f636573 736f7273 2920352e d Processors) 5. |
13 | 0030 342e3120 32303136 30393139 20287265 4.1 20160919 (re |
14 | 0040 6c656173 6529205b 41524d2f 656d6265 lease) [ARM/embe |
15 | 0050 64646564 2d352d62 72616e63 68207265 dded-5-branch re |
16 | 0060 76697369 6f6e2032 34303439 365d00 vision 240496]. |
17 | Contents of section .ARM.attributes: |
18 | 0000 41300000 00616561 62690001 26000000 A0...aeabi..&... |
19 | 0010 05436f72 7465782d 4d300006 0c074d09 .Cortex-M0....M. |
20 | 0020 01120414 01150117 03180119 011a011e ................ |
21 | 0030 04 . |
Die Warnung kommt daher, dass "mumble" per .data-Pseudo-op angelegt wird, lut[] dagegen per .section mit dem Attribut "a". Keine Ahnung, welche Attribute sich hinter .data jetzt konkret verbergen.
Leute was der GCC beim ARM oder PC macht ist mir ehrlich gesagt vollkommen egal, auch wenn es für einem ARM Programmierer interessant ist. Ich habe einen AVR!!!!! @Johann L. Diese Adressen habe ich aus dem MAP File, wobei 0x81000712 falsch ist. Die Variable liegt logischerweise im Datenbereich: data (rw!x) : ORIGIN = 0x800100, LENGTH = _DATA_REGION_LENGTH_ Bei 0x800712. Der Code arbeitet sauber, nur beim Debuggen gibt es halt Probleme. Da ist auch nichts raus optimiert und selbst wenn wäre eine Globale Variable die in ca. 10 Dateien benutzt wird und ca. 70Byte hat auch nicht so leicht weg zubekommen. Komischerweise kann ich Variablen mit kleineren Adressen mir ansehen, aber das muss ich mir im MAP File noch genauer nachsehen. Klaus
Jörg W. schrieb: > Die Warnung kommt daher, dass "mumble" per .data-Pseudo-op > angelegt wird, lut[] dagegen per .section mit dem Attribut "a". > Keine Ahnung, welche Attribute sich hinter .data jetzt konkret > verbergen. Diese "Attribute" nennt ELF "Section Flags"; sie werden in den entsprechenden Section Headers gespeichert (im 3. Feld .sh_flags). Problem ist wohl, dass mit dem Section Attribut keine Section Flags (und auch kein Alignment) angegeben werden können. Flags für .data wären "aw". Hier sollte aber helfen, eine eigene Input-Section zu nehmen wie .data.foo. Geht's damit?
Klaus schrieb: > @Johann L. > Diese Adressen habe ich aus dem MAP File, wobei 0x81000712 falsch ist. > Die Variable liegt logischerweise im Datenbereich: > data (rw!x) : ORIGIN = 0x800100, LENGTH = __DATA_REGION_LENGTH__ > Bei 0x800712. Und von wo bis wo hat das Device den RAM? Evtl. läuft der RAM über, und die Tools machen ein wrap around beim Lokatieren bzw. die Hardware beim Zugriff. Oder ein Problem mit dem Debugger selbst; dazu fällt mir nix ein weil ich keinen Degugger verwende. Falls -gstrict-dwarf nicht hilft (eher wahrscheinlich) dann mal bei avrfreaks.net nachfragen, ist vermutlich ein bekanntes Problem dann.
Johann L. schrieb: > dann mal bei avrfreaks.net nachfragen Ich glaube, nach AVR Studio 4.18 muss man dort auch nicht mehr fragen. Das Ding ist einfach von vorgestern, und selbst wenn es ein Bug ist (bei deren selbstgestricktem DWARF-Parser nicht so unwahrscheinlich), wird ihn nach so vielen Jahren niemand mehr reparieren. Mit dem puren Offset 0x800000 sollte aber auch das olle Studio klar kommen, den gab's schon seit eh und je.
Der ATMEGA644 hat 4 Kbytes Internal SRAM, sollte also nicht zum Problem führen. Früher hatte ich das Projekt noch mit dem guten alten "WINAVR 2010" bearbeitet. Da konnte man noch eine COFF Datei erzeugen und die funktionierte perfekt. Aber nun einige Jahre und Versions updates später geht der selbe Code mit den selben Projekt Dateien nicht mehr. VG, Klaus
Klaus schrieb: > Aber nun einige Jahre und Versions updates später geht der selbe Code > mit den selben Projekt Dateien nicht mehr. Dann installier' dir doch mal ein aktuelles Atmel Studio.
Das hatte ich mal gemacht und war froh als ich es wieder runter hatte. Jetzt habe ich eine Kette auf dem Rechner die normalerweise super läuft und ich alle Macken kenne. Unter Code::Blocks (die IDE unter der ich das Projekt schreibe) habe ich auch mal AVaRICE getestet und da gibt es anscheinend das selbe Problem. Ich bekomme meine Drecks Variablen einfach nicht angezeigt.
Da must du bei der uralten Software halt mit Leben. Das Studio hatte schon damals zu seiner Blütezeit mit der aktuellsten WinAVR-Version diese Debuggerprobleme. Immerhin kann du ja im Studio auch den Speicherinhalt direkt anschauen, da siehst du dann, was an der Adresse steht. Oliver
Oliver S. schrieb: > Immerhin kann du ja im Studio auch den Speicherinhalt direkt anschauen, > da siehst du dann, was an der Adresse steht. Was aber nicht der aktuelle Wert der Variablen sein muss, falls der grade in irgendwelchen Registern zu finden ist.
So ich habe alles noch mal überprüft. An den Adressen liegt es nicht. Ich kann mir Variablen davor und dahinter ansehen. Ich habe nur die Probleme bei meinen wichtigsten Variablen, wäre ja sonst nicht aufgefallen. Die sind alle eine Kombination von struct und union. Also so was hier:
1 | typedef struct {....} S_Test1; |
2 | typedef struct {....} S_Test2; |
3 | |
4 | |
5 | typedef struct {....} S_Test3; |
6 | typedef struct {....} S_Test4; |
7 | typedef union { |
8 | unsigned char HAll0; |
9 | S_Test3 Test3; |
10 | S_Test4 Test4; |
11 | } U_Test5; |
12 | |
13 | |
14 | typedef union { |
15 | unsigned char Daten[100]; |
16 | S_Test1 Test1; |
17 | S_Test2 Test2; |
18 | U_Test31 Test3; |
19 | } U_Test; |
20 | |
21 | U_Test Test_System; |
Und Test_System ist dann nicht anzeigbar. Komisch ist aber das einige von solchen Variablen funktionieren und andere nicht. Im Netz finde ich dazu keine Informationen, oder ich suche einfach falsch. Viele Grüsse, Klaus
Kannst du denn die Komponente der Union angeben, die angezeigt werden soll?
Bei den fehlerhaften geht absolut nichts. Bei denen die ich anzeigen kann geht jedes Element. Bit Strukturen kann man anscheinend auch nicht anzeigen lassen. Ob das jemals ging kann ich aber nicht unterschreiben.
Such dir einen noch viel älteren Compiler. Wie ich schon schrieb, hat das Studio die Probleme mit WinAVR2010 schon immer. Der war damals schon "zu neu" dafür. Und daran hat sich in den letzten x Jahren nichts geändert. Die ernsthafte Lösung ist natürlich, auf das aktuelle Studio und eine aktuelle toolchain umzusteigen. Früher war eben nicht alles besser. Oliver
Klar am besten zum fünfer, das Teil soll ja sowas von Fehler haben, was man so liest. Wenn alle Aussagen stimmen dann ist für das Siebener mein Rechner auch hoffnungslos zu langsam (P4 mit XP -> zum tippen und kompilieren ist der aber noch zu schnell).
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.