Forum: Compiler & IDEs wie variablenadresse in einer eff datei ändern?


von Klaus (Gast)


Lesenswert?

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

von Huh (Gast)


Lesenswert?

Was ist eine "eff Datei"?
Wann ist ein Wert "komisch"?

von Klaus (Gast)


Lesenswert?

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

von nadresse in einer eff (Gast)


Lesenswert?

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

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von Nop (Gast)


Lesenswert?

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.

von Klaus (Gast)


Lesenswert?

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

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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?

von Nop (Gast)


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Klaus (Gast)


Lesenswert?

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

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Klaus (Gast)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Klaus (Gast)


Lesenswert?

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.

von Oliver S. (oliverso)


Lesenswert?

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

von Jim M. (turboj)


Lesenswert?

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.

von Klaus (Gast)


Lesenswert?

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

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Kannst du denn die Komponente der Union angeben, die angezeigt werden 
soll?

von Klaus (Gast)


Lesenswert?

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.

von Oliver S. (oliverso)


Lesenswert?

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

von Klaus (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.