mikrocontroller.net

Forum: Compiler & IDEs Wieso generiert der Compiler Chaos?


Autor: Tobias Z (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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();
}

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Evtl. ist einfach der Speicher voll?

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

Autor: Tobias Z (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Definiere Chaos und Normalzustand.

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, ja!

Vielleicht ein STACK Problem?

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Tobias Z (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Tobias Z (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Andreas K. (a-k)
Datum:

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

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Tobias Z (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tips und Ideen funktionieren mit konkretem Code vor der Nase besser als 
frei assoziierend.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.