default von Switch wird nicht abgearbeitt

OP #2737269
Lesenswert?

Hallo Experten,
bin wider mal mit meinem Latein am Ende.
Habe folgenden Code und verstehe nicht warum die default Marke meines 
Switch Blockes nicht ausgeführt wird. Jedenfalls sagt das AvrStudio beim 
erstellen eines bookmark das dieser Teil vom Code der Optimierung zum 
Opfergefallen ist.
1
void RxProt(volatile uint8_t input)
2
{
3
  extern protoIn Proto[2];
4
  static uint8_t pos;
5
  static uint8_t error;
6
  
7
  extern volatile uint8_t protoflag;
8
  static uint8_t *ptr;
9

10
  switch(pos)
11
    {
12
        default:// recive
13
          if (input==START)
14
      {  
15
        Proto[0].start= input;
16
        Proto[1].start= input;
17
        pos++;
18
          }
19
          break;
20
    case 1:
21
        
22
      Proto[0].len= input;
23
      Proto[1].len= input;
24
      pos++;
25
      break;
26
    case 2:
27
      pos++;
28
      switch(input)
29
      {
30
        case 1:
31
          ptr = &Proto[0];
32
          protoflag |= (1<<RxCh1);
33
          Proto[0].adress= input;
34
          break;
35
        case 2:
36
          ptr = &Proto[1];
37
          protoflag |= (1<<RxCh2);
38
          Proto[1].adress= input;
39
          break;
40
        default:
41
          pos=0;
42
          break;
43
      }
44
      break;
45
    //case 1:
46
    //case 2:
47
        case 3:
48
    case 4:
49
    case 5:
50
    case 6:
51
    case 7:
52
    case 8:
53
    case 9:
54
    case 10:
55
    case 11:
56
    case 12:
57
    case 13:
58
      case 14:    
59
      *(ptr+pos )= input;
60
      pos++;
61
      break;
62
    case 15:
63
      *(ptr+pos )= input;
64
      pos++;
65
      //protoflag |= (1<<RxComp);  
66
      //t= CalcCRC16(dataRX,15);
67
      if (CalcCRC16(ptr,15)!=0)//CalcCRC16(dataRX,15)
68
      {
69
        error++;
70
        pos=0;
71
      }
72
      else
73
      {
74
        pos=0;
75
        protoflag |= (1<<RxComp);  
76
        protoflag |= (1<<RxCh1);  
77
        RxLedPort ^= (1<<RxLed);    
78
      }
79
  }
80
}
Ich spreche vom zweitem Switch Block.
das input kommt vom Empfangsinterrupt.
Die Funktion RxProt wird auch im Empfangsinterrupt der Uart aufgerufen

Kann mir jemand auf die Sprünge helfen.
Wenn ich die Optimierung ausschalte dann Funktioniert das Ganze.
Ich habe zwar auf volatile gedacht aber leider kriege ich es nicht hin.

Vielen Dank für Eure Hilfe

Peter
Gast #2737279
Lesenswert?

Aus dem gezeigten Code-Ausschnitt lässt sich die Ursache nicht 
ermitteln.

Reduziere den Code so weit wie möglich, so das er das Problem noch 
zeigt, aber auch kompilierbar ist. Poste ihn als Anhang. Poste auch alle 
Warnings die Du angezeigt bekommst.
Gast #2737282
Lesenswert?

Ganz allgemein kann man noch hinzufügen, das der Compiler aus Deinem 
Quelltext geschlossen hat, das der Default-Fall nie eintreten kann.
Im allgemeinen gilt dieser Schluss auch. Die Ursache wird also in Deinem 
Code liegen.
OP #2737288
Lesenswert?

Danke für die Antworten.
Der Code ist Funktioniert mit Optimierung nicht mehr.
Fakt ist das die variable input mit Sicherheit nicht immer 1 oder 2 ist.
Input ist ja mit den Daten von der Uart gefühlt kann also von 0 bis 255 
alles beinhalten.
Ich werde vrsuchen den Code zu verkleinern und zu Posten.

Danke für Eure Hilfe
Peter

Ps mit Sicherheit ligt der Fehler bei mir.
Gast #2737302
Lesenswert?

>Danke für die Antworten.
Bitte.

>Der Code ist Funktioniert mit Optimierung nicht mehr.
Ein Hinweis, das Du was anderes geschrieben hast, als Du denkst.

>Fakt ist das die variable input mit Sicherheit nicht immer 1 oder 2 ist.
>Input ist ja mit den Daten von der Uart gefühlt kann also von 0 bis 255
>alles beinhalten.
So das sich dann die Frage stellt, warum Du nicht alle 256 Möglichkeiten 
im Switch berücksichtigt hast.
Abgesehen davon, kann es auch durch den Kontrollfluss möglich sein, das 
der Wertebereich an der Stelle des Aufrufs der Funktion eingeschränkt 
ist und der Compiler das aus dem Code statisch analysieren kann. Der 
Eingabewertebereich allein ist nicht entscheidend.

>Ich werde vrsuchen den Code zu verkleinern und zu Posten.
Gut.

>Ps mit Sicherheit ligt der Fehler bei mir.
Nun, "mit Sicherheit" ist vermutlich auch übertrieben, aber er liegt 
wahrscheinlich bei Dir.
OP #2737309
Lesenswert?

Noname schrieb:
> So das sich dann die Frage stellt, warum Du nicht alle 256 Möglichkeiten
> im Switch berücksichtigt hast.

Ich möchte ja bei allen andern Daten außer bei 1 und 2 abbrechen indem 
ich pos auf 0 setze.
Also habe ich es in einer gewissen Art und Weise alle Möglichkeiten 
berücksichtigt.

Peter

Hoffe das ich den Code bald soweit habe das ich in Posten kann
Gast #2737318
Lesenswert?

@ Pier S.

>Ich möchte ja bei allen andern Daten außer bei 1 und 2 abbrechen indem
>ich pos auf 0 setze.
>Also habe ich es in einer gewissen Art und Weise alle Möglichkeiten
>berücksichtigt.

Ja, das hast Du. Meine Frage war nicht relevant. Ein Irrtum meinerseits.

Es bleibt die Möglichkeit das aus dem Kontrollfluss erkennbar ist, das 
andere Fälle ausser 1 und 2 nicht eintreten können.
#2737379
Lesenswert?

In deinem Zip-File:

Ist das mit oder ohne Optimierungen compiliert?

Im LSS-File ist der fragliche Code vorhanden und auch die Sprungleiste 
sieht auf den ersten Blick vernünftig aus.


(Es kommt zwar vor, dass Compiler fehlerhaft ausgeliefert werden. Aber 
es ist selten. In >95% aller Fälle hast du den Fehler im Programm selbst 
programmiert. Compilerfehler würd ich für mich erst mal immer 
ausschliessen und den Fehler erst mal im Code suchen)
Gast #2737384
Lesenswert?

>hab mich zu früh gefreut das Problem ist noch vorhanden.

Ja. Davon sind A.K. und ich ausgegangen.

OK. Code ist vorhanden. Aber ich habe keine Lust das Ganze Gewusel nun 
noch auseinander zu nehmen. Vielleicht ja jemand anders.

Falls sich keiner findet der nicht so faul ist wie ich, reduziere den 
Code soweit, das nur das allernotwendigste vorhanden ist um den Fehler 
reproduzieren zu können. Aber er muss kompilierbar sein.

Was ist eigentlich mit den Warnungen? Keinerlei Warnungen angezeigt?
#2737385
Lesenswert?

Noname schrieb:
>>hab mich zu früh gefreut das Problem ist noch vorhanden.
>
> Ja. Davon sind A.K. und ich ausgegangen.
>
> OK. Code ist vorhanden. Aber ich habe keine Lust das Ganze Gewusel nun
> noch auseinander zu nehmen. Vielleicht ja jemand anders.

Geht mir eigentlich genauso.
Vor allen Dingen dann, wenn ich erst mal das Mischmasch aus 
Tabultor-Einrückungen und Leerzeichen-Einrückungen auseinandersortieren 
und aneinander angleichen muss, um zu sehen ob die { - } Hierarchien 
korrekt sind und mit der vorhandenen Einrückung übereinstimmen.

Ich denke, der fragliche Code wird bei eingeschalteter Optimierung schon 
irgendwo sein. Nur hat der Compiler das eben ein wenig umgestellt, so 
dass er nicht mehr auf den ersten Blick zu finden ist. In a nutshell: 
Ich denke, bei der Suche warum der Code in der optimierten Version nicht 
funktioniert, wird da der falsche Baum angebellt.
Gast #2737399
Lesenswert?

Karl-Heinz schrieb:
>...wird da der falsche Baum angebellt.

Vermutlich. Habe mir nochmal den Eröffnungspost durchgelesen.

>Habe folgenden Code und verstehe nicht warum die default Marke meines
>Switch Blockes nicht ausgeführt wird.

>Jedenfalls sagt das AvrStudio beim
>erstellen eines bookmark das dieser Teil vom Code der Optimierung zum
>Opfergefallen ist.

Das eine hat mit dem anderen nichts zu tun. Durch die Optimierung kann 
es schon sein, das der dahinterliegende Asm-Code irgendwo und noch 
zerfasert herumliegt, so das der Debugger meint er könne die Adresse 
nicht lokalisieren.

Das müsste jetzt nochmal geklärt werden:
1. Funktioniert der Code wirklich nicht.
oder
2. Kann man nur an dem Default keinen Breakpoint (Bookmark ???) setzen.
Gast #2737402
Lesenswert?

Naja. Zwischendurch werkel ich hier gerade an ner STM32F4-Geschichte 
herum. Habe gerade keine Lust so tief einzusteigen. Am Ende ist es 
ohnehin ein Missverständnis oder ein fehlendes volatile oder ne 
Initialisierung, das/die man schon mal nur per Augenschein sehen kann. 
Aber nicht in dem Verhau eben.
Persönliche Seite #2737424
Lesenswert?

Pier S. schrieb:

> Ich spreche vom zweitem Switch Block.

1) Der 2. switch (input) wird nur in case 2 des äusseren switch (input)
   betreten, d.h. im inneren ist input immer 2.  Ergo: der default-Fall
   wird nie gebraucht, ditto case 1.

2) Mach das volatile am Parameter weg, das ist Käse

3) ptr hat den falschen Typ. Proto[0] ist vom Typ protoIn, &Proto[0]
   demnach vom Typ protoIn* und nicht vom Typ uint8_t*.

4) externe Deklarationen gehören bis auf seltene Ausnahmen in einen
   Header, nicht ins C-Modul wo Inkompatibilitäten nicht auffallen.

5) case 15 fehlt ein break. Ist momentan zwar egal, bei Umstrukturierung
   oder Erweiterung des Codes wirst du dir aber den Wolf suchen.

Ich habe folgenden Code verwendet, weil sonst Deklarationen fehlen:
1
#include <stdint.h>
2

3
#define START 0
4

5
typedef struct
6
{
7
    uint8_t start;
8
    uint8_t len;
9
    uint8_t adress;
10
} protoIn;
11

12
enum { RxLed, RxCh1,  RxCh2, RxComp };
13

14
#define RxLedPort *((uint8_t volatile*) 42)
15

16
void RxProt (uint8_t input)
17
{
18
    extern protoIn Proto[2];
19
    static uint8_t pos;
20
    static uint8_t error;
21

22
    extern volatile uint8_t protoflag;
23
    static uint8_t *ptr;
24

25
    switch(pos)
26
    {
27
        default:// recive
28
            if (input==START)
29
            {  
30
                Proto[0].start= input;
31
                Proto[1].start= input;
32
                pos++;
33
            }
34
            break;
35

36
        case 1:
37

38
            Proto[0].len = input;
39
            Proto[1].len = input;
40
            pos++;
41
            break;
42

43
        case 2:
44
            pos++;
45
            switch (input)
46
            {
47
                case 1:
48
                    ptr = &Proto[0];
49
                    protoflag |= (1<<RxCh1);
50
                    Proto[0].adress= input;
51
                    break;
52
                case 2:
53
                    ptr = &Proto[1];
54
                    protoflag |= (1<<RxCh2);
55
                    Proto[1].adress= input;
56
                    break;
57
                default:
58
                    pos=0;
59
                    break;
60
            }
61
            break;
62
        //case 1:
63
        //case 2:
64
        case 3:
65
        case 4:
66
        case 5:
67
        case 6:
68
        case 7:
69
        case 8:
70
        case 9:
71
        case 10:
72
        case 11:
73
        case 12:
74
        case 13:
75
        case 14:    
76
            *(ptr+pos )= input;
77
            pos++;
78
            break;
79
        case 15:
80
            *(ptr+pos )= input;
81
            pos++;
82
            //protoflag |= (1<<RxComp);  
83
            //t= CalcCRC16(dataRX,15);
84
            if (CalcCRC16(ptr,15)!=0)//CalcCRC16(dataRX,15)
85
            {
86
                error++;
87
                pos=0;
88
            }
89
            else
90
            {
91
                pos=0;
92
                protoflag |= (1<<RxComp);  
93
                protoflag |= (1<<RxCh1);  
94
                RxLedPort ^= (1<<RxLed);    
95
            }
96
    }
97
}

hm...

Das äussere swicth ist auf pos :-/, da war ich oben zu fix...

Dafür entält der erzeugte Code Instruktionen für den default des inneren 
switch :-))
Gast #2737435
Lesenswert?

Hm. Der Code geht ohne Optimierung aber nicht mit.
Guck Dir alle in interrupts benutzten Variablen an ob sie wirklich 
volatile sind.


>1) Der 2. switch (input) wird nur in case 2 des äusseren switch (input)
>   betreten, d.h. im inneren ist input immer 2.  Ergo: der default-Fall
>   wird nie gebraucht, ditto case 1.

Der äussere switch hängt nicht von input ab sondern von pos.

pos ist nicht initialisiert!


Gar keine Warnings?
#2737438
Lesenswert?

Pier S. schrieb:

> Wie soll ich dann weiter vorgehen?

Hast du eine Möglichkeit, dir irgendwo Ausgaben machen zu lassen? (LCD, 
noch ne UART)
Wenn ja: Einen kompletten Frame da mal ausgeben lassen und ansehen, was 
du zurückbekommst.
Wenn nein: warum hast du sowas nicht? Programmentwicklung ohne sich auf 
der realen Hardware was ausgeben zu lassen hat immer was von 'Stochern 
im Nebel'


1
typedef volatile struct // 15 Byte
2
{  
3
  uint8_t start;
4
  uint8_t len;
5
  uint8_t adress;
6
  int analog[4] ;
7
  uint8_t  output ;
8
  uint8_t crcerror;
9
  unsigned int crc;
10
}protoIn;

Welche Aussage hat da der Member crcerror?
Ist das die Rückmeldung vom Gerät, dass deine Anfrage einen CRC-Error 
hatte?
Persönliche Seite #2737447
Lesenswert?

Pier S. schrieb:
> Johann L. schrieb:
>> 1) Der 2. switch (input) wird nur in case 2 des äusseren switch (input)
>>    betreten, d.h. im inneren ist input immer 2.  Ergo: der default-Fall
>>    wird nie gebraucht, ditto case 1.
>
> Der äußere switch hat pos als Parameter also kann input alles möglichen
> Werte haben .

Hab mich schon selbst korrigiert:

Johann L. schrieb:

> Das äussere swicth ist auf pos :-/, da war ich oben zu fix...
>
> Dafür entält der erzeugte Code Instruktionen für den default des inneren
> switch :-))
#2737450
Lesenswert?

Der default-Zweig wird auch vom Compiler erzeugt.
Hier der entscheidende Ausschnitt aus dem lss-File.
Der Compiler hat halt eine andere Stelle im Code gefunden, der die 
gleiche Funktion hat.
Das default-Label ist dadurch verlorengegangen, der Code ist aber da.

1
      switch(input)
2
     7da:  89 81         ldd  r24, Y+1  ; 0x01
3
     7dc:  81 30         cpi  r24, 0x01  ; 1
4
     7de:  21 f0         breq  .+8        ; 0x7e8 <RxProt+0x64>
5
     7e0:  82 30         cpi  r24, 0x02  ; 2
6
     7e2:  09 f0         breq  .+2        ; 0x7e6 <RxProt+0x62>
7
     7e4:  3f c0         rjmp  .+126      ; 0x864 <RxProt+0xe0> Das ist der default
8
     7e6:  0f c0         rjmp  .+30       ; 0x806 <RxProt+0x82>
9

10
   ...
11
   
12
      pos=0;
13
     864:  10 92 b1 01   sts  0x01B1, r1  ;                  in R1 steht wohl immer Null
14
     868:  10 c0         rjmp  .+32       ; 0x88a <RxProt+0x106>
15
      }
OP #2737452
Lesenswert?

Karl Heinz Buchegger schrieb:
> Hast du eine Möglichkeit, dir irgendwo Ausgaben machen zu lassen?
> Wenn ja: Einen kompletten Frame da mal ausgeben lassen und ansehen, was
> du zurückbekommst.

Ja habe ich und die Daten kommen auch richtig an.Ohne Optimierung ist 
mein Programm ja auch der Meinung das die Daten richtig sind.

Karl Heinz Buchegger schrieb:
> Welche Aussage hat da der Member crcerror?
> Ist das die Rückmeldung vom Gerät, dass deine Anfrage einen CRC-Error
> hatte?

Ja damit sieht man ob die Gegenstelle Fehler beim Empfangen hatte.
#2737456
Lesenswert?

Pier S. schrieb:
> Karl Heinz Buchegger schrieb:
>> Hast du eine Möglichkeit, dir irgendwo Ausgaben machen zu lassen?
>> Wenn ja: Einen kompletten Frame da mal ausgeben lassen und ansehen, was
>> du zurückbekommst.
>
> Ja habe ich und die Daten kommen auch richtig an.Ohne Optimierung ist
> mein Programm ja auch der Meinung das die Daten richtig sind.

Der Frame den du zurückbekommst ist korrekt? (Ausgeben lassen, sieht das 
plausibel aus?)
Hast du die CRC mal händisch nachgerechnet?
#2737463
Lesenswert?

Andere Frage: Woran merkst du eigentlich, dass 'es nicht funktioniert'. 
Beim Drüberschauen hab ich nichts ausmachen können, das spezifisch auf 
einen CRC Fehler reagiert (ausser der static error Variablen). Du hast 
du noch eine Timeout-Sache inkludiert, kann es sein, dass die anschlägt?
OP #2745965
Lesenswert?

Hallo,
nach einer längeren Pause habe ich wider Zeit gefunden an meinem 
Programm weiter zu machen.
Ich glaube ich mache einen bösen Fehler mit den verwendeten Zeiger.
Ich vermute das ich mir die Daten meines Structur Array zerschieße.
1
typedef volatile struct // 15 Byte
2
{  
3
  uint8_t start;
4
  uint8_t len;
5
  uint8_t adress;
6
  int analog[4] ;
7
  uint8_t  output ;
8
  uint8_t crcerror;
9
  unsigned int crc;
10
}protoIn;
11

12
void RxProt(volatile uint8_t input)
13
{
14
  
15
  static uint8_t pos;
16
  static uint8_t error;
17
  
18
  
19
  static uint8_t *ptr;
20

21
  switch(pos)
22
    {
23
        default:// recive
24
          if (input==START)
25
      {  
26
        test[0].start= input;
27
        test[1].start=input;
28
        pos++;
29
          }
30
          break;
31
    case 1:
32
      test[0].len=input;
33
      test[1].len=input;
34
      pos++;
35
      break;
36
    case 2:
37
      pos++;
38
      switch(input)
39
      {
40
        case 1:
41
          ptr = &test[0];
42
          protoflag |= (1<<RxCh1);
43
          test[0].adress= input;//Proto[0].adress= input;
44
          break;
45
        case 2:
46
          ptr = &test[1];
47
          protoflag |= (1<<RxCh2);
48
          test[1].adress= input;//Proto[1].adress= input;
49
          break;
50
        default:
51
          pos=0;
52
          break;
53
      }
54
      break;
55
    //case 1:
56
    //case 2:
57
        case 3:
58
    case 4:
59
    case 5:
60
    case 6:
61
    case 7:
62
    case 8:
63
    case 9:
64
    case 10:
65
    case 11:
66
    case 12:
67
    case 13:
68
      case 14:    
69
      *(ptr+pos )= input;
70
      pos++;
71
      break;
72
    case 15:
73
      *(ptr+pos )= input;
74
      pos++;
75
      //protoflag |= (1<<RxComp);  
76
      //t= CalcCRC16(dataRX,15);
77
      if (CalcCRC16(ptr,15)!=0)//CalcCRC16(dataRX,15)
78
      {
79
        error++;
80
        pos=0;
81
      }
82
      else
83
      {
84
        pos=0;
85
        protoflag |= (1<<RxComp);  
86
        //protoflag |= (1<<RxCh1);  
87
        RxLedPort ^= (1<<RxLed);    
88
      }
89
      break;
90
  }
91
}
Ich habe den Teil wo ich mit den Zeigern Arbeite nochmal beigelegt.
Ich hoffe jemand kann mir helfen den Fehler zu finden.

Vielen Dank im voraus

Peter
#2746630
Lesenswert?

Karl Heinz Buchegger schrieb:
> Ich hab hier auf dem PC kein AVR-Studio bzw. AVR-Gcc und ich hab auch
> keine Lust da extra einen zu installieren (darf ich auch gar nicht).

Du darfst keine Software installieren? Das ist als Entwickler doch wohl 
unumgänglich...

Pier S. schrieb:
> Mann o Mann bin ich blöd die Structur hat 15 Byte und ich zähle munter
> bis 16 und überschreibe mir die Daten vom nächsten Datensatz.

Das erinnert mich an einen Fehler, den ich diese Woche bei einem Code 
Review gefunden habe: Jemand deklariert ein
int array[17];
und einige Zeilen weiter unten steht dann:
array[17] = 0;

Da kriegt man schon ein wenig Kopfweh...
Gast #2757981
Lesenswert?

Mark Brandis schrieb:
> Das erinnert mich an einen Fehler, den ich diese Woche bei einem Code
> Review gefunden habe: Jemand deklariert ein
> int array[17];
> und einige Zeilen weiter unten steht dann:
> array[17] = 0;
>
> Da kriegt man schon ein wenig Kopfweh...

... und die "magic numbers" hast du nicht angemeckert?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren