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.
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.
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....?????????
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.
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......
Du kannst dir den Krams ja auf jeden Fall mit avr-objdump angucken.
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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.