mikrocontroller.net

Forum: Compiler & IDEs WinAVR-20080610: mit -Os kaputtoptimiert ?


Autor: Oleg R. (m_bedded)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe ein Phänomen mit WinAVR-20080610 + AStudio. Wie es für mich 
aussieht, hat -Os etwas zu viel wegoptimiert.

Ein Mega32 soll ein SPI-Slave sein, der 16 Bytes Daten zur Abholung 
bereitstellt. Alles ganz einfach: im ewigen Zyklus wird SlaveSelect 
überwacht (wenn 1->0, Zähler auf 0 setzen). Und im ISR(SPI_STC_vect) den 
Zähler inkrementieren und das nächste Byte in SPDR geladen.

Dies funktioniert auch in Hardware, wenn die Optimierung ausgeschaltet 
ist. Wird aber -Os benutzt, passiert folgendes. Der Zähler wird im 
ewigen Zyklus nicht mehr auf 0 gesetzt. Scheinbar hält der Compiler die 
Anweisung "SpiBufPtr = 0" für eine ohne Auswirkung, obwohl eine ISR eben 
diesen Zähler nutzt.

Was mach' ich bloß falsch?

Hier Ausschnitt aus main():
  while(1)
  {
    cli();
    //SPI slave select edge (nSS falling edge)
    if (!(PINB & 0x10)) {
      if (prev_nSS) {
        PrepSpiSndBuf();
        SpiBufPtr = 0; // <---- diese Anweisung fehlt nachher
        SPDR = SpiSndBuf[SpiBufPtr];
      }
      prev_nSS = 0;
    } else {
      prev_nSS = 1;
    }
    
    if (SpiBufPtr > PKT_SIZE-1) { //receive buffer full
      ReadSpiRecBuf();
    }
    sei();
  }

Und so wurde es übersetzt:
  while(1)
  {
    cli();
 296:  f8 94         cli
    //SPI slave select edge (nSS falling edge)
    if (!(PINB & 0x10)) {
 298:  b4 9b         sbis  0x16, 4  ; 22
 29a:  02 c0         rjmp  .+4        ; 0x2a0 <main+0x3a>
 29c:  81 e0         ldi  r24, 0x01  ; 1
 29e:  04 c0         rjmp  .+8        ; 0x2a8 <main+0x42>
      if (prev_nSS) {
 2a0:  88 23         and  r24, r24
 2a2:  11 f0         breq  .+4        ; 0x2a8 <main+0x42>
        PrepSpiSndBuf();
        SpiBufPtr = 0;
        SPDR = SpiSndBuf[SpiBufPtr];
 2a4:  9f b9         out  0x0f, r25  ; 15
 2a6:  80 e0         ldi  r24, 0x00  ; 0
    }
    
    if (SpiBufPtr > PKT_SIZE-1) { //receive buffer full
      ReadSpiRecBuf();
    }
    sei();
 2a8:  78 94         sei
 2aa:  f5 cf         rjmp  .-22       ; 0x296 <main+0x30>

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

Bewertung
0 lesenswert
nicht lesenswert
"volatile" bei den gemeinsamen Variablen von Prog und Interrupt-Routine 
vergessen.

Autor: Oleg R. (m_bedded)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
stimmt!! Danke vielmals!

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.