avr-gcc Assembler Probleme!

OP (Firma: Angestellter/Freelancer) #2825565
Lesenswert?
• ▲
▼
Hi,

Ich versuche einen ATmega8 in Assembler(avr-gcc) unter Linux zu 
programmieren.
1
avr-gcc -c -Wall -Wextra -mmcu=atmega8 ./test.S -o ./test.elf
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.  */
4
#  if __AVR_ARCH__ >= 100
5
#    define __SFR_OFFSET 0x00
6
#  else
7
#    define __SFR_OFFSET 0x20
8
#  endif
9
#endif
10
...
11
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)

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!
Gast #2825727
Lesenswert?
• ▲
▼
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
Gast #2825761
Lesenswert?
• ▲
▼
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
Gast #2825765
Lesenswert?
• ▲
▼
> 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?
OP (Firma: Angestellter/Freelancer) #2825779
Lesenswert?
• ▲
▼
1
#define __SFR_OFFSET 0
2

3
#include <avr/io.h>
4

5
#define tmp r16
6

7
#define MIN r17
8
#define HOUR r18
9

10
.text
11

12
.org 0x000
13
  rjmp RESET
14

15
RESET:
16

17
  ldi MIN, 0x00
18
  ldi HOUR, 0x00
19

20
  ldi tmp, 0xFF
21
  out DDRD, tmp
22
  ldi tmp, 0xFF
23
  out PORTD, tmp
24
test:  RJMP test ; !!! ENDLOSSCHLEIFE zum TESTEN
25

26
  ldi tmp, 0x00  ;input Taster PINC0, PINC1 
27
  out DDRC, tmp
28
  ldi tmp, 0x03
29
  out PORTC, tmp
30

31

32
WHILE:  in tmp, PORTC
33
  sbis PORTC, 0
34
  inc MIN
35
  out PORTD, MIN
36
  sbis PORTC, 1
37
  inc HOUR
38

39
  ldi tmp, 0xFF
40
WAIT:  dec tmp
41
  brne WAIT
42
  rjmp WHILE
1
#!/bin/bash
2
avr-gcc -Wall -Wextra -mmcu=atmega8 -O0 ./test.S -o ./test.elf
3
avr-objcopy -j .text -j .data -O ihex ./test.elf ./test.hex
4
sudo avrdude -c avr910 -p m8 -P /dev/ttyUSB0 -e -U ./test.hex
Persönliche Seite #2825822
Lesenswert?
• ▲
▼
James Bonddraht schrieb:

> Ich versuche einen ATmega8 in Assembler(avr-gcc) unter Linux zu
> programmieren.
>
1
avr-gcc -c -Wall -Wextra -mmcu=atmega8 ./test.S -o ./test.elf
> 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:
1
#include <avr/io.h>
2

3
.text
4

5
;; Eine ISR
6
.global TIMER1_COMPA_vect
7
TIMER1_COMPA_vect:
8
    reti
9

10
;; Programmstart nach crt*.o
11
.global main
12
main:
13
    ;; Code
OP (Firma: Angestellter/Freelancer) #2825934
Lesenswert?
• ▲
▼
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?
Persönliche Seite #2827169
Lesenswert?
• ▲
▼
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
Gast #2827584
Lesenswert?
• ▲
▼
@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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.