Moin, ich versuche derzeit verzweifelt ein stück c code auf nem attiny13 zum laufen zu bringen. Allerdings scheint eine leere c funktion dafür zu sorgen, dass der µkontroller nicht läuft: funktionierender code: #define F_CPU 9600000UL #include <avr/io.h> #include <util/delay.h> /* int blabb(){ return 0; } */ int main (void) { DDRB |= (1 << PB3); while(1) { PORTB ^= (1 << PB3); _delay_ms(5); } return 0; } sobald die leere funktion nicht mehr auskommentiert ist, hört PB3 auf zu toggeln. Kann das jemand erklären? objdump der hex files: /////////keine leere funktion 00000000 <.sec1>: 0: bb 9a sbi 0x17, 3 ; 23 2: 98 e0 ldi r25, 0x08 ; 8 4: 88 b3 in r24, 0x18 ; 24 6: 89 27 eor r24, r25 8: 88 bb out 0x18, r24 ; 24 a: ef ed ldi r30, 0xDF ; 223 c: fe e2 ldi r31, 0x2E ; 46 e: 31 97 sbiw r30, 0x01 ; 1 10: f1 f7 brne .-4 ; 0xe 12: 00 c0 rjmp .+0 ; 0x14 14: 00 00 nop 16: f6 cf rjmp .-20 ; 0x4 //////////leere funktion 00000000 <.sec1>: 0: 80 e0 ldi r24, 0x00 ; 0 2: 90 e0 ldi r25, 0x00 ; 0 4: 08 95 ret 6: bb 9a sbi 0x17, 3 ; 23 8: 98 e0 ldi r25, 0x08 ; 8 a: 88 b3 in r24, 0x18 ; 24 c: 89 27 eor r24, r25 e: 88 bb out 0x18, r24 ; 24 10: ef ed ldi r30, 0xDF ; 223 12: fe e2 ldi r31, 0x2E ; 46 14: 31 97 sbiw r30, 0x01 ; 1 16: f1 f7 brne .-4 ; 0x14 18: 00 c0 rjmp .+0 ; 0x1a 1a: 00 00 nop 1c: f6 cf rjmp .-20 ; 0xa
das stimmt etwas beim kompilieren nicht. Am Anfang müsste die ISR-Vektoren kommen, die sehen ich bei dir nicht. Wie erstellt du denn das Binary?
Makefile: CC=avr-gcc CFLAGS=-mmcu=attiny13 -Os -c LDFLAGS= SOURCES=main.c OBJECTS=$(SOURCES:.c=.o) EXECUTABLE=progrm01.elf all: $(SOURCES) $(EXECUTABLE) avr-objcopy -O ihex -j .text -j .data $(EXECUTABLE) $(EXECUTABLE:.elf=.hex) $(EXECUTABLE): $(OBJECTS) $(CC) $(LDFLAGS) $(OBJECTS) -o $@ .cpp.o: $(CC) $(CFLAGS) $< -o $@ clean: rm $(OBJECTS)
Deiner Ausgabe fehlt die Interrupt-Vektor-Tabelle. Normalerweise müsste bei 0 ein Sprung zum Startup-Code stehen, der dann mit main() weiter macht. Bei dir fängt's aber direkt mit der ersten Funktion an. Zeig doch lieber mal den vom Compiler erzeugten Assembler-Code statt eines wieder disassemblierten Binaries. Das wäre etwas übersichtlicher.
monad schrieb: > Makefile: bin mir nicht sicher, aber der linker muss auch wissen was es für ein µC ist. Das sehen ich bei dir nicht.
> CFLAGS=-mmcu=attiny13 -Os -c
-Os Keine Optimierung.
Die leere Funktion wird nicht entfernt.
user@pc$ avr-objdump -h -S progrm01.elf progrm01.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn 0 .text 0000001e 00000000 00000000 00000074 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .data 00000000 00800060 0000001e 00000092 2**0 CONTENTS, ALLOC, LOAD, DATA 2 .comment 00000011 00000000 00000000 00000092 2**0 CONTENTS, READONLY Disassembly of section .text: 00000000 <blabb>: 0: 80 e0 ldi r24, 0x00 ; 0 2: 90 e0 ldi r25, 0x00 ; 0 4: 08 95 ret 00000006 <main>: 6: bb 9a sbi 0x17, 3 ; 23 8: 98 e0 ldi r25, 0x08 ; 8 a: 88 b3 in r24, 0x18 ; 24 c: 89 27 eor r24, r25 e: 88 bb out 0x18, r24 ; 24 10: ef ed ldi r30, 0xDF ; 223 12: fe e2 ldi r31, 0x2E ; 46 14: 31 97 sbiw r30, 0x01 ; 1 16: f1 f7 brne .-4 ; 0x14 <main+0xe> 18: 00 c0 rjmp .+0 ; 0x1a <main+0x14> 1a: 00 00 nop 1c: f6 cf rjmp .-20 ; 0xa <main+0x4>
Peter II schrieb: > monad schrieb: >> Makefile: > > bin mir nicht sicher, aber der linker muss auch wissen was es für ein µC > ist. Das sehen ich bei dir nicht. CFLAGS=-mmcu=attiny13 -Os -c
Kurt schrieb: > -Os Keine Optimierung. > > Die leere Funktion wird nicht entfernt. und? Damit darf das Programm aber nicht fehlerhaft werden. Sein linker aufruf ist falsch.
Kurt schrieb: > Peter II schrieb: >> monad schrieb: >>> Makefile: >> >> bin mir nicht sicher, aber der linker muss auch wissen was es für ein µC >> ist. Das sehen ich bei dir nicht. > > CFLAGS=-mmcu=attiny13 -Os -c linker ist doch $(EXECUTABLE): $(OBJECTS) $(CC) $(LDFLAGS) $(OBJECTS) -o $@ also LDFLAGS.
Kurt schrieb: >> CFLAGS=-mmcu=attiny13 -Os -c > > -Os Keine Optimierung. -Os steht für Größenoptimierung, nicht für keine Optimierung. > Die leere Funktion wird nicht entfernt. Kann sie auch gar nicht, da der Compiler nicht weiß, ob die Funktion von irgendwo anders aus aufgerufen wird. Wenn schon, müßte das der Linker tun. Aber davon abgesehen: Ja, und? Auch wenn die Funktion nicht entfernt wird, sollte sie den Rest trotzdem nicht stören.
vielen Dank, das war der Fehler. Musste natürlich LDFLAGS=-mmcu=attiny13 setzen.
Ich lege beim Linkeraufruf immer noch die CFLAGS dazu, weil das bei bestimmten Optimierungen (LTO) notwendig ist. Schaden tut es m.W. nie. Die LFLAGS sind dann nur für den Linkeraufruf bestimmt.
Ääääh ... und jetzt ist der Code fehlerfrei? Oder funktioniert der Code 'nur', wie man sich das vorgestellt hat, da die leere Funktion weg-optimiert wurde? Tip: Pack die unschöne Funktion ans Ende, dann kann Die auch drin bleiben ohne zu stören - braucht dann aber halt trotzdem Speicher. Würde das wohl .elf File beim Assembler mit dem .lst File gleichsetzen ... Dann sieht man, daß MIT der Funktion, daß dort ein RET an 3.ter stelle steht. (Wie der Compiler auf r24 und r25 kommt ... kA) Da zuvor aber nicht bestimmt zur main gesprungen wird, beginnt der µC bei 0 mit dem Programm - und da kommt nach 3 Befehlen das 'ret' und ein Stapel-Überlauf nimmt seinen Lauf - durch das Return wird die Rücksprung-Adresse vom Stapel runter geholt, was hier wohl dann 0x80e0 oder 0xe080 als Ziel ergeben wird - und da steht dann auch nur Müll, was dann nicht ganz der erwarteten Funktion des Programm entsprechen könnte. MfG
Patrick J. schrieb: > Ääääh ... > > und jetzt ist der Code fehlerfrei? ja, warum denn nicht? Wenn er dem linker nicht die cpu übergibt, dann kann er den STartcode nicht einfügen, deswegen sieht der code so merkwürdig aus.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.