Hallo zusammen, ich habe mir gerade an etwas (fast) die Zaehne ausgebissen: (Dass der gnu-as einen anderen Pseudo-Op Syntax hat, hab ich schnell hingekriegt :-|) Irgendwas stimmt mit den Adressen und dem .org Pseudo im Zusammenhang mit dem Atmel ATmega (hier ATmega32) nicht: Wenn ich im *.S-file ein .org URXCaddr rjmp int_rxc einfuege und mit avr-as assembliere, zeigt der Atmel Disassembler mir diesen Befehl an der Adresse 0x0D an, obwohl im m32def.inc file folgendes steht: .equ URXCaddr, 0x01a ; USART Receive Complete Interrupt Vec Gebe ich jedoch in das .S file 0x0034 ein, funktioniert es und der Befehl kommt an die (Atmel)-Adresse 0x001a Die Erklaerung mag sein, dass avr-as davon ausgeht, dass (zumindest beim .org Pseudo) immer 8-Bit Bloecke adressiert werden, dagegen fuer Atmel immer 16-Bit adressiert werden, und daher kommt der schoene Faktor 2. (Nur das hex, das der AVR Disassembler `richig' anzeigt, funktioniert dann auch auf der Zielhardware.) Gibt es noch andere Fallen, die beim avr-as lauern? Das heisst ja, man braucht ein ganzes neues Set an *.inc Dateien fuer den avr-as? Gibt es jemanden, der den avr-as voellig problemlos einsetzt? Schoene Gruesse Thorsten PS: meine `toolchain' ist: avr-gcc -Os -mmcu=ATmega32 -o dram.o dram.S avr-objcopy -j .text -O ihex dram.o dram.hex Anbei mein Test-File.
> Wenn ich im *.S-file ein > .org URXCaddr rjmp int_rxc > einfuege ... .org ist böse. ;-) Bei einer Toolchain mit verschieblichen Objektmoduln sollte man .org prinzipiell vermeiden, da es ja erst der Linker ist, der die einzelnen Objekte an die passenden Stellen im Speicher schiebt. Wenn man also bestimmte Dinge an bestimmten Adressen haben will, sollte man das dem Linker kund tun (in diesem Falle zum Beispiel über separate .section's, deren Startadressen man im Linkerscript hinterlegt). Das hat übrigens gar nichts mit AVR oder GNU-Tools zu tun, das war schon unter CP/M beim M80 und L80 so. Dein Beispiel ist dahingehend eine Ausnahme: du hast alles in einer Datei und benutzt die Verschieblichkeit des Objekts praktisch nicht. > ..., zeigt der Atmel Disassembler mirdiesen Befehl an der Adresse > 0x0D an ... Die Atmel-Tools und -Datenblätter arbeiten im ROM mit 16-bit-Worten als Einheit, da der ROM im Prinzip so organisiert ist. ,,Im Prinzip'' deshalb, weil man ihn mit LPM trotzdem byteweise zugreifen kann. Außerdem ist es natürlich verwirrend, unterschiedliche Speicherbereiche mit unterschiedlich großen Wortgrößen innerhalb der Tools zu adressieren. Wenn du stattdessen den GNU-Disassembler benutzt (avr-objdump -d), dann bekommst du auch konsistente Adressierung. > Das heisst ja, man braucht ein ganzes neues Set an *.inc Dateien > fuer den avr-as? Du kannst auch #include <avr/io.h> nehmen, allerdings lies dir bitte vorher die Doku (in der avr-libc-Doku) durch. Die IO-Register werden dann anders benutzt oder du musst einen Kompatibilitätsmodus einschalten. > Gibt es jemanden, der den avr-as voellig problemlos einsetzt? Den GCC? ;-) > PS: meine `toolchain' ist: > avr-gcc -Os -mmcu=ATmega32 -o dram.o dram.S Das "-Os" ist bedeutungslos, wenn du gar nicht compilierst... Außerdem benennst du die Ausgabedatei auf .o, was per Konvention impliziert, dass es sich um ein verschiebliches Objektmodul handeln würde. In der Tat lässt du den Compiler aber auch noch den Linker aufrufen, d. h. die Objektdatei ist nicht mehr verschieblich. Unter Unix wäre sie in diesem Falle normalerweise endungslos, in der AVR-GCC-Welt hat sich der Suffix .elf dafür eingebürgert (obwohl die verschieblichen .o-Datei ebenfalls ELF-Dateien sind). Ich bin mir übrigens nicht ganz sicher, ob der Compiler in dieser Aufrufform noch die Interruptvektoren aus gcrt1.S mit einbinden will oder nicht, eigentlich ist diese Aufrufform für C-Code vorbehalten (bei der neben den Interruptvektoren noch ein minimales Laufzeitsystem für das Initialisieren der Variablen, den Aufruf von main() und den abschließenden Aufruf von exit() existiert). Wie der Linker genau vom Compiler aus aufgerufen wird, kannst du dir durch hinzufügen der Option -v sagen lassen.
Hallo Jörg! Vielen Dank fuer Deine ausfuehrliche Antwort! > .org ist böse. ;-) Habs nur genau so gemacht, wie den meisten Beispielcode fuer das AVRStudio auch ... Aber weil alle es machen, muss es ja nicht gut sein ;-) > Außerdem ist es natürlich verwirrend, unterschiedliche > Speicherbereiche mit unterschiedlich großen Wortgrößen innerhalb der > Tools zu adressieren. Das sollte ins Wiki zum GNU-GCC / avr-as ... weil der selbe Code bei zwei verschiedenen Assemblern nicht das selbe liefert (selber Code = bis auf den etwas anderen Syntax = mit sed modifizierter AVRStudio-Code). I'll do this later. > Wenn du stattdessen den GNU-Disassembler benutzt (avr-objdump -d), > dann bekommst du auch konsistente Adressierung. Das ist korrekt. Deswegen hatte ich gar nicht angefangen, ueber die `wirkliche' Adresse nachzudenken. Erst als ich das .hex-File auseinandergenommen habe, wunderte ich mich sehr ... > Du kannst auch #include <avr/io.h> nehmen, Fuer dieses einfache Projekt bleib ich erstmal bei quick-and-dirty. Aber danke, dass Du mich drauf hingewiesen hast, wie man es am besten und richtigsten macht. Gibts da irgendwo mal ein Beispielprojekt mit Makefile oder so? Bisher habe ich immer nur was fuer C/C++ gefunden. >> Gibt es jemanden, der den avr-as voellig problemlos einsetzt? > Den GCC? ;-) Ich dachte an einen Menschen, der damit handgeschriebenen Assembler-Code assembliert und in den AVR laedt. Wie gesagt, die meisten scheinen ja nur C/C++ einzusetzen. Schoene Gruesse Thorsten
>> Du kannst auch #include <avr/io.h> nehmen, > Gibts da irgendwo mal ein Beispielprojekt mit Makefile oder so? > Bisher habe ich immer nur was fuer C/C++ gefunden. http://www.nongnu.org/avr-libc/user-manual/assembler.html >>> Gibt es jemanden, der den avr-as voellig problemlos einsetzt? >> Den GCC? ;-) > Ich dachte an einen Menschen, der damit handgeschriebenen > Assembler-Code assembliert und in den AVR laedt. Wie gesagt, die > meisten scheinen ja nur C/C++ einzusetzen. Naja, wenn man die GNU-Tools installiert hat, dann vermutlich in erster Linie nicht, um damit Assemblerprojekte zu realisieren. Was aber eher der Fall sein dürfte ist, dass man eine einzelne Assemblerdatei (zum Beispiel für einen Interrupthandler) in ein C-Projekt mit einbindet. Für letzteres habe ich auch mal ein Beispiel für die avr-libc-Doku angefangen, aber das ist noch nicht bis zur Veröffentlichung gelangt bislang.
Hiho. Momentan hab ich den ENC28J60-Teil + ARP/ICMP/UDP/TCP/IRQ-Handling in Assembler und das ganze 'drumherum' in C. Alles mit AVR-GCC/AVR-AS ;-) Es geht also. Über den Sinn läßt sich streiten, aber ich wollte eine kleine TCP-Lib haben (schreibt man ja nicht immer neu das Teil) und die Bequemlichkeit von C, bzw dem Linker für den Rest. Ich verstehe es irgendwie nicht große Assemblerprojekte zu erstellen, die dann haufenweise .asm-Dateien oder .inc-Dateien einbinden. Das gibt doch bestimmt haufenweise Redefines, doppelten Code und sonstigen nicht bedachten Quatsch. Vielleicht fehlt mir dazu auch die Disziplin. Aber dafür gibt's ja die Tool-Chain ;-) Grüße, Freakazoid
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.