Sehr interessant die Bemerkung zum Hex.
Ich habe leider auch noch ein ungelöstes Problem und weiß nicht genau wo ich suchen muß:
Ich benutze WinAVR für die C-Programmierung, AVR-Studio für die Simulation. Für ein Bootlader-Experiment möchte ich im ATmega168 den Code auf 0x1c00 festnageln. Das geht nur leider schief. Aso der Reihe nach:
Mein makefile sieht so aus:
Code:
PRG = bootload
OBJ = bootload.c
MCU_TARGET = atmega168
OPTIMIZE = -O2
DEFS =
LIBS = -lm
# You should not have to change anything below here.
CC = avr-gcc
# Override is only needed by avr-lib build system.
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
override LDFLAGS = -Wl,--section-start=.bootloader=0x1c00,-Map,$(PRG).map
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
all: $(PRG).elf lst text eeprom
$(PRG).elf: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
clean:
rm -rf *.o $(PRG).elf *.eps *.png *.pdf *.bak
rm -rf *.lst *.map $(EXTRA_CLEAN_FILES)
lst: $(PRG).lst
%.lst: %.elf
$(OBJDUMP) -h -S $< > $@
# Rules for building the .text rom images
text: hex bin srec
hex: $(PRG).hex
bin: $(PRG).bin
srec: $(PRG).srec
%.hex: %.elf
$(OBJCOPY) -j .text -j .data -O ihex $< $@
%.srec: %.elf
$(OBJCOPY) -j .text -j .data -O srec $< $@
%.bin: %.elf
$(OBJCOPY) -j .text -j .data -O binary $< $@
# Rules for building the .eeprom rom images
eeprom: ehex ebin esrec
ehex: $(PRG)_eeprom.hex
ebin: $(PRG)_eeprom.bin
esrec: $(PRG)_eeprom.srec
%_eeprom.hex: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
%_eeprom.srec: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@
%_eeprom.bin: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@
# Every thing below here is used by avr-libc's build system and can be ignored
# by the casual user.
FIG2DEV = fig2dev
EXTRA_CLEAN_FILES = *.hex *.bin *.srec
dox: eps png pdf
eps: $(PRG).eps
png: $(PRG).png
pdf: $(PRG).pdf
%.eps: %.fig
$(FIG2DEV) -L eps $< $@
%.pdf: %.fig
$(FIG2DEV) -L pdf $< $@
%.png: %.fig
$(FIG2DEV) -L png $< $@
Im C-Code ist <avr/boot.h> eingebunden und die Funktionen haben alle ihren Prototyp gemäß WinAVR-Doku:
Code:
// function prototypes that go into the bootloader section
void wait1sec () __attribute__ ((section (".bootloader")));
char getChar () __attribute__ ((section (".bootloader")));
void putChar (char data) __attribute__ ((section (".bootloader")));
void sendString (char *string) __attribute__ ((section (".bootloader")));
void sendTheBuffer (int size) __attribute__ ((section (".bootloader")));
void receiveTheBuffer (int size) __attribute__ ((section (".bootloader")));
void xAbort () __attribute__ ((section (".bootloader")));
char xCalcSum(char *data) __attribute__ ((section (".bootloader")));
int xCalcCrc(char *data) __attribute__ ((section (".bootloader")));
void xSendPacket(char packetNum, char *data, char checkMethod) __attribute__ ((section (".bootloader")));
char xReceivePacket (char checkMethod) __attribute__ ((section (".bootloader")));
char receivePackets (char checkMethod) __attribute__ ((section (".bootloader")));
char sendPackets(int packets, char checkMethod) __attribute__ ((section (".bootloader")));
int main (void) BOOTLOADER_SECTION;//__attribute__ ((section (".bootloader")));
Bei der Übersetzung gibt es eine Warnung, weil bei diesem Controller die eeprom.h nicht funktioniert, aber das benutze ich hier auch nicht, also ignorieren.
Das erzeugte Map-File sieht auch noch vertrauenerweckend aus (besonders die letzten Zeilen):
Code:
Archive member included because of file (symbol)
C:/Programme/Atmel/WinAVR/bin/../lib/gcc/avr/3.4.3/avr5\libgcc.a(_copy_data.o)
C:\DOCUME~1\tfeli6\LOCALS~1\Temp/cck1aaaa.o (__do_copy_data)
C:/Programme/Atmel/WinAVR/bin/../lib/gcc/avr/3.4.3/avr5\libgcc.a(_clear_bss.o)
C:\DOCUME~1\tfeli6\LOCALS~1\Temp/cck1aaaa.o (__do_clear_bss)
Allocating common symbols
Common symbol size file
xPacketBuffer 0x85 C:\DOCUME~1\tfeli6\LOCALS~1\Temp/cck1aaaa.o
Memory Configuration
Name Origin Length Attributes
text 0x00000000 0x00020000 xr
data 0x00800060 0x0000ffa0 rw !x
eeprom 0x00810000 0x00010000 rw !x
*default* 0x00000000 0xffffffff
Linker script and memory map
Address of section .data set to 0x800100
LOAD C:/Programme/Atmel/WinAVR/bin/../lib/gcc/avr/3.4.3/../../../../avr/lib/avr5/crtm168.o
Address of section .bootloader set to 0x1c00
LOAD C:\DOCUME~1\tfeli6\LOCALS~1\Temp/cck1aaaa.o
LOAD C:/Programme/Atmel/WinAVR/bin/../lib/gcc/avr/3.4.3/../../../../avr/lib/avr5\libm.a
LOAD C:/Programme/Atmel/WinAVR/bin/../lib/gcc/avr/3.4.3/avr5\libgcc.a
LOAD C:/Programme/Atmel/WinAVR/bin/../lib/gcc/avr/3.4.3/../../../../avr/lib/avr5\libc.a
LOAD C:/Programme/Atmel/WinAVR/bin/../lib/gcc/avr/3.4.3/avr5\libgcc.a
.hash
*(.hash)
.dynsym
*(.dynsym)
.dynstr
*(.dynstr)
.gnu.version
*(.gnu.version)
.gnu.version_d
*(.gnu.version_d)
.gnu.version_r
*(.gnu.version_r)
.rel.init
*(.rel.init)
.rela.init
*(.rela.init)
.rel.text
*(.rel.text)
*(.rel.text.*)
*(.rel.gnu.linkonce.t*)
.rela.text
*(.rela.text)
*(.rela.text.*)
*(.rela.gnu.linkonce.t*)
.rel.fini
*(.rel.fini)
.rela.fini
*(.rela.fini)
.rel.rodata
*(.rel.rodata)
*(.rel.rodata.*)
*(.rel.gnu.linkonce.r*)
.rela.rodata
*(.rela.rodata)
*(.rela.rodata.*)
*(.rela.gnu.linkonce.r*)
.rel.data
*(.rel.data)
*(.rel.data.*)
*(.rel.gnu.linkonce.d*)
.rela.data
*(.rela.data)
*(.rela.data.*)
*(.rela.gnu.linkonce.d*)
.rel.ctors
*(.rel.ctors)
.rela.ctors
*(.rela.ctors)
.rel.dtors
*(.rel.dtors)
.rela.dtors
*(.rela.dtors)
.rel.got
*(.rel.got)
.rela.got
*(.rela.got)
.rel.bss
*(.rel.bss)
.rela.bss
*(.rela.bss)
.rel.plt
*(.rel.plt)
.rela.plt
*(.rela.plt)
.text 0x00000000 0xa2
*(.vectors)
.vectors 0x00000000 0x68 C:/Programme/Atmel/WinAVR/bin/../lib/gcc/avr/3.4.3/../../../../avr/lib/avr5/crtm168.o
0x00000000 __vectors
0x00000000 __vector_default
0x00000068 __ctors_start = .
*(.ctors)
0x00000068 __ctors_end = .
0x00000068 __dtors_start = .
*(.dtors)
0x00000068 __dtors_end = .
*(.progmem.gcc*)
*(.progmem*)
0x00000068 . = ALIGN (0x2)
*(.init0)
*(.init1)
*(.init2)
.init2 0x00000068 0xc C:/Programme/Atmel/WinAVR/bin/../lib/gcc/avr/3.4.3/../../../../avr/lib/avr5/crtm168.o
*(.init3)
*(.init4)
.init4 0x00000074 0x16 C:/Programme/Atmel/WinAVR/bin/../lib/gcc/avr/3.4.3/avr5\libgcc.a(_copy_data.o)
0x00000074 __do_copy_data
.init4 0x0000008a 0x10 C:/Programme/Atmel/WinAVR/bin/../lib/gcc/avr/3.4.3/avr5\libgcc.a(_clear_bss.o)
0x0000008a __do_clear_bss
*(.init5)
*(.init6)
*(.init7)
*(.init8)
*(.init9)
.init9 0x0000009a 0x4 C:/Programme/Atmel/WinAVR/bin/../lib/gcc/avr/3.4.3/../../../../avr/lib/avr5/crtm168.o
*(.text)
.text 0x0000009e 0x4 C:/Programme/Atmel/WinAVR/bin/../lib/gcc/avr/3.4.3/../../../../avr/lib/avr5/crtm168.o
0x0000009e __vector_22
0x0000009e __vector_1
0x0000009e __vector_24
0x0000009e __vector_12
0x0000009e __bad_interrupt
0x0000009e __vector_6
0x0000009e __vector_3
0x0000009e __vector_23
0x0000009e __vector_25
0x0000009e __vector_11
0x0000009e __vector_13
0x0000009e __vector_17
0x0000009e __vector_19
0x0000009e __vector_7
0x0000009e __vector_5
0x0000009e __vector_4
0x0000009e __vector_9
0x0000009e __vector_2
0x0000009e __vector_21
0x0000009e __vector_15
0x0000009e __vector_8
0x0000009e __vector_14
0x0000009e __vector_10
0x0000009e __vector_16
0x0000009e __vector_18
0x0000009e __vector_20
0x000000a2 . = ALIGN (0x2)
*(.text.*)
0x000000a2 . = ALIGN (0x2)
*(.fini9)
*(.fini8)
*(.fini7)
*(.fini6)
*(.fini5)
*(.fini4)
*(.fini3)
*(.fini2)
*(.fini1)
*(.fini0)
0x000000a2 _etext = .
.data 0x00800100 0x146 load address 0x000000a2
0x00800100 PROVIDE (__data_start, .)
*(.data)
.data 0x00800100 0x146 C:\DOCUME~1\tfeli6\LOCALS~1\Temp/cck1aaaa.o
*(.gnu.linkonce.d*)
0x00800246 . = ALIGN (0x2)
0x00800246 _edata = .
0x00800246 PROVIDE (__data_end, .)
.bss 0x00800246 0x85
0x00800246 PROVIDE (__bss_start, .)
*(.bss)
*(COMMON)
COMMON 0x00800246 0x85 C:\DOCUME~1\tfeli6\LOCALS~1\Temp/cck1aaaa.o
0x0 (size before relaxing)
0x00800246 xPacketBuffer
0x008002cb PROVIDE (__bss_end, .)
0x000000a2 __data_load_start = LOADADDR (.data)
0x000001e8 __data_load_end = (__data_load_start + SIZEOF (.data))
.noinit 0x008002cb 0x0
0x008002cb PROVIDE (__noinit_start, .)
*(.noinit*)
0x008002cb PROVIDE (__noinit_end, .)
0x008002cb _end = .
0x008002cb PROVIDE (__heap_start, .)
.eeprom 0x00810000 0x0
*(.eeprom*)
0x00810000 __eeprom_end = .
.stab
*(.stab)
.stabstr
*(.stabstr)
.stab.excl
*(.stab.excl)
.stab.exclstr
*(.stab.exclstr)
.stab.index
*(.stab.index)
.stab.indexstr
*(.stab.indexstr)
.comment
*(.comment)
.debug
*(.debug)
.line
*(.line)
.debug_srcinfo
*(.debug_srcinfo)
.debug_sfnames
*(.debug_sfnames)
.debug_aranges 0x00000000 0x4c
*(.debug_aranges)
.debug_aranges
0x00000000 0x4c C:\DOCUME~1\tfeli6\LOCALS~1\Temp/cck1aaaa.o
.debug_pubnames
0x00000000 0xf3
*(.debug_pubnames)
.debug_pubnames
0x00000000 0xf3 C:\DOCUME~1\tfeli6\LOCALS~1\Temp/cck1aaaa.o
.debug_info 0x00000000 0x59e
*(.debug_info)
.debug_info 0x00000000 0x59e C:\DOCUME~1\tfeli6\LOCALS~1\Temp/cck1aaaa.o
*(.gnu.linkonce.wi.*)
.debug_abbrev 0x00000000 0x1b2
*(.debug_abbrev)
.debug_abbrev 0x00000000 0x1b2 C:\DOCUME~1\tfeli6\LOCALS~1\Temp/cck1aaaa.o
.debug_line 0x00000000 0x529
*(.debug_line)
.debug_line 0x00000000 0x529 C:\DOCUME~1\tfeli6\LOCALS~1\Temp/cck1aaaa.o
.debug_frame
*(.debug_frame)
.debug_str 0x00000000 0x24e
*(.debug_str)
.debug_str 0x00000000 0x24e C:\DOCUME~1\tfeli6\LOCALS~1\Temp/cck1aaaa.o
0x292 (size before relaxing)
.debug_loc
*(.debug_loc)
.debug_macinfo
*(.debug_macinfo)
OUTPUT(bootload.elf elf32-avr)
.bootloader 0x00001c00 0x47c
.bootloader 0x00001c00 0x47c C:\DOCUME~1\tfeli6\LOCALS~1\Temp/cck1aaaa.o
0x00001c00 wait1sec
0x00001cdc xCalcSum
0x00001dae xReceivePacket
0x00001e5c receivePackets
0x00001c70 sendTheBuffer
0x00001ec6 sendPackets
0x00001c36 putChar
0x00001f20 main
0x00001cfc xCalcCrc
0x00001d4c xSendPacket
0x00001cc8 xAbort
0x00001c46 sendString
0x00001c20 getChar
0x00001c9c receiveTheBuffer
Bis hierher haben die Tools verstanden was ich von Ihnen will. Die Adresslage paßt noch.
Das Hex-file steht dann aber "daneben":
Code:
:100000000C9434000C944F000C944F000C944F004F
:100010000C944F000C944F000C944F000C944F0024
:100020000C944F000C944F000C944F000C944F0014
:100030000C944F000C944F000C944F000C944F0004
:100040000C944F000C944F000C944F000C944F00F4
:100050000C944F000C944F000C944F000C944F00E4
:100060000C944F000C944F0011241FBECFEFD4E02E
:10007000DEBFCDBF12E0A0E0B1E0E2EAF0E002C0F6
:1000800005900D92A634B107D9F712E0A6E4B2E0CC
:1000900001C01D92AB3CB107E1F70C94900F0C949A
:0200A00000005E
:1000A2000D0A582D4D4F44454D20746573740D0A49
:1000B200747970652027722720746F2072656365DA
:1000C20069766520646174612066726F6D206F725B
:1000D2002027732720746F2073656E642064617417
:1000E2006120746F207465726D696E616C0D0A0017
:1000F2000D0A3E003A20756E6B6E6F776E20636F4D
:100102006D6D616E6400202D3E2072656164792000
:10011200746F20726563656976652C2077616974F6
:10012200696E6720666F722064617461207061631A
:100132006B65747300202D2063616E63656C6C6562
:1001420064202873657276657220646964206E6F1C
:100152007420726573706F6E642077697468696E5B
:1001620020313230732900202D3E2072656164797E
:1001720020746F2073656E642C2077616974696ED8
:100182006720666F72207265717565737400202D29
:10019200207472616E736D697373696F6E20636F21
:1001A2006D706C6574656400202D207472616E73CD
:1001B2006D697373696F6E2061626F72746564003A
:1001C200202D207472616E736D697373696F6E2076
:1001D20061626F727465642064756520746F206556
:0601E20072726F727300DF
:00000001FF
Alles ist wie immer ab Adresse 0x0000 referenziert, auch AVR-Studio zeigt mir in der Simulation Nonsens in der falschen Adresslage an (die Bootreset-Option habe ich auf 0x1c00 eingestellt). Also scheint es am Generator für die Hex-Files / makfile zu liegen. Aber wo?
Muß ich dem Hex-File-Generator (avr-objcopy?) noch etwas im makefile mitteilen? Wenn ja was und wie? In der Doku (zu WinAVR) habe ich es noch nicht gefunden.
Bevor sich jetzt jemand wundert: Dies ist bisher irgendein Programm, das im Bereich des Bootloaders residieren soll, ohne SPM und alles. Erst wenn das stimmt, gehe ich an die Entwicklung des eigentlichen Bootladers...
Lesezeichen