Hallo,
ich beschäftige mich derzeit ziemlich viel mit der Erstellung statischer
Bibliothekten in Kombination mit Portabilität (sprich eine Bibliothek
auf allen möglichen Prozessoren mit unterschiedlichen Taktfrequenzen
einsetzbar, auch wenn sie eher hardwarenah sind..)
Jetzt ist mir folgendes Phänomen über den Weg "gelaufen" beim Erstellen
einer Bibliothek die komplett losgelöst von Hardwareinterfaces ist:
Vorgehen:
1. Übersetzen mit avr-gcc OHNE Angabe einer mmcu
2. Archivieren mit ar
Lief auf Atmega88 super, auf Atmega32 super, auf Atmega162 nicht. Hab
dann die Bibliothek speziell für den Mega162 übersetzt und es
funktionierte auch (inkl. auf den beiden anderen Prozessoren, da ja nix
prozessorspezifisches im Code ist).
Als Grund stellte sich heraus, dass beim Compilieren ohne
Prozessorangabe (bzw. auch wenn ich für mega88 compiliere) eine Sektion
__do_copy_data im Objectfile landet. Lt. Internetrecherche ist die zur
Initialisierung globaler und statischer Variablen und wird automatisch
erzeugt, allerdings auch (wenn nich existent) vom AVR-GCC aus der
Library libgcc.a beim Compilieren eingebunden.
(Siehe dazu
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=68548&start=0
oder vergleichbare Quellen)
Beim Compilieren für neuere Prozessoren (Atmega88 beispielsweise)
scheint das keine Probleme zu geben, wenn in der statischen Bibliothek
diese Sektion schon existiert, da kommt der Linker damit klar..
Prozessoren mit >64k Programmspeicher (Bei denen die Sektion existieren
MUSS) hab ich jetzt leider nicht da zum Testen...
Hat da jemand nähere und ausführlichere Informationen über diese
Thematik bzw. ist in der WinAVR-Compilation-Toolchain entsprechend
bewandert dass er mir das erklären könnte? Finde im Netz irgendwie keine
wirklich zufriedenstellende Informationen und Workarounds/Regeln für was
man dann Compiliert, ob diese Sektion bei statischen Bibliotheken eher
rauszuschmeissen ist oder eher beizubehalten.
VG und Danke schonmal
Thomas
__do_copy_data ist keine Section, es ist ebenso wie __do_clear_bss ein
Symbol aus der libgcc. Der zugehörige Code dient zum Initialiseren von
Daten im Static Storage und wird eingelinks, wenn die Symbole in der
Quelle referenziert werden.
__do_copy_data und __do_clear_bss stehen in section .init4. Darüner
hinaus gibe es noch anderen Code zum Aufruf von Constructors (auch in
C), call von main, init von SP und zero-reg, etc. Der Startup-Code ist
ein Mix aus code von libgcc und avr-libc bzw. selbstgeschriebenem Code.
Der libgcc-Teil ist Teil von GCC, die GCC-Quelle ist
./libgcc/config/avr/lib1funcs.S
Falls du Libs erzeugst sollten die mindestens die Granularität von
avr-gccs Multilibs haben. atmega88 (gehört zu avr4: hat kein CALL)
gehört zB zu einer anderen Multilib-Ausprägung wie atmega32 (gehört zu
avr5: hat CALL).
Die Core/MCU-Zuordnung findet sich in
./gcc/config/avr/avr-mcus.def
Für Multilib Meta-Info siehe zB auch auch -print-multi-lib,
-print-multi-os-directory, etc.:
http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html
Hallo Johann,
erstmal vielen Dank für deine Antwort!
Ich lese jetzt schon seit ein paar Tagen in der AVR-GCC Dokumentation,
schön langsam wird einiges klarer.
Könnte mir bitte anhand des folgenden Beispiels jemand bestätigen /
widerlegen, dass ich das ganze richtig verstanden habe?
Ich habe Quelldateien (test.c und test.h), die in eine Library
verwandelt werden sollen.
Ich compiliere jetzt test.c 2x folgendermaßen:
avr-gcc -c -mmcu=avr4 -o avr4/libtest.a test.c
avr-gcc -c -mmcu=avr5 -o avr5/libtest.a test.c
Danach kopiere ich die zwei erhaltenen Libraryfiles in die
entsprechenden lib-Ordner meines GCC-Verzeichnisses, in meinem Fall mit
WinAVR:
C:\WinAVR-20100110\avr\lib\avr4
C:\WinAVR-20100110\avr\lib\avr5
In einem Projekt, in dem nun die Bibliothek verwendet werden soll, wird
ganz normal die Headerdatei (die man dann auch sinnvollerweise im
entsprechenden include-verzeichnis des compilers ablegt) eingebunden
wird, und dem Compiler der Schalter -ltest mitgegeben.
Wird das Projekt jetzt für Mega88 übersetzt, nimmt der Linker jetzt das
Archiv aus C:\WinAVR-20100110\avr\lib\avr4 (weil mega88 auf AVR4-Familie
aufgeschlüsselt wird) und wird das Projekt für Mega32 übersetzt, wird
die libtest.a aus dem avr5-Verzeichnis gewählt?
Hab ich das richtig verstanden?
Prozipiell ist die Vorgehensweise richtig, allerdings würde ich nicht
eine GCC-Installation dafür hacken.
Besser: Ein eigenes Verzeichnis machen mit Unterverzeichnissen wie
include/ und lib/ und diese Verzeichnisse beim Compileren/Linken
mitgeben als Suchpfade per -I bzw. -L. In shell-speek:
Yeah halbwegs verstanden =)
Schon klar dass das Verändern einer Installation nicht der optimale Weg
ist, mir gehts eher ums Prinzip bevor ich mich jetzt an die konkrete
Umsetzung mache.
Kurz zur Erklärung meiner Intention:
Die Inhalte der Bibliothek sind dann aber unter anderem für Schüler und
weniger "gebildete" Programmierer ausgelegt, die gerade mal ein bisschen
angefangen haben auf uC zu arbeiten angefangen haben, leider wird laut
Lehrplan Compilation Chain usw. erst ein oder zwei Jahre später gemacht,
und da möchte ich es bei dem einen Compilerschalter -lLibName belassen,
der in der IDE hinzugefügt wird.
Sind z.B. unter anderem einfach Treibersoftwareteile für die Komponenten
der Experimentierboards der Schule dabei (SD-Card mit FAT, RTC usw.),
also großteils Komponenten die aus Zeit-/ und Vorbildungsgründen vom
Schüler während des Unterrichts weder verstanden werden noch müssen,
jedoch ein ganz nettes Gimmick darstellen und die Motivation fördern.
Und da ist mir eine Bibliothek am einfachsten erschienen, um das schön
zu kapseln und einfach verfügbar zu machen. Dass da drinnen bei der
SD-Karte noch ein Haufen Softwareframework, SPI-Interface usw. läuft ist
dann nebensächlich.
Muss ich mir aber noch konkret anschauen ob das auf vernünftigem Wege
und vor allem ohne Verändern einer fertigen Installation hinhaut oder
eben nicht.
Aber vielen Dank auf alle Fälle für deine Hilfe!
Thomas Bergmüller schrieb:> Muss ich mir aber noch konkret anschauen ob das auf vernünftigem Wege> und vor allem ohne Verändern einer fertigen Installation hinhaut oder> eben nicht.
Na, wenn du quasi Maintainer deiner eigenen pimp-my-WinAVR-Distribution
bist, kannst du ja auch ohne schlechtes Gewissen Änderungen daran
vornehmen ;-)