Hallo,
ich habe eine Software für einen ATMega162 mit externem RAM. avr-size
gibt mir folgende Meldung:
1
AVRMemoryUsage
2
----------------
3
Device:atmega162
4
5
Program:6270bytes(38.3%Full)
6
(.text+.data+.bootloader)
7
8
Data:3846bytes(375.6%Full)
9
(.data+.bss+.noinit)
Wenn ich die Software mit dem "avr-gcc (WinAVR 20100110) 4.3.3"
compiliere, läuft die einwandfrei. Es spielt auch keine Rolle, ob ich
beim Linker "-Wl,-Tdata=0x800500,--defsym=__heap_end=0x807fff" angebe
oder weglasse.
Sobald ich die aber mit der Version 7.3.0 compiliere, bekomme ich die
Fehlermeldung "section `.data' is not within region `data'" bzw.
"section `.bss' is not within region `data'".
Beim Linken habe ich folgende Parameter angegeben:
a)-Wl,--section-start,.data=0x800500,--defsym=__heap_end=0x807fff
b) -Wl,-Tdata=0x800500,--defsym=__heap_end=0x807fff
c) -Wl,-section-start=.data=0x800500
d) -Wl,-section-start=.data=0x800500
-Wl,-section-start=XRAMSTART=0x800500
e) keinen der genannten Parameter
Es kommt jedesmal dieselbe Meldung des Linkers
Es werdem dazu noch die Adressen 0x800650 und
also:
address 0x800650 of Multitasking.elf section `.data' is not within
region `data'
bzw.:
address 0x801440 of Multitasking.elf section `.bss' is not within region
`data'
Meine Vermutung ist, dass es mit der Angabe des externen Rams zu tun
hat. Ich weiss aber nicht, was ich dem Linker genau angeben muss bzw. wo
der Fehler liegt.
Kann mir jemand einen Tipp geben?
Vielen Dank
Andreas schrieb:> Meine Vermutung ist, dass es mit der Angabe des externen Rams zu tun> hat. Ich weiss aber nicht, was ich dem Linker genau angeben muss bzw. wo> der Fehler liegt.
Du hast 3k8 RAM, der Prozessor scheinbar nur etwa 1k, deshalb zu >>100%
voll
Andreas schrieb:> Data: 3846 bytes (375.6% Full)
Kommt das in etwa hin? Also brauchst Du 3k8 RAM oder ist das ein Fehler,
weil z.B. 3k Teststrings irrtümlich im RAM statt nur ROM gelandet sind?
Bruno V. schrieb:> Du hast 3k8 RAM, der Prozessor scheinbar nur etwa 1k, deshalb zu >>100%> voll
Danke erstmal für Deine schnelle Antwort.
Das stimmt. Aber ich habe 32k externen Ram. Sorry, ist aus meinem
Beitrag nicht klar geworden.
Andreas schrieb:> Aber ich habe 32k externen Ram.
Das musst du dem Linker auch mitteilen.
Früher™ nahm der Linker per default sehr viel RAM an, egal wieviel der
konkrete AVR wirklich hatte. Jetzt ist das genauer herunter gebrochen
worden, mit der exakten Menge an RAM für jeden AVR.
Probier mal, ob
1
-Wl,--defsym=__DATA_REGION_LENGTH__=32768
funktioniert. Das wäre zumindest das Symbol, auf das der Linkerscript
zurück greift. Kann auch sein, dass man das über den Compiler mitteilen
kann – vielleicht schlägt Johann ja hier auf und weiß aus dem Hut mehr
dazu.
Jörg W. schrieb:> Probier mal, ob> -Wl,--defsym=__DATA_REGION_LENGTH__=32768>> funktioniert. Das wäre zumindest das Symbol, auf das der Linkerscript> zurück greift. Kann auch sein, dass man das über den Compiler mitteilen> kann – vielleicht schlägt Johann ja hier auf und weiß aus dem Hut mehr> dazu.
Perfekt. Du bist der Beste. Es ist nicht nur so, dass die Software sich
fehlerfrei compilieren und linken lässt, sie läuft auch.
Vielen Dank
Johann L. schrieb:> Siehe zum Beispiel die AVR-LibC Doku zu "Symbols in the Default Linker> Script":
Erstmal auch Dir danke für Deine Bemühungen.
Aber irgendwie funktioniert das nicht oder ich habe es nicht verstanden.
Es gibt immer noch Fehler beim Linken. Folgendes habe ich ausprobiert
und beim Linken übergeben:
Bei allen drei Versuchen bekomme ich immer angezeigt:
section `.bss' is not within region 'data' und als Adresse 0x801040
Kannst Du mir sagen, wie der Aufruf richtig sein muss?
Vielen Dank
Weil ich dachte, ich hätte mich von AVR-Studio irritieren lassen. Dort
muss das ohne 0x80 angegeben werden.
Aber das Ergebnis bleibt dasselbe. Irgendwas mache ich falsch. Es
funktioniert bisher nur mit der von Jörg vorgeschlagenen Lösung
Nur zwecks der Neugier: Früher hätte man sowas per Linker Script
geregelt, einfach und übersichtlich. Ist das hier AVR-spezifisch oder so
eine neumodische IDE-Erfindung?
Diese Symbole werden im Linker Script gesetzt und können im Programm
verwendet werden. Zum Beispiel braucht der Startup Code diese Symbole,
um Static Storage korrekt initialisieren zu können. Diese Symbole
umzudefinieren ist so, als würdest du schreiben
1
#define INT_MAX 2147483647
und dann erwarten, dass int ein 32-Bit Typ ist.
Wie es geht, hat Jörg bereits geschrieben:
Das Layout der data Region kann durch Definieren der genannten Symbole
angepasst werden
wobei START die Startadresse der Region ist und LEN deren Länge in
Bytes, also zum Beispiel LEN=32k.
__DATA_REGION_ORIGIN__wurde erst mit Binutils v2.40 2023-01-14
PR29741 eingeführt; mit älteren Versionen endet die data Region also vor
dem physikalischen Ende vom XRAM. Eine mögliche Abhilfe ist, LEN so zu
vergrößern, dass data bis zum Ende vom XRAM reicht.
Dann bleibt noch die Frage, wo der Stapel liegen soll. Üblicherweise
nutzt der das interne SRAM, und daher wird SP mit RAMEND weak
initialisiert. Falls SP einen anderen Startwert erhalten soll, dann
kann man Symbol __stack entsprechend setzen.
Bauform B. schrieb:> Nur zwecks der Neugier: Früher hätte man sowas per Linker Script> geregelt, einfach und übersichtlich. Ist das hier AVR-spezifisch oder so> eine neumodische IDE-Erfindung?
Ein Symbol zu definieren ist immer noch einfacher, als ein eigenes
Linker Script zu maintainen. Die o.g. Symbole werden ja vom default ld
Script verwendet, also gibt es keinen Grund, das Rad neu zu erfinden.
Johann L. schrieb:> Das Layout der data Region kann durch Definieren der genannten Symbole> angepasst werden-Tdata=START -Wl,--defsym,__DATA_REGION_ORIGIN__=START> -Wl,--defsym,__DATA_REGION_LENGTH__=LEN> wobei START die Startadresse der Region ist und LEN deren Länge in> Bytes, also zum Beispiel LEN=32k.
Danke Dir. Werde ich nächste Woche ausprobieren. Dieses Wochenende
schaffe ich es nicht mehr.
Johann L. schrieb:> Ein Symbol zu definieren ist immer noch einfacher, als ein eigenes> Linker Script zu maintainen.
Das war auch mein Horror. Ich hatte nur nach der Fehlermeldung gegoogelt
und dort wurde mehrfach erwähnt, das Linkerscript anzupassen. Damit wäre
ich aber wahrscheinlich hoffnungslos überfordert gewesen.
Vielen Dank Euch beiden für die gute Hilfe
Andreas schrieb:> Damit wäre ich aber wahrscheinlich hoffnungslos überfordert gewesen.
Ist keine Raketenwissenschaft. Insgesamt aber finde ich den Ansatz der
AVR-GNU-Toolchain, generische Linkerscripts mitzuliefern und damit alles
"aus der Dose 'raus" aus einer Hand zu haben viel besser als das
Gewurschtel bei ARM (jetzt mal auf Cortex-M bezogen), wo jede IDE jedes
Herstellers ihr eigenes Linkerscript und natürlich dazu passend ihren
eigenen Startup-Code mitliefert.
> Ein Symbol zu definieren ist immer noch einfacher, als ein eigenes> Linker Script zu maintainen.
Ich weiss nicht. Was gibt es da gross zu maintainen? Ich hab
fuer alle meine Projekte immer ein eigenes Linkerscript.
Beim aufsetzen kopiere ich das schamlos von einem alten
Projekt, lese das einmal mit eingeschaltetem Verstand durch
und passe 1-2 Werte an und nur wenn sich was ernstes
an meinem Projekt aendert gehe ich da nochmal rein.
Vanye
Vanye R. schrieb:> Ich hab> fuer alle meine Projekte immer ein eigenes Linkerscript.
Kann man machen, muss man aber nicht.
Code für einen AVR kannst du halt¹ mit sowas wie
compilieren, und das bestehende ELF-File kannst du wie es ist flashen.
Bequemer geht's nicht, finde ich. Der einzige nennenswerte Unterschied
zum Compilieren eines Host-Programms ist die Angabe des MCU-Typs.
¹ Natürlich nur, wenn das Setup keine Besonderheiten hat wie eben hier
der externe RAM.
Jörg W. schrieb:> Probier mal, ob> -Wl,--defsym=__DATA_REGION_LENGTH__=32768>> funktioniert.Johann L. schrieb:> Das Layout der data Region kann durch Definieren der genannten Symbole> angepasst werden-Tdata=START -Wl,--defsym,__DATA_REGION_ORIGIN__=START> -Wl,--defsym,__DATA_REGION_LENGTH__=LEN> wobei START die Startadresse der Region ist und LEN deren Länge in> Bytes, also zum Beispiel LEN=32k.
Ich wollte mich bei Euch beiden nochmal bedanken. Ich habe es heute
morgen getestet. Die Software funktioniert mit Euren Angaben perfekt.
Allerdings habe ich noch was (zumindest für mich) erstaunliches
festgestellt.
Wenn ich die Software mit der Version 4.3.3 compiliere und linke, dann
funktioniert die auch, wenn ich beim linken nicht angebe, dass der
externe RAM vorhanden ist. An Ram wird über avr-size angegeben, dass
322,3% benötigt werden. Sobald ich aber den RAM nur geringfügig erhöhe
(329,7%) läuft meine Software nicht mehr. Selbst wenn ich beim Linken
angebe, dass der externe RAM vorhanden ist.
Wird exakt dieselbe Software mit dem avr-gcc 7.3.0 erstellt, läuft die
Software einwandfrei. Beim Linken muss aber:
angegeben werden.
Dieselbe Software für den AT90CAN128 funktioniert aber auch mit der
Version 4.3.3. Hier ist jedoch kein externer Ram angeschlossen und auch
nicht beim Linken eingestellt, weil der genug internen hat.
Es wird also Zeit, dass ich mal auf eine neue Version umsteige. Bisher
habe ich das immer vermieden, da es mit dem Eclipse-Plugin so schön
einfach war. Aber das funktioniert seit einiger Zeit, aufgrund von
Änderungen bei avr-dude, sowieso nicht mehr vollständig.
Aber trotzdem vielen Dank. Ihr habt mir richtig weitergeholfen. Ohne
Euch wäre ich aufgeschmissen gewesen.
Andreas schrieb:> Aber das funktioniert seit einiger Zeit, aufgrund von Änderungen bei> avr-dude, sowieso nicht mehr vollständig.
Hm. Seit wann denn genau?
Oliver
Oliver S. schrieb:> Hm. Seit wann denn genau?
Habe ich vor ein paar Wochen festgestellt, als ich auf eine neue Version
von avr-dude umsteigen musste. Normalerweise könnte man das über das
Eclipse-Plugin ganz komfortabel einstellen und die Software auch
übertragen. Das geht jetzt nicht mehr. Hab irgendwo gelesen, dass in den
config-Dateien von avrdude was geändert wurde und deshalb das
eclipse-plugin nicht mehr funktioniert. Dafür habe ich mir eine
Batch-Datei erstellt. Ist nur nervig, wenn man den Controller wechselt.
Der Programmierer des Plugins, Thomas Holland, war damals auch hier im
Forum aktiv. Aber ich glaube das letzte Update ist schon was länger her.
Andreas schrieb:> Wenn ich die Software mit der Version 4.3.3 compiliere und linke, dann> funktioniert die auch, wenn ich beim linken nicht angebe, dass der> externe RAM vorhanden ist.
Kommt auf die Distro an. Bei v4.3.3 vermutlich WinAVR-20100110 o.ä.
Wie gesagt ist die Compilerversion unerheblich, was zählt ist die
Binutils-Version und welche Patches da reingepackt sind. Ein Binutils
Install enthält Kopien die default ld-Skripte in
$prefix/avr/lib/ldscripts
Interessant ist hier die Definition der data Region: Zunächst war es
1
data (rw!x) : ORIGIN = $DATA_ORIGIN, LENGTH = $DATA_LENGTH
dann 2015
1
data (rw!x) : ORIGIN = $DATA_ORIGIN, LENGTH = __DATA_REGION_LENGTH__
und 2023 schließlich
1
data (rw!x) : ORIGIN = __DATA_REGION_ORIGIN__, LENGTH = __DATA_REGION_LENGTH__
Geschichte:
https://sourceware.org/git/?p=binutils-gdb.git;a=history;f=ld/scripttempl/avr.sc;hb=HEAD
Dabei sind die $-Werte architekturspezische (genau genommen
Emulation-spezifische) Konstanten, die idR so definiert sind, dass
$DATA_ORIGIN + $DATA_LENGTH = 64 KiB.
Die __-Werte sind Symbole, deren default-Wert der jeweilige $-Wert ist.
Wenn also niemand (zB Startup-Code oder Anwender) die Symbole definiert,
dann ändert sich auch nix an deren Wert.
Definition der $-Werte geschieht in den avr*.sh Dateien:
https://sourceware.org/git/?p=binutils-gdb.git;a=tree;f=ld/emulparams;hb=HEAD
Exakte Werte sind nützlich, damit der Likner meckert wenn eine Region
überläuft und damit nicht in die Hardware passt. Ist die Region zu
groß, damm stört das den Linker nicht; es kann aber sein, dass ein nicht
funktionierender Code erstellt wird. Und das ist natürlich mühsam zu
debuggen.
> An Ram wird über avr-size angegeben, dass 322,3% benötigt werden.
Also eine hornalte Version von avr-size mit Patches, die es nie ins
offizielle Repo geschafft hat.
> Sobald ich aber den RAM nur geringfügig erhöhe> (329,7%) läuft meine Software nicht mehr. Selbst wenn ich beim Linken> angebe, dass der externe RAM vorhanden ist.
Was heißt "RAM erhöhen" ?
Wie gesagt: Aufs Linken an sich hat da keinen Einfluss, lediglich auf
Diagnostics.
> -Wl,--defsym=__DATA_REGION_LENGTH__=32768
Geht übrigens auch kürzer als ...=32k
Erstmal Danke, dass Du Dir noch die Mühe gemacht hast, das nochmal so
detailliert zu erklären.
Johann L. schrieb:> Bei v4.3.3 vermutlich WinAVR-20100110 o.ä.
Stimmt, genau die. Die hatte ich damals installiert, ich glaube als ich
angefangen habe eclipse zu verwenden. Da die bisher immer funktioniert
hatte, habe bin ich meinen Grundsätzen (Never touch a running system)
treu geblieben. Aber jetzt geht es wohl nicht mehr.
Johann L. schrieb:> Interessant ist hier die Definition der data Region: Zunächst war es
Ich habe versucht mit der alten Version (WinAVR-20100110) und den Linker
mit folgendem Parameter aufgerufen:
Es funktioniert aber nicht. Möglicherweise habe ich das aber auch nicht
richtig verstanden und die Definitionen sind falsch. Die Software läuft
dann nicht mehr an, wenn ich den "RAM erhöhe" (Erklärungen dazu später).
Johann L. schrieb:> Also eine hornalte Version von avr-size mit Patches, die es nie ins> offizielle Repo geschafft hat.
Das verstehe ich nicht. Selbst wenn ich avr-size aus der avr-version
7.3.0 nehme, habe ich diese Angabe.
Johann L. schrieb:> Was heißt "RAM erhöhen" ?
RAM erhöhen war von mir bescheuert ausgedrückt. Es hätte wohl besser
"Ram-Verbrauch erhöhen" heissen müssen. Kurz zur Erklärung, wie ich das
meinte. Ich habe ein Array, darin sind die einzelnen Elemente
Strukturen. Diese Strukturen bestehen aus einer Vielzahl von Elementen
mit unsigned int und unsigned char. Wenn ich das Array um 2 Einträge
erhöhe, dann läuft die Software nicht mehr. Das ist allerdings nur bei
WinAVR2010 so, bzw. wie Du geschrieben hattest, bei der dazugehörigen
Version von Binutils. Erstelle ich das Ganze mit avr 7.3.0 und nehme
auch die entsprechend Binutils-Version, dann klappt es.
Johann L. schrieb:> Geht übrigens auch kürzer als ...=32k
Danke, ist geändert.
Andreas schrieb:> Selbst wenn ich avr-size aus der avr-version 7.3.0 nehme, habe ich diese> Angabe.
"avr-version 7.3.0", was genau ist das?
Vermutlich Microchips mit privaten Patches zusammen gefrickelte
Toolchain.
In den regulären Tools gibt jeweils separate Versionen für GCC, Binutils
und AVR-LibC, da diese auch separat gepflegt werden.
In den regulären Binutils hat das size-Kommando ebendiese AVR-Patches
nie gesehen, und deren ursprünglicher Autor (dürte noch von Eric
Weddington stammen) hatte damals auch gleich gesagt, dass er gar nicht
die Absicht hatte, das als offizielle Patches einzureichen – eben weil
ihm klar war, dass so ein Hack da nie offiziell Bestand haben würde.
Jörg W. schrieb:> "avr-version 7.3.0", was genau ist das?>> Vermutlich Microchips mit privaten Patches zusammen gefrickelte> Toolchain.
Ich musste erst noch einmal suchen woher ich die hatte. Deine Vermutung
stimmt.
https://ww1.microchip.com/downloads/aemDocuments/documents/DEV/ProductDocuments/SoftwareTools/avr8-gnu-toolchain-3.7.0.1796-win32.any.x86_64.zipJörg W. schrieb:> In den regulären Tools gibt jeweils separate Versionen für GCC, Binutils> und AVR-LibC, da diese auch separat gepflegt werden.
Wo finde ich die? Ich bin davon ausgegangen, dass das, wenn die von
Microchip sind, was vernünftiges ist.
Jörg W. schrieb:> In den regulären Binutils hat das size-Kommando ebendiese AVR-Patches> nie gesehen, und deren ursprünglicher Autor (dürte noch von Eric> Weddington stammen) hatte damals auch gleich gesagt, dass er gar nicht> die Absicht hatte, das als offizielle Patches einzureichen – eben weil> ihm klar war, dass so ein Hack da nie offiziell Bestand haben würde.
Das habe ich nicht verstanden. Ich das avr-size nicht schlecht, wenn es
mir den benötigten Flash und Ram anzeigt. Warum war ihm klar, dass das
nichts offizielles wird?
Andreas schrieb:> Jörg W. schrieb:>> In den regulären Tools gibt jeweils separate Versionen für GCC, Binutils>> und AVR-LibC, da diese auch separat gepflegt werden.>> Wo finde ich die?
Beispielsweise in den Ausgaben der einzelnen Tools:
1
$ avr-gcc --version
2
avr-gcc (GCC) 14.1.0
3
Copyright (C) 2024 Free Software Foundation, Inc.
4
This is free software; see the source for copying conditions. There is NO
5
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
6
7
$ avr-ld --version
8
GNU ld (GNU Binutils) 2.40
9
Copyright (C) 2023 Free Software Foundation, Inc.
10
This program is free software; you may redistribute it under the terms of
11
the GNU General Public License version 3 or (at your option) a later version.
12
This program has absolutely no warranty.
Schwieriger ist es für die AVR-LibC, da es für diese keine installierten
ausführbaren Kommandos gibt. Hier musst du entweder deine
Paketquellenverwaltung fragen, oder wenn du weißt, wo die Dateien
installiert sind, kannst du dir den Inhalt von version.h anzeigen
lassen:
1
$cat/usr/local/avr/include/avr/version.h
2
/* Copyright (c) 2005, Joerg Wunsch -*- c -*-
3
All rights reserved.
4
…
5
6
/** \ingroup avr_version
7
String literal representation of the current library version. */
8
#define __AVR_LIBC_VERSION_STRING__ "2.3.0git"
(In meinem Falle ist es also eine Entwicklerversion direkt aus dem Git,
die ich installiert habe.)
> Das habe ich nicht verstanden. Ich das avr-size nicht schlecht, wenn es> mir den benötigten Flash und Ram anzeigt. Warum war ihm klar, dass das> nichts offizielles wird?
Weil die GNU Binutils generisch für eine riesige Palette von CPUs (und
MCUs) sind, der Hack aber lediglich AVRs beinhaltete, und davon dann
halt auch noch eine eigene Kopie dieser Information.
Wenn man es hätte richtig machen wollen, hätte man eine Kopie dieser
Information irgendwo im Dateisystem hinterlegt und dann sowohl GCC, ggf.
den Linker und eben das size-Kommando darauf zugreifen lassen, und hätte
dies für alle möglichen MCUs zumindest bereitstellen sollen. Die gesamte
Klasse der Cortex-M MCUs hat ja nicht weniger Bedarf an derartiger
Information.
Da Eric dazu keine Motivation hatte, blieb es halt ein Hack, den er in
sein WinAVR eingebaut hat, ohne dass der jemals offizialisiert worden
wäre.
Jörg W. schrieb:> Beispielsweise in den Ausgaben der einzelnen Tools:
Das hatte ich falsch ausgedrückt. Mit
"Wo finde ich die?"
meinte ich, wo ich die regulären Tools zum Download finde. Bei Dir steht
dort z.B. "avr-gcc (GCC) 14.1.0". Bei mir 4.3.3.
Im Rahmen meiner Fehlersuche habe ich versucht die aktuellen,
offiziellen Versionen der Tools und allem drumherum zu finden. Dabei
habe ich nur die von mir genannten gefunden.
Jörg W. schrieb:> Da Eric dazu keine Motivation hatte, blieb es halt ein Hack, den er in> sein WinAVR eingebaut hat, ohne dass der jemals offizialisiert worden> wäre.
Danke für die Erklärung. Habe ich jetzt verstanden.
Jörg W. schrieb:> Schwieriger ist es für die AVR-LibC, da es für diese keine installierten> ausführbaren Kommandos gibt.
In einer Shell kann man zum Beispiel:
Andreas schrieb:> Mit> "Wo finde ich die?"> meinte ich, wo ich die regulären Tools zum Download finde.
Beim Packager deines geringsten Misstrauens.
Tools wie GCC oder GNU Binutils oder AVR-LibC liefern erst einmal nur
Sourcecode.
Den kannst du jetzt selbst compilieren, oder du suchst dir jemanden, der
ihn für dich compiliert.
Ich kann dir leider nicht sagen, wer sowas aktuell für Windows macht.
Bei den typischen Linux-Distributionen oder auch bei FreeBSD (wo ich
eher zu Hause bin) hast du mehr oder minder aktuelle Versionen in deren
jeweiligen Vertriebskanälen dabei, die das für dich vorcompilieren.
Johann L. schrieb:> Diese Symbole werden im Linker Script gesetzt und können im Programm> verwendet werden. Zum Beispiel braucht der Startup Code diese Symbole,> um Static Storage korrekt initialisieren zu können. Diese Symbole> umzudefinieren ist so, als würdest du schreiben>
1
#define INT_MAX 2147483647
> und dann erwarten, dass int ein 32-Bit Typ ist.
Hab die Doku mal angepasst. Wenn jemand so einen Fehler macht, dann ist
das keine Fehler des Anwenders, sondern der Doku...
Johann L. schrieb:> Hab die Doku mal angepasst. Wenn jemand so einen Fehler macht, dann ist> das keine Fehler des Anwenders, sondern der Doku...
Meinst Du mich damit? Ich verstehe nicht, wo ich das in der Doku
anpassen soll. Hatte auch erst jetzt wieder Zeit reinzusehen, sonst
hätte ich mich eher gemeldet.
Andreas schrieb:> Ich verstehe nicht, wo ich das in der Doku anpassen soll.
Die Aussage war: "Hab das in der Doku angepasst." Da ist ein "ich" am
Anfang des Satzes weggelassen worden. ;-)