Forum: Mikrocontroller und Digitale Elektronik Compilerfehler oder Programmfehler AVR


von Markus (Gast)


Lesenswert?

Hallo,
ich hab was sehr seltsames bei meinem ATmega88PA bemerkt.
Zum Hintergrund:
es ist ein Programm zum steuern eines GSM Modules, dass im Fehlerfall, 
sprich Heizung ist kaputt, eine SMS an max. 4 Nummern versendet.
Die erste SMS wird an Nummer1 ohne Probleme versendet.
Bei der zweiten SMS wird die Funktion sms_schreiben mit i=2 aufgerufen.
Nicht wie erwartet geht es nach Ende der Funktion zurück sondern beginnt 
wieder am Anfang des GESAMTEN Programmes. Zudem ist mir aufgefallen bei 
der 2ten SMS wird auch buff_schreibe_c Fehlerhaft bearbeitet.
Wie kann ich das Beheben oder den Fehler mehr eingrenzen. Ich habe einen 
ICE3 Debugger.


Program Memory Usage:  4738 bytes   57,8 % Full
Data Memory Usage:  756 bytes   73,8 % Full



hier wird Fall 1 aufgerufen
1
void sms_schreiben_handler(uint8_t fall)
2
{
3
  //Fall 1 = Heizung Fehler
4
  //Fall 2 = Bestätigung nach Nummer geändert
5
  
6
  uint8_t i =0;
7
  char buff_c [100];
8
  uint8_t save = 0;
9
  
10
  if (fall==1)
11
        {  
12
    
13
    for (i=1;i<=(eeprom_nummern.anzahl);i++)
14
    {
15
      save++;
16
      strcpy(sms.text,"Die Heizung meldet einen Fehler");
17
      sms_schreiben(i);
18
      if (save==4)
19
      {
20
        return;
21
      };
22
    };
23
    
24
    return;
25
  };
26
  
27
28
29
  if (fall==2)
30
  {
31
    
32
    strcpy( buff_c, "Es wurden folgende Nummern eingetragen:" );
33
    
34
    switch(eeprom_nummern.anzahl)
35
    {
36
      case 1:
37
      strcat( buff_c, eeprom_nummern.nummer1);
38
      break;
39
      
40
      case 2:
41
      strcat( buff_c, eeprom_nummern.nummer1);
42
      strcat( buff_c,";");
43
      strcat( buff_c, eeprom_nummern.nummer2);
44
      break;
45
      
46
      
47
      case 3:
48
      strcat( buff_c, eeprom_nummern.nummer1);
49
      strcat( buff_c,";");
50
      strcat( buff_c, eeprom_nummern.nummer2);
51
      strcat( buff_c,";");
52
      strcat( buff_c, eeprom_nummern.nummer3);
53
      break;
54
      
55
      case 4:
56
      strcat( buff_c, eeprom_nummern.nummer1);
57
      strcat( buff_c,";");
58
      strcat( buff_c, eeprom_nummern.nummer2);
59
      strcat( buff_c,";");
60
      strcat( buff_c, eeprom_nummern.nummer3);
61
      strcat( buff_c,";");
62
      strcat( buff_c, eeprom_nummern.nummer4);
63
      break;
64
      
65
      
66
    };  
67
    
68
    strcpy(sms.text,buff_c);
69
    
70
    sms_schreiben(1); //Null ist Nummer 1
71
    
72
    
73
    
74
  };
75
76
};
1
void sms_schreiben(uint8_t nummer)
2
{
3
  char buff_schreibe_c[20];
4
  
5
  
6
  
7
  
8
  EIMSK=0x00;
9
  
10
  cli();
11
  sim_guthaben();
12
  wait_sekunden(2);
13
  
14
  uart_puts("AT+CMGF=1"); // Text mode
15
  _delay_ms(100);
16
  
17
18
  
19
  
20
strcpy(buff_schreibe_c,"AT+CMGS="); // Ziel Nummer
21
  
22
  
23
  switch(nummer)
24
  {
25
    case 1:    
26
    strcat(buff_schreibe_c,eeprom_nummern.nummer1);
27
    break;
28
    
29
    case 2:
30
    strcat(buff_schreibe_c,eeprom_nummern.nummer2);
31
    break;
32
    
33
    case 3:
34
    strcat(buff_schreibe_c,eeprom_nummern.nummer3);
35
    break;
36
    
37
    case 4:
38
    strcat(buff_schreibe_c,eeprom_nummern.nummer4);
39
    break;
40
    
41
    
42
    
43
  };
44
  
45
  uart_puts(buff_schreibe_c);
46
  _delay_ms(100);
47
48
  uart_puts(sms.text);
49
  uart_puts(sms.guthaben);
50
// zu testzwecken auskommentiert  uart_putc(0x1A);
51
  
52
  wait_sekunden(5);
53
  
54
  
55
  
56
57
  return;
58
};

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Du kannst mit an Sicherheit grenzender Wahrscheinlichkeit davon ausgehen 
dass es sich nicht um einen Compilerfehler handelt.

Markus schrieb:
> Bei der zweiten SMS wird die Funktion sms_schreiben mit i=2 aufgerufen.
> Nicht wie erwartet geht es nach Ende der Funktion zurück sondern beginnt
> wieder am Anfang des GESAMTEN Programmes.

Reset aufgrund nicht existenten Interrupt-Handlers oder aufgrund eines 
Stack overflows, oder watchdog, oder...

Markus schrieb:
> cli();
>   sim_guthaben();
>   wait_sekunden(2);

das cli() ist zumindest verdächtig

Ich tippe aber auf stack overflow.

von sei (Gast)


Lesenswert?

kein sei()

Aber auch: Mehrere Sekunden mit deaktivierten Interrupts zu blockieren 
riecht nach falschem Design.

von Markus (Gast)


Lesenswert?

Ja, ich hoffe es les liegt an mir dann kann ich es beheben.
Wie soll ich das am besten mit Sei()/cli() lösen?
Ist es besser die Interrupts direkt zu deaktivieren?

von Markus (Gast)


Lesenswert?

Ich brauch in der Funktion sim_guthaben() Timer1 um ein Timeout zu 
erzeugen.

von Rolf M. (rmagnus)


Lesenswert?

Markus schrieb:
> Ja, ich hoffe es les liegt an mir dann kann ich es beheben.
> Wie soll ich das am besten mit Sei()/cli() lösen?

Die Interrupts immer nur so kurz wie irgend möglich sperren. cli() und 
sei() immer paarweise benutzen. Wo ist das sei() zu dem cli() in 
sms_schreiben?

> Ist es besser die Interrupts direkt zu deaktivieren?

Schwer zu sagen, da unbekannt ist, welche Interrupts es bei dir 
überhaupt gibt, was sie machen und wie sie mit dem restlichen Programm 
zusammenarbeiten.

Ansonsten: Einen Stackoverflow kann ich mir auch vorstellen, da dein 
Speicher ja mit statischen Variablen schon recht voll ist und die 
gezeigten Funktionen auch nicht sehr sparsam damit umgehen.

von g457 (Gast)


Lesenswert?

Ein Stacküberlauf ist sogar sehr wahrscheinlich. Aber wie man schon an 
dem kurzen Codeauszug sehen kann, gibt es massenhaft Speicherbereiche, 
die man problemlos in den Flash verschieben kann.

von Marco S (Gast)


Lesenswert?

strncpy/strncat können helfen, Fehler zu vermeiden.

von Markus (Gast)


Lesenswert?

Cool vielen Dank hab mal wieder dazu gelernt :D
Also ich hab jetzt mal cli(); gelöscht dann gings.

von Marco S (Gast)


Lesenswert?

Schau dir den code ruhig weiter an. Meine Handynummer lässt dein 
buff_schreibe_c überlaufen. Und mit so einem noblen Debugger solltest du 
auch mal spielen.

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.