Ist -c (compile do not link) vielleicht falsch?
Wenn ich ohne -c starte kommt die Fehlermeldung: "undefined reference to
main".
Wie kann ich mir den fertigen Assembler-Code vom avr-gcc anzeigen lassen
(also was er aus meinem macht)?
1
#define __SFR_OFFSET 0
2
#include <avr/io.h>
3
...
4
.org 0x000
5
rjmp RESET
6
7
RESET:
8
ldi r16, 0xFF
9
out DDRD, r16
10
11
ldi r16, 0xFF
12
out PORTD, r16
13
14
end: rjmp end
aus iom8.h
1
/* Port D */
2
#define PIND _SFR_IO8(0x10)
3
#define DDRD _SFR_IO8(0x11)
4
#define PORTD _SFR_IO8(0x12)
aus sfr_defs.h
1
#ifndef __SFR_OFFSET
2
/* Define as 0 before including this file for compatibility with old asm
3
sources that don't subtract __SFR_OFFSET from symbolic I/O addresses. */
Jetzt habe ich #define __SFR_OFFSET 0 in meinem Code, weil ohne gibts
Fehlermeldungen (...must be less than 32 bei SBIS PORTD[im späteren
code]).
Wenn SFR_OFFSET 0x20 ist funktioniert OUT, aber bei SBIS PORTD z.B
funktionierts nicht mehr, da müsste denn für I/O Register 0x20
substrahiert werden ???
Nun weiß ich nicht wie man das nun korrekt macht ???
Danke für Tipps!
Hi
>Wenn SFR_OFFSET 0x20 ist funktioniert OUT, aber bei SBIS PORTD z.B>funktionierts nicht mehr, da müsste denn für I/O Register 0x20>substrahiert werden ???
Dir ist aber klar, das der mögliche Adressbereich von 'sbis/sbis'
kleiner als der von 'in/out' ist?
MfG Spess
Spess53 schrieb:> Dir ist aber klar, das der mögliche Adressbereich von 'sbis/sbis'> kleiner als der von 'in/out' ist?
Ja SBIS (0 - 31(0x1F)) und OUT/IN (0 - 63(0x3F))
Hi
Dann verstehe ich deine Frage
>Wenn SFR_OFFSET 0x20 ist funktioniert OUT, aber bei SBIS PORTD z.B>funktionierts nicht mehr, da müsste denn für I/O Register 0x20>substrahiert werden ???>Nun weiß ich nicht wie man das nun korrekt macht ???
nicht so richtig. Für IO-Register >= 100 wird die Speicheradresse
benutzt und es wird mit sts/lds auf die Register zugegriffen. Bei
Adressen zwischen 32 und 99 werden 0x20 von der Speicheradresse
abgezogen und in/out, und eingeschränkt sbic/sbis, verwendet.
MfG Spess
> Wenn ich ohne -c starte kommt die Fehlermeldung: "undefined reference to
main".
Die Fehlermeldung kommt wohl vom Linker. Wenn Du diesen ausschaltest,
kommt sie nicht.
Kannst Du mal komplette files / das Projekt anhängen?
> Ist -c (compile do not link) vielleicht falsch?
Ja. -c macht preprocess, compile and assemble. Das ist nur ein Teil.
Du will auch den Linker Symbole und Relocations auflösen lassen, Daten
und Funktionen lokatieren lassen, etc.
> Wenn ich ohne -c starte kommt die Fehlermeldung: "undefined reference to> main"
Weil es keine main gibt.
In C-Programmen gibt es eben immer eine main, und da du avr-gcc als
Treiber verwendest, werden auch C-Bibliotheken wie libgcc, (AVR-)libc
und Start-Up Code crt*.o hinzugebunden.
Der Startup-Code initialisiert den µC (SP, R1, .data, .bss), ruft
Konstruktoren auf (.ctors, .dtors) und schliesslich main, exit und
Destruktoren (.dtors), weiters definiert crt*.o die Vektor-Tabelle.
avr-gcc ist nur ein Treiber-Programm, das anhand von -c/-S/-E etc.
Sub-Programme aufruft und mit adäquaten Kommandozeilenoptionen versort.
> Wie kann ich mir den fertigen Assembler-Code vom avr-gcc anzeigen lassen> (also was er aus meinem macht)?
avr-gcc ruft nur den Präprozessor auf, der die # auflöst. Das bekommst
du mit -save-temps. Danach kannst du Dumps/Disassemblies vom Assembler
erzeugen lassen, Disassemblies mit objdump und Map-Files vom Linker.
> .org 0x000> rjmp RESET>> RESET:
Lass das .org weg. Das ist keine absolute Adresse.
Eher sowas, damit zB in der Vector-Tabelle kein Relaxing stattfindet und
.vectors garantiert bei 0 liegt:
1
#include <avr/io.h>
2
3
;; AVR-Libc definiert leider keinen RESET_vect
4
#define RESET_vect_num 0
5
#define RESET_vect _VECTOR (RESET_vect_num)
6
7
;; Vector-Tabelle
8
.section .vectors,"ax",@progbits
9
.global __vectors
10
__vectors:
11
rjmp RESET_vect
12
13
14
;; Programm
15
.text
16
17
RESET_vect:
18
;; Code
Das ganze braucht du natürlich nur, wenn du ohne C-Umgebung arbeitest,
d.h. sowas wie -Wl,-nostdlib -Wl,-nodefaultlibs -nocrt0.
Wie die Optionen genau sind sagt die Doku, hab ich jetzt nicht im Kopf.
Mit C-Umgebung siehts einfach so aus:
Danke schonmal!
Ich bin damit leider völlig überfordert.
Woher hast du dein Wissen, woher komme ich an mehr
Hintergrundinformationen (alle man-pages möchte ich nun nicht lesen)!
Und wie würdest du das fertige Assembler-Programm übersetzen?
James Bonddraht schrieb:> Woher hast du dein Wissen,
Schwer zu sagen. Ich weiß auch nicht mehr, wo und wann ich gelernt hab,
dass Deutschland an Frankreich grenzt...
> woher komme ich an mehr Hintergrundinformationen> (alle man-pages möchte ich nun nicht lesen)!
man ist hier nicht sehr gehaltvoll, aber keine Doku zu lesen ich ein
ganz schlechter Anfang. Brauch man zwar nicht komplett durchzulesen,
aber 5 Minuten überfliegen, um im entscheidenden Moment zu wissen, wo
man was nachschaut, ist Gold wert und spart im Endeffekt viel Zeit und
Nerven.
Da sind zunächst die Doku der Binutils [1], des Compilers [2] und
der AVR-Libc [3].
Startup-Code der AVR-Libc, i.W. die Quelle der crt*.o, findet sich in
[4] und die entsprechenden Teile des Startup-Codes, den die libgcc [5]
beisteuert, ist das, was in .init-Sections steht.
Weiters gibt es ein Tutorial nebs Dome-Projekten [6] in der AVR-Libc.
Schliesslich ist es auch hilfreich, dem Tools bei der Arbeit
zuzuschauen:
- Welchen Code erzeugt der Compiler?
- Wie ruft er Assembler und Linke auf?
- Was steht in eim Map-File?
- Welche Standard-Sections gibt es und wozu dins die gut?
.data, .text, .progmem, .init, .vectos, .comment, .rodata, .bss, ...
- Wie sieht das Disassembly aus?
> Und wie würdest du das fertige Assembler-Programm übersetzen?
Kommt drauf an ob du Bare-Metal magst oder den flauschigen Unterbau
der AVR-Libc bevorzugst mit ihren Headerm, I/O-Definitionsn,
Startup-Code, Vektor-Tabelle, ...
[1] http://sourceware.org/binutils/docs-2.22/
[2] http://gcc.gnu.org/onlinedocs/
[3] http://www.nongnu.org/avr-libc/user-manual
[4]
http://svn.savannah.nongnu.org/viewvc/trunk/avr-libc/crt1/gcrt1.S?&root=avr-libc&view=markup
[5]
http://gcc.gnu.org/viewcvs/trunk/libgcc/config/avr/lib1funcs.S?revision=190644&view=markup
[6] http://www.nongnu.org/avr-libc/user-manual/group__asmdemo.html
@gjlayde
Zu den crts ein kleiner avr-gcc Bug Report:
-mmcu=at90usb1287 bindet crtusb1286 statt crtusb1287 ein.
Falscher Eintrag in der avr-mcus.def?
Macht programmtechnisch keinen Unterschied, da beide bis auf den Namen
identisch sind. In meinem Build-System baue ich die libc aber explizit
für ein Device und dabei ist es gerade aufgefallen.
makefile schrieb:> Zu den crts ein kleiner avr-gcc Bug Report:> -mmcu=at90usb1287 bindet crtusb1286 statt crtusb1287 ein.>> Falscher Eintrag in der avr-mcus.def?
Ja, mach bitte nen Bugreport dafür. Danke.