Forum: Compiler & IDEs Mapfile via avr-nm: Unstimmigkeiten


von Andreas Paulin (Gast)


Lesenswert?

Hi, Freunde der Nacht,

Entwicklungssoftware: WinAvr und AVRStudio.

Hardware: ATMEGA128@16MHz, 4k int.RAM und 60K externes RAM.

Eigentlich wollten wir der Einfachheit Heap UND statisch deklarierte 
Variable ins externe RAM packen und fertig.
Unsere Firmware muss aber einen einen schnellen Sampling-Job 
(10µs/Sample)erledigen.
Die gesampelten Daten kommen in ein 512Byte großes Array.

Und jetzt das Problem:
Die Zeit wird auch bei 16MHz, d.h. 160 Takte für ein Sample etwas knapp.
Internes RAM benötigt lt. Datenblatt 2 Takte für einen Zugriff, externes 
RAM ohne Waitstates 4 Takte.
Arbeitsvariable und Sampling-Array im externen RAM: ZU langsam.
Also müssen die statischen Var. doch ins interne RAM (4K).
Und das ist langsam voll. Stackkollision droht.

Also versuche ich, zu optimieren.
Dazu die Memorymap mit avr-nm generiert:

E:\Programme\WinAVR\bin\avr-nm.exe --print-size --demangle 
--numeric-sort RLX_ExtMem_IntRam.elf>RLX_ExtMem_IntRam.map

Beachte: Numerisch, also nach Adressen aufsteigend sortiert!

Und hier sind seltsame Unstimmigkeiten, die ich nicht verstehe.
Hier ein Beispiel:

.........
00800966 00000002 D ucHeaderLen
00800b26 00000001 D LCD240_DisplayMode
00800b27 00000001 D LCD240_CurSize

d.H.  - jetzt mal ohne den 800000-Offset:
LCD240_DisplayMode wird ab B26h abgelegt, ist 1 Byte lang, und das 
nächste Datum heißt
LCD240_CurSize und wird ab B27h abgelegt.
Soweit stimmt die Rechnung
Aaaaaaaaaber:
ucHeaderLen liegt bei 966h und ist 2Byte groß.
Nächstes Datum LCD240_DisplayMode läge also bei 968h.
Wieso gehts hier bei B26 weiter?
Und wo verschwinden die Differenz von (B26h-966h) = 488d Byte?

Anderes, ähnliches Beispiel:
...........
00800583 00000014 D pe1
008005a5 00000014 D pe2
008005c7 00000014 D pe3
008005e9 00000014 D peBack
008006c7 0000000e d C.0.2509
00800962 00000002 D ucIndexLen

Wieso liegen z.B. die pe.. Variable mit Länge 14h nicht 14h Byte sondern 
22h Byte auseinander?
Und was ist das Symbol "C.0.2509" für ein seltsames Ding, das scheinbar 
962h-6C7h = 296h(667d!) Byte verbraucht, bis die nächste Var. ucIndexLen 
kommt?

Wenn mir das jemand erklären könnte wärs klasse.
Vielen Dank schonmal im voraus.

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


Lesenswert?

Vermutlich liegen dazwischen noch statische Variable, die nicht als
globale Symbole auftauchen (modulintern).  Kann auch sein, dass diese
bereits der Linker aus der Symboltabelle rauslässt.  Im (schwer zu
lesenden) Linker-Map-File müssten sie aber drin sein.

Übrigens dauert ein Zugriff auf den externen SRAM laut Datenblatt
(minimal) einen Takt pro Byte länger als intern, also 3 Takte.

von Andreas Paulin (Gast)


Lesenswert?

OK, danke Dir. Ich habe nach etwas abspecken etc. neu compiliert.
Wieder diese fraglichen Lücken.
Speziell folgende Zeilen irritieren:

008003d6 0000000e d C.0.2521
00800671 00000002 D ucIndexLen

Das heißt also, dass von Adresse 3d6h bis 671h im Ram ein 665Byte großer 
Block dem (lokalen, 'd') Symbol "C.0.2521" zugeteilt wurde.

"C.0.2521" kommt nicht von meinem Code.
Habe daraufhin mal die Quelle dieser Symbole gesucht.
nm mit Option '--line-numbers' liefert

008003d6 0000000e d C.0.2521 
./../../../../avr-libc-1.4.6/crt1/gcrt1.S:123
00800671 00000002 D ucIndexLen  ../RLX_Filesys.c:56

Ich finde aber auf meinem ganzen Rechner keinen Pfad 
"./../../../../avr-libc-1.4.6/crt1/gcrt1.S"

Was kann dieses ""C.0.2521" sein, das sich so fettmacht?
Es wird im standardmäßig linkergenerierten Mapfile übrigens nicht 
aufgeführt....?????????

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


Lesenswert?

Das gcrt1.S enthält den C-Startup-Code.  Du findest es natürlich nur
dann auf deinem Rechner, wenn du auch den Quellcode der avr-libc
installierst, ansonsten findest du nur die daraus generierten
Objektdateien.

C.0.2521 klingt nach einem lokalen Symbol (vielleicht sowas wie
"static ... C"?).

Was steht denn im entsprechenden Bereich dann drin?  Wenn meine
Vermutung stimmt, müsste es sich um initialisierte Datenbereiche
handeln, also solche, die zur Laufzeit vorbelegt worden sind.
Vielleicht geben die dort gefundenen Daten dir ja Aufschluss darüber,
woher sie kommen.

von Andreas Paulin (Gast)


Lesenswert?

Jup. Die nm-Ausgabe

008003d6 0000000e d C.0.2521

enthält als Datentyp das 'd'. Steht für Symbole im .data Segment
Lokale (kleinschreibung) Daten.

STOP!
Nochmal nachlesen:
008003d6 0000000e d C.0.2521
00800671 00000002 D ucIndexLen

Was, wenn das Symbol "C.0.2521" sich wirklich nur 0000000e Byte 
reserviert wie von nm angegeben und die restliche Differenz von
008003d6 zu
00800671
wirklich von 'irgendwas' anderem ausgefüllt wird, wie Du vermutet hast?

Wir haben ja hier noch so 'ne Gurke:
00800675 00000002 D uiHeaderLen          ../RLX_Filesys.c:59
0080086d 00000001 D LCD240_DisplayMode  ../RLX_LCD240_B.c:13

ucHeaderLen bei 00800675, 2 Byte lang, dann eine große Lücke und dann
LCD240_DisplayMode ab 0080086d.

Hm, was steht da in der Lücke drin... der Debugger ist zur Zeit beim 
Kollege,  vielleicht kann ich nm auch dazu bringen, mir die Lücken 
anzeigen zu lassen...
Schätze, ich werde mal in diese Richtung forschen gehen......

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


Lesenswert?

Du kannst dir den Krams ja auf jeden Fall mit avr-objdump angucken.

von Andreas Paulin (Gast)


Lesenswert?

objdump......OK. Irgendwo mal gehört, nie benutzt danke für den Tip ich 
probiers aus...

Ööööhm.. haltemal, andere Sache. Da steht was von "avr-libc-1.4.6"

Ist das nicht uralter Kram? Ist da nicht 3.4.6 oder so aktuell?
Kann das sein, dass ich hier mal upgraden sollte?

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


Lesenswert?

1.6.x ist aktuell.  Sollte aber hier keine Geige spielen, da diese
Datenbereiche ja vom Compiler irgendwie erzeugt worden sein müssen.

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.