Forum: Compiler & IDEs simulavr error: address out of bounds bei Initialisierung SPH


von Ulf R. (roolf)


Lesenswert?

Hallo,

ich begehe gerade meine ersten Schritte mit der AVR-Programmierung; Ziel 
ist ein reines Assemblerprogramm unter Debian Linux mit der gcc 
toolchain zu erstellen und auch zu simulieren.

Programm first.S
1
#include <avr/io.h>
2
#define temp r19
3
4
  .org 0
5
  
6
  ldi temp, lo8(RAMEND)
7
  out _SFR_IO_ADDR(SPL), temp
8
  ldi temp, hi8(RAMEND)
9
  out _SFR_IO_ADDR(SPH), temp
10
11
go:  
12
  rjmp go

wird (durch ein Standard-Makefile) übersetzt mit
1
avr-gcc -c -mmcu=atmega8 -I. -x assembler-with-cpp \
2
  -Wa,-adhlns=obj/first.lst,-gstabs first.S -o obj/first.o
3
avr-gcc -mmcu=atmega8 -I. -gstabs -DF_CPU=14745600UL \
4
  -Os -funsigned-char -funsigned-bitfields -fpack-struct \
5
  -fshort-enums -Wall -Wstrict-prototypes -Wundef \
6
  -Wa,-adhlns=obj/first.o  -std=gnu99 --combine -fwhole-program \
7
  -Wundef -MD -MP -MF .dep/first.elf.d obj/first.o \
8
  --output first.elf -Wl,-Map=first.map,--cref  -nostdlib
9
avr-objcopy -O ihex -R .eeprom first.elf first.hex
10
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
11
  --change-section-lma .eeprom=0 -O ihex first.elf first.eep

Nun ist simulavr in der Version 0.1.2.6 (von 
http://mirror.its.uidaho.edu/pub/savannah/simulavr/) installiert. Die 
Simulation (avr-gdb 6.4) wird gestartet mit
1
simulavr --gdbserver --device atmega8 \
2
        --clock-freq 14745600 --port 4242 &
3
4
avr-gdb

und dort eingegeben
1
file first.elf
2
target remote localhost:4242
3
load
4
s
und mehrfach RETURN zur Einzelschrittsimulation. Es kommt nach einigen 
Schritten zu folgender Fehlermeldung:
1
(gdb) s
2
42              out _SFR_IO_ADDR(SPL), temp
3
(gdb)
4
reset () at first.S:43
5
43              ldi temp, hi8(RAMEND)
6
(gdb)
7
44              out _SFR_IO_ADDR(SPH), temp
8
(gdb)
9
10
storage.h:58: ERROR: address out of bounds: 0x460
11
12
Ignoring packet error, continuing...

Das Disassembler-File first.lss zeigt
1
reset:
2
        ldi temp, lo8(RAMEND)
3
   0:   3f e5           ldi     r19, 0x5F       ; 95
4
        out _SFR_IO_ADDR(SPL), temp
5
   2:   3d bf           out     0x3d, r19       ; 61
6
        ldi temp, hi8(RAMEND)
7
   4:   34 e0           ldi     r19, 0x04       ; 4
8
        out _SFR_IO_ADDR(SPH), temp
9
   6:   3e bf           out     0x3e, r19       ; 62
d.h. der Stackpointer wird offenbar mit 0x045f geladen, was bei 1kB RAM 
und 0x20 für Register und weiteren 0x40 für IO-Register wie erwartet 
ist. Woher kommt dann der obige fehlerhafte Zugriff auf 0x0460?

von Ulf R. (roolf)


Lesenswert?

Fürs Archiv: Ich konnte das Problem lösen. Ursache war offenbar eine 
Verwirrung der gcc-Toolchain durch verschiedene inkompatible Optionen 
(?); meine Aufrufe oben stammten aus einem zusammengegoogelten Makefile.

Der folgende Aufruf
1
avr-cpp -mmcu=atmega8 -o first.s first.S
2
avr-as -mmcu=atmega8 --warn --gstabs -o first.o first.s
3
avr-ld -nostdlib -o first.elf first.o

funktioniert bei mir und führt nun beim Paar simulavr/avr-gdb zum 
erwarteten Ergebnis.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ist aber immer noch nicht völlig korrekt.  Der avr-ld benötigt
ggf. noch ein -mavrX (X = 1...6).  Klappt für den ATmega8 gerade
nur zufällig mit dem Defaultwert.

von Ulf R. (roolf)


Lesenswert?

Danke für den Hinweis auf das fehlende -mavrN bei avr-ld.

Offenbar ist es ziemlich ungewöhnlich, auf den AVR Mikrocontrollern in 
Assembler zu entwickeln - solche zusammenfassenden Informationen zum 
Thema "Reines Assemblerprojekt auf AVR unter Linux" habe ich in den 
einschlägigen Tutorials bisher nur sehr wenige gefunden.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ulf Rolf schrieb:

> Offenbar ist es ziemlich ungewöhnlich, auf den AVR Mikrocontrollern in
> Assembler zu entwickeln

Es gibt sicher ein paar Hanseln, die das tun, aber die werden dann
wohl allesamt den Primitiv-Assembler von Atmel benutzen, der ins
AVR Studio intrigiert ist.

Selbst mit der GNU Toolchain würde ich wohl persönlich alles dem
Frontend namens avr-gcc überlassen.  Mit einer Dateiendung .S ruft
es automatisch Präprozessor und Assembler auf, und es kann auch den
Linker selbst aufrufen.

von Ulf R. (roolf)


Lesenswert?

Jörg Wunsch schrieb:

> Selbst mit der GNU Toolchain würde ich wohl persönlich alles dem
> Frontend namens avr-gcc überlassen.  Mit einer Dateiendung .S ruft
> es automatisch Präprozessor und Assembler auf, und es kann auch den
> Linker selbst aufrufen.

Das hatte ich zuerst versucht, allerdings beim Linken mit avr-gcc den 
Fehler "ldscripts/avr4.x: no such file or directory" erhalten. Mit 
obigem "avr-ld -mavr4 ..." bekomme ich jetzt denselben Fehler. Nach 
einigem Suchen habe ich nun herausgefunden, dass ich das Problem umgehen 
kann, wenn ich dem Linker "-L/usr/lib" als weitere Option mitgebe.

Bleibt die Frage, ob der Weg, Präprozessor, Compiler und Linker alles 
über avr-gcc aufzurufen, gleichwertig ist oder gar Vorteile bietet? Vom 
ästhetischen Programmierer-Gefühl her erscheint mir die 
Parameterübergabe in der Form "-Wa,..." bzw. "-Wl,..." einfach 
unsauberer als ein direkter Aufruf von avr-as bzw. avr-ld.

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
Noch kein Account? Hier anmelden.