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


von Frank (Gast)


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:
1
int main(void)
2
{
3
4
  //check if reset was generate through WD
5
  if(!( MCUSR & (1<<WDRF) ))      
6
  {
7
    random_number = get_random();
8
  }
9
  
10
  MCUSR &= ~(1 << WDRF);
11
12
  init_avr();
13
  init_varis();
14
15
  PORTB = 0x00;
16
  DDRB  = 0x3F;  
17
18
  PORTC = 0x05;
19
  DDRC  = 0x3F;
20
21
  PORTD = 0x00;
22
  DDRD |= 0xFE;
23
24
  _SEI;
25
26
  //watchdog enable
27
  wdt_enable(WDTO_500MS);
28
29
  //get random id
30
  random_ID = random_number;
31
32
  //start_system
33
  system_start_up(); 
34
35
  uc_8 schedule;
36
37
  schedule = 0;        
38
    
39
  
40
    while(1){
41
42
    //test sequence digital values
43
    switch(schedule)
44
    {
45
      //digital value of 240
46
      case 0:                  
47
      if(buffer[0] == 0x05)
48
      {
49
        PORTB |= (1 << PB2);        
50
        schedule++;
51
      }
52
      break;
53
54
      //digital value of 224
55
      case 1:                  
56
      if(buffer[0] == 0x08)
57
      {
58
        PORTB |= (1 << PB3);        
59
        schedule++;
60
      }
61
      break;
62
63
      //digital value of 96
64
      case 2:                  
65
      if(buffer[1] == 0xBB)
66
      {
67
        PORTD |= (1 << PD7);
68
        schedule++;
69
      }
70
      break;
71
72
      //digital value of 64
73
      case 3:
74
      if(buffer[2] == 0xBB)      
75
      {
76
        PORTC |= (1 << PC3);
77
        schedule++;
78
      }
79
      break;
80
      
81
      //digital value of 0
82
      case 4:                
83
      if (buffer[3] == 0x00) 
84
      {
85
        PORTC |= (1 << PC5);
86
        schedule++;
87
      }
88
      break;
89
90
      //digital value of 248
91
      case 5:                  
92
      if((buffer[4] == 0xBB) || (buffer[4] == 0xCC))
93
      {
94
        PORTC &= ~(1 << PC5);
95
        PORTD &= ~(1 << PD7);
96
        PORTC &= ~(1 << PC3);
97
        PORTB &= ~(1 << PB2);
98
        PORTB &= ~(1 << PB3);
99
        schedule++;
100
      }
101
      break;
102
103
      //digital value of 72
104
      case 6:
105
      if((buffer[5] <= 180) && (buffer[5] >= 70))
106
      {
107
        PORTB &= ~(1 << PB2);
108
        PORTC &= ~(1 << PC5);
109
        PORTD |= (1 << PD7);
110
        PORTC |= (1 << PC3);
111
        PORTB |= (1 << PB3);
112
        schedule++;
113
      }
114
      break;
115
116
      //digital value of 16
117
      case 7:
118
      if((buffer[6] <= 180) && (buffer[6] >= 70))
119
      {
120
        PORTB &= ~(1 << PB3);
121
        PORTB |= (1 << PB2);
122
        PORTC |= (1 << PC5);
123
        PORTD |= (1 << PD7);
124
        PORTC |= (1 << PC3);
125
        schedule++;
126
      }
127
      break;
128
129
      //digital value of 8
130
      case 8:
131
      if((buffer[7] <= 180) && (buffer[7] >= 70))
132
      {
133
        PORTB |= (1 << PB3);
134
        PORTB &= ~(1 << PB2);
135
        PORTC |= (1 << PC5);
136
        PORTD |= (1 << PD7);
137
        PORTC |= (1 << PC3);
138
        schedule++;
139
      }
140
      break;
141
142
      //digital value of 24
143
      case 9:
144
      if((buffer[8] <= 180) && (buffer[8] >= 70))
145
      {
146
        PORTB &= ~(1 << PB3);
147
        PORTB &= ~(1 << PB2);
148
        PORTC |= (1 << PC5);
149
        PORTD |= (1 << PD7);
150
        PORTC |= (1 << PC3);
151
        schedule++;
152
      }
153
      break;
154
155
      //digital value of 80
156
      case 10:
157
      if((buffer[9] <= 180) && (buffer[9] >= 70))
158
      {  
159
        PORTB &= ~(1 << PB3);
160
        PORTC &= ~(1 << PC5);
161
        PORTD |= (1 << PD7);
162
        PORTC |= (1 << PC3);
163
        PORTB |= (1 << PB2);
164
        schedule++;
165
      }
166
      break;
167
168
      //digital value of 0
169
      case 11:
170
      if((buffer[10] <= 180) && (buffer[10] >= 70))
171
      {
172
        PORTB |= (1 << PB3);
173
        PORTB |= (1 << PB2);
174
        PORTC |= (1 << PC5);
175
        PORTD |= (1 << PD7);
176
        PORTC |= (1 << PC3);
177
        PORTB |= (1 << PB5);
178
        schedule++;
179
      }
180
      break;
181
    }
182
183
  }
184
}


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?

von Matthias H. (mathes)


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

von OliverSo (Gast)


Lesenswert?

Optimierung ausgeschaltet?

Oliver

von Frank (Gast)


Lesenswert?

Hey,

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

Danke euch beiden!

von Frank (Gast)


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?

von Karl H. (kbuchegg)


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.

von Stefan K. (_sk_)


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

von Frank (Gast)


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.

von Frank (Gast)


Lesenswert?

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

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

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

von OliverSo (Gast)


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

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.