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
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__
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:
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
typedefstruct{....}S_Test1;
2
typedefstruct{....}S_Test2;
3
4
5
typedefstruct{....}S_Test3;
6
typedefstruct{....}S_Test4;
7
typedefunion{
8
unsignedcharHAll0;
9
S_Test3Test3;
10
S_Test4Test4;
11
}U_Test5;
12
13
14
typedefunion{
15
unsignedcharDaten[100];
16
S_Test1Test1;
17
S_Test2Test2;
18
U_Test31Test3;
19
}U_Test;
20
21
U_TestTest_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
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).