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?