Forum: Compiler & IDEs Wieso generiert der Compiler Chaos?


von Tobias Z (Gast)


Lesenswert?

Hallo allerseits,

hab' für ein Projekt (Tiny861, GCC, AVRStudio) schon ein paar KBytes 
Code geschrieben. Bis jetzt hat immer alles funktioniert, aber plötzlich 
erzeugt der Compiler nur noch 'Chaos'. Wenn ich irgendwo im Code etwas 
kleines ändere, dann erzeugt das plötzlich die wildesten Effekte. 
Ausserdem verhält sich das Programm unterschiedlich, je nach 
eingestellter Optimierung, aber auch mit 'O0' funktioniert das Programm 
nicht richtig. Ich benutze keine delays, die sich ja je nach Optimierung 
anders verhalten können, der Code wird mit 0 Warnungen compiliert. Ich 
kann durch Versuche / dummy Code etc. wirklich ausschliessen, dass ich 
dieses Chaos selbst programmiere.
Das Programm enthält zwei Interruptroutinen, siehe unten. Vielleicht 
mach' ich hier etwas falsch. Dank diesen ISRs ist das Debuggen auch 
etwas mühsamer, für den Tiny861 kann ich ja auch nicht den Simulator 
gebrauchen, da dort dessen Timer noch nicht implementiert sind.

Ich vermute aber eher, dass eine Einstellung im Studio / Makefile 
bezüglich des Memorys nicht stimmt. Hab' dort nie was verändert. Was 
kann dort oder generell zu solchem Verhalten führen?

Vielen vielen Dank für jede Hilfe! Tobias


_____________________________

ISR(TIMER0_CAPT_vect){
  cli();
  unsigned char sreg;
  sreg=SREG; //save status reg
        .....

  SREG=sreg;
  sei();
}



ISR(TIMER1_OVF_vect){
  cli();
  unsigned char sreg;
  sreg=SREG; //save status reg
  .....

  SREG=sreg;
  sei();
}

von Kai G. (runtimeterror)


Lesenswert?

Evtl. ist einfach der Speicher voll?

Ansonsten lässt sich ohne Quellcode und einer "Chaosbeschreibung" nicht 
viel dazu sagen...

von Tobias Z (Gast)


Lesenswert?

Nein, das würd' ich nicht vermuten:
_________________________________________________

Build started 3.3.2008 at 14:57:38
avr-gcc.exe  -mmcu=attiny861 -gdwarf-2 -std=gnu99   -Wall 
-DF_CPU=8000000UL -O0 -funsigned-char -funsigned-bitfields -fpack-struct 
-fshort-enums -MD -MP -MT CD1.o -MF dep/CD1.o.d  -c  ../CD1.c
avr-gcc.exe -mmcu=attiny861 -Wl,-Map=CD1.map CD1.o 
controller_configuration.o ADC.o     -o CD1.elf
avr-objcopy -O ihex -R .eeprom  CD1.elf CD1.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" 
--change-section-lma .eeprom=0 --no-change-warnings -O ihex CD1.elf 
CD1.eep || exit 0
avr-objdump -h -S CD1.elf > CD1.lss

AVR Memory Usage
----------------
Device: attiny861

Program:    6502 bytes (79.4% Full)
(.text + .data + .bootloader)

Data:        319 bytes (62.3% Full)
(.data + .bss + .noinit)


Build succeeded with 0 Warnings...

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Definiere Chaos und Normalzustand.

von Tobi (Gast)


Lesenswert?

Das makro ISR sichert doch das SREG! Und schaltet die Global Interrupts 
aus. Das müsste also nicht explizit gemacht werden.
Ist der richtige Prozessor eingestellt?

von Tobi (Gast)


Lesenswert?

OK, ja!

Vielleicht ein STACK Problem?

von Εrnst B. (ernst)


Lesenswert?

Ich vermute einen Stacküberlauf, provoziert durch die sei()s in den 
ISRs.

Bei deinem Code können die ISRs beliebig tief verschachtelt aufgerufen 
werden, schmeiss den ganzen sei, sreg, cli-krempel raus. das macht der 
Compiler schon selber alles richtig.

von Tobias Z (Gast)


Lesenswert?

Danke für alle Antworten!

Ja, unter 'Project options' ist der richtige Typ eingestellt.
Stimmt - dass ISR() das SREG sichert, hab' ich auch irgendwo mal 
gelesen. Könnte ich mal rausnehmen, aber sollte ja auch nicht schaden..?

Mit 'Chaos meine ich, dass offensichtlich Variablen geändert werden, 
wenn ich irgndwo was ändere, das gar nichts mit diesen Variablen zu tun 
hat.
Der Controller erhält (primäre Funktion des Programms) eine 
Eingangsfrequenz und wandelt diese in verschiedene Pulse mit 
Pausenlängen entsprechend der Einganzsfrequenz um.
Wenn ich irgendwo was ändere, das gar nicht die Pulsbreite des 
Ausgangssignals betrifft, so ändert sich diese doch plötzlich, obschon 
im ganzen Programm nur an zwei Orten diese Zeit bestimmt wird, mit 
Konstanten.
Es sieht so aus, wie wenn sich Variablen auf die gleichen Register 
zugreifen o.ä.

Ich weiss, das ist etwas 'trocken', so..
Könnte den Code sonst auch mal schicken, bin aber sicher, dass es an 
sonstigen Einstellungen liegt.

Gruss, Tobias

von Tobi (Gast)


Lesenswert?

Das sieht mir eher nach einem Speicherproblem aus! Entweder ein 
Stack-Überlauf oder ein Fehler im Code, der auf falsche Adressen 
zugreift (z.B aus einem Vektor rausschreiben).
Wenn du das sei() aufrufst sind die Interrupts wieder scharf. Es kommen 
dann aber evtl. noch ein paar Pops. D.h., es könnte ein anderer 
Interrupt dazwischenfunken, bevor die ISR richtig fertig ist.
Tu's lieber mal raus :-)

von Karl H. (kbuchegg)


Lesenswert?

Tobias Z wrote:
> Danke für alle Antworten!
>
> Ja, unter 'Project options' ist der richtige Typ eingestellt.
> Stimmt - dass ISR() das SREG sichert, hab' ich auch irgendwo mal
> gelesen. Könnte ich mal rausnehmen, aber sollte ja auch nicht schaden..?

Doch, das kann es. Weil die Interrupts dann schon frei gegeben
werden, während du noch in einer ISR bist.

Also: Raus mit dem ganzen Krempel.

> Mit 'Chaos meine ich, dass offensichtlich Variablen geändert werden,
> wenn ich irgndwo was ändere, das gar nichts mit diesen Variablen zu tun
> hat.

Der klassische Fehler dazu: Array Zugriffe 'out of bounds'

> Ich weiss, das ist etwas 'trocken', so..
> Könnte den Code sonst auch mal schicken, bin aber sicher, dass es an
> sonstigen Einstellungen liegt.

Ziemlich sicher nicht.
Praktisch alle 'seltsamen Fehler' entpuppen sich letztendlich
meistens als Fehler des Programmierers und nicht des Compilers.

von Tobias Z (Gast)


Lesenswert?

Danke vielmals!

Das mit den SEI()s hat tatsächlich etwas gebracht - wenn ich die 
Eingansfrequenz beim 'Capture' pin unter eine bestimmte Grenze 
verringerte, dann gabs vorher 'noch mehr' Chaos. Ich weiss natürlich, 
dass dies auch 'chaotisch' beschrieben ist, aber sonst müsste ich gleich 
'nen Roman schreiben.
Ganz traue ich der Sache noch nicht sehe immer Dinge, die wie ein 
'Ausflippen' aussehen, aber ich muss wohl zuerst wieder über die Bücher, 
resp. über den µC...

Was ich mir aber immer noch nicht erklären kann, ist, dass mein Programm 
'gar nichts' tut, wenn ich mit der Optimierung 'Os' Compiliere. 
Eigentlich würde ich dasselbe verhalten mit weniger Codesize erwarten.
Was kann hier 'faul' sein, oder was muss ich hierbei beachten?

DANKE!

von Andreas K. (a-k)


Lesenswert?

Wenn Code mit -O0 anders funktioniert als mit -Os, liegt der Fehler fast 
immer beim Anwender. Meistens an fehlendem "volatile".

von Tobi (Gast)


Lesenswert?

Wenn du Variablen in ISR's verwendest, müssen die immer volatile sein!
Volatile heisst, die Variablen liegen im RAM (nicht in Registern) und 
sie werden nicht wegoptimiert.

von Tobias Z (Gast)


Lesenswert?

Danke, das weiss ich und mach' ich auch so. An dem kanns nicht liegen.
Muss wohl weitersuchen, bin aber froh um weitere Ideen!
Tobias

von Andreas K. (a-k)


Lesenswert?

Tips und Ideen funktionieren mit konkretem Code vor der Nase besser als 
frei assoziierend.

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.