mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Breakpoint im AVR Studio wird nicht gesetzt


Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich hab im AVR Studio das Problem das ich den Breakpoint beim debuggen 
mit dem JTAGICEmkII nicht überall setzen kann. Aus der Vergangenheit 
kannte ich das nur bei einem Fehler im Code, doch leider kann ich keinen 
finden. Hier der Code der Hauptroutine:
int main(void)
{

  //check if reset was generate through WD
  if(!( MCUSR & (1<<WDRF) ))      
  {
    random_number = get_random();
  }
  
  MCUSR &= ~(1 << WDRF);

  init_avr();
  init_varis();

  PORTB = 0x00;
  DDRB  = 0x3F;  

  PORTC = 0x05;
  DDRC  = 0x3F;

  PORTD = 0x00;
  DDRD |= 0xFE;

  _SEI;

  //watchdog enable
  wdt_enable(WDTO_500MS);

  //get random id
  random_ID = random_number;

  //start_system
  system_start_up(); 

  uc_8 schedule;

  schedule = 0;        
    
  
    while(1){

    //test sequence digital values
    switch(schedule)
    {
      //digital value of 240
      case 0:                  
      if(buffer[0] == 0x05)
      {
        PORTB |= (1 << PB2);        
        schedule++;
      }
      break;

      //digital value of 224
      case 1:                  
      if(buffer[0] == 0x08)
      {
        PORTB |= (1 << PB3);        
        schedule++;
      }
      break;

      //digital value of 96
      case 2:                  
      if(buffer[1] == 0xBB)
      {
        PORTD |= (1 << PD7);
        schedule++;
      }
      break;

      //digital value of 64
      case 3:
      if(buffer[2] == 0xBB)      
      {
        PORTC |= (1 << PC3);
        schedule++;
      }
      break;
      
      //digital value of 0
      case 4:                
      if (buffer[3] == 0x00) 
      {
        PORTC |= (1 << PC5);
        schedule++;
      }
      break;

      //digital value of 248
      case 5:                  
      if((buffer[4] == 0xBB) || (buffer[4] == 0xCC))
      {
        PORTC &= ~(1 << PC5);
        PORTD &= ~(1 << PD7);
        PORTC &= ~(1 << PC3);
        PORTB &= ~(1 << PB2);
        PORTB &= ~(1 << PB3);
        schedule++;
      }
      break;

      //digital value of 72
      case 6:
      if((buffer[5] <= 180) && (buffer[5] >= 70))
      {
        PORTB &= ~(1 << PB2);
        PORTC &= ~(1 << PC5);
        PORTD |= (1 << PD7);
        PORTC |= (1 << PC3);
        PORTB |= (1 << PB3);
        schedule++;
      }
      break;

      //digital value of 16
      case 7:
      if((buffer[6] <= 180) && (buffer[6] >= 70))
      {
        PORTB &= ~(1 << PB3);
        PORTB |= (1 << PB2);
        PORTC |= (1 << PC5);
        PORTD |= (1 << PD7);
        PORTC |= (1 << PC3);
        schedule++;
      }
      break;

      //digital value of 8
      case 8:
      if((buffer[7] <= 180) && (buffer[7] >= 70))
      {
        PORTB |= (1 << PB3);
        PORTB &= ~(1 << PB2);
        PORTC |= (1 << PC5);
        PORTD |= (1 << PD7);
        PORTC |= (1 << PC3);
        schedule++;
      }
      break;

      //digital value of 24
      case 9:
      if((buffer[8] <= 180) && (buffer[8] >= 70))
      {
        PORTB &= ~(1 << PB3);
        PORTB &= ~(1 << PB2);
        PORTC |= (1 << PC5);
        PORTD |= (1 << PD7);
        PORTC |= (1 << PC3);
        schedule++;
      }
      break;

      //digital value of 80
      case 10:
      if((buffer[9] <= 180) && (buffer[9] >= 70))
      {  
        PORTB &= ~(1 << PB3);
        PORTC &= ~(1 << PC5);
        PORTD |= (1 << PD7);
        PORTC |= (1 << PC3);
        PORTB |= (1 << PB2);
        schedule++;
      }
      break;

      //digital value of 0
      case 11:
      if((buffer[10] <= 180) && (buffer[10] >= 70))
      {
        PORTB |= (1 << PB3);
        PORTB |= (1 << PB2);
        PORTC |= (1 << PC5);
        PORTD |= (1 << PD7);
        PORTC |= (1 << PC3);
        PORTB |= (1 << PB5);
        schedule++;
      }
      break;
    }

  }
}


Wenn ich nen Breakpoint im "case 0" bei schedule++; setzen will setzt 
das Studio den Breakpoint an die Stelle der if Abfrage im "case 1". Und 
weiterhin merkwürdig ist, dass wenn ich einen Breakpoint im "case 11" 
bei schedule++; setze, hält der Debugger dort an sobald die if Bedingung 
in "case 0" erfüllt ist. Die anderen Bedingungen "case 1 -10" sind aber 
definitiv noch nicht erfüllt worden.

Liegt das wohl am Code oder hat das Studio Probleme beim debuggen?

Autor: Matthias H. (mathes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Frank

Am AVR-Studio liegt das wahrscheinlich nicht. Ich nutze die 
IAR-workbench und hatte vor einiger Zeit das gleiche Phänomen. Bei mir 
trat das nach einem rebuild nicht mehr auf.

Ich vermute es lag daran, das ich im debugging-mode den Quelltext 
verändert habe. Seit ich bei mir diese Unart abgestellt habe trat der 
Fehler nicht mehr auf. ;-)

Gruß
Matthias

Autor: OliverSo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Optimierung ausgeschaltet?

Oliver

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey,

es lag an der Optimierung. Ausgestellt und schon klappts. Schon 
Merkwürdig.

Danke euch beiden!

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ähm, mal was anderes. Kann es denn sein das durch die 
Optimierungeinstellung sich auch das hex-File ändert? Also das das 
Hauptprogramm sich anders verhält  wenn ich es mit Optimierung 
compiliere oder ohne?

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

Bewertung
0 lesenswert
nicht lesenswert
Frank wrote:
> Ähm, mal was anderes. Kann es denn sein das durch die
> Optimierungeinstellung sich auch das hex-File ändert? Also das das
> Hauptprogramm sich anders verhält  wenn ich es mit Optimierung
> compiliere oder ohne?

Kann durchaus sein.
Im Regelfall ist es dann aber meist ein Fehler im Programm.
Irgendetwas, das laut C-Standard als undefiniertes Verhalten
gilt und das im nicht optimierten Modus anders funktioniert als
im optimierten.

Compiler haben zwar auch Fehler, werden allerdings vor der
Auslieferung gut genug getestet. Die Wahrscheinlichkeit
das du selber der Übeltäter bist, ist um eine Vielfaches höher.

Ein anderes Thema ist natürlich, daß optimierte Programme
schneller laufen. Dadurch kann sich das komplette Timing
verschieben und zu Problemen führen.

Autor: Stefan Kleinwort (_sk_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn der BP mit Optimierung nicht zu setzen ist, dann liegt das oft 
daran, dass an dieser Stelle mit Optimierung kein Code mehr ist, oder 
der Code vom Compiler so umgestellt / optimiert wurde, das AVRStudio 
nicht den "richtigen" Punkt für den BP findet.

Oft hilft, sich die Stelle im Disassembler anzuschauen und dort den BP 
zu setzen.

Ohne Optimierung würde ich nicht unbedingt arbeiten wollen, auch wenn es 
dann "klappt" ....


Stefan

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke!

Was mich nur gewundert hat, ist dass das Programm auf dem Testboard 
einwandfrei läuft und es nur beim debuggen die Probleme gibt.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, jetzt brauch ich nochmal eure Hilfe. Hab mir den Bereich wie Stefan 
vorgeschlagen hat im Disassembler angeschaut.

Optimierung auf -O1
160:          switch(schedule)
+0000008B:   2F8C        MOV     R24,R28          Copy register
+0000008C:   2799        CLR     R25              Clear Register
+0000008D:   27AA        CLR     R26              Clear Register
+0000008E:   27BB        CLR     R27              Clear Register
+0000008F:   01FC        MOVW    R30,R24          Copy register pair
+00000090:   970C        SBIW    R24,0x0C         Subtract immediate from word
+00000091:   F7C0        BRCC    PC-0x07          Branch if carry cleared
+00000092:   5EE6        SUBI    R30,0xE6         Subtract immediate
+00000093:   4FFF        SBCI    R31,0xFF         Subtract immediate with carry
+00000094:   9409        IJMP                     Indirect jump to (Z)
164:            if(buffer[0] == 0x05)
+00000095:   9180015B    LDS     R24,0x015B       Load direct from data space
+00000097:   3085        CPI     R24,0x05         Compare with immediate
+00000098:   F789        BRNE    PC-0x0E          Branch if not equal
166:              PORTB |= (1 << PB2);        
+00000099:   9A2A        SBI     0x05,2           Set bit in I/O register
167:              schedule++;
+0000009A:   5FCF        SUBI    R28,0xFF         Subtract immediate
169:            break;

Optimierung auf -Os
160:          switch(schedule)
+000000AE:   2F8C        MOV     R24,R28          Copy register
+000000AF:   2799        CLR     R25              Clear Register
+000000B0:   27AA        CLR     R26              Clear Register
+000000B1:   27BB        CLR     R27              Clear Register
+000000B2:   01FC        MOVW    R30,R24          Copy register pair
+000000B3:   970C        SBIW    R24,0x0C         Subtract immediate from word
+000000B4:   F7C0        BRCC    PC-0x07          Branch if carry cleared
+000000B5:   5EE6        SUBI    R30,0xE6         Subtract immediate
+000000B6:   4FFF        SBCI    R31,0xFF         Subtract immediate with carry
+000000B7:   9409        IJMP                     Indirect jump to (Z)
164:            if(indicator == 0x05)
+000000B8:   9180015B    LDS     R24,0x015B       Load direct from data space
+000000BA:   3085        CPI     R24,0x05         Compare with immediate
+000000BB:   F789        BRNE    PC-0x0E          Branch if not equal
+000000BC:   C069        RJMP    PC+0x006A        Relative jump


Sieht so aus als ob der Befehl gar nicht erst ausgeführt wird. Aber 
warum funktioniert das Programm dann auf dem Testboard?

Autor: OliverSo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Zurordnung C-Code zu Assemblercode passt bei eingeschalteter 
Optimierung einfach nicht mehr. Es gibt nicht zu jeder Zeile C-Code 
genau einen Block Assembler-Code. Das Programm macht zwar noch das, was 
du willst, aber nicht so, wie du willst. Insofern musst du schon genau 
nachverfolgen, was der Assemblercode macht, und die eingestreuten 
C-Code-Zeilen dabei mehr oder weniger ignorieren.

Wenn alles richtig funktioniert, ist es doch gut. Es gibt gar nicht so 
viele Möglichlichkeiten, ein Programm so zu schreiben, daß es mit 
Optimierung zu anderen Ergebnissen kommt, als ohne. Normalerweise 
handelt es sich dann um vergessene volatile Qualifiers.

Oliver

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.