Hallo zusammen,
Ich habe mir für meinen Arduino Mega 2560 und das dafür verwendete GSM Modul Sim900 ein Unterprogramm geschrieben, um auf vorhandene SMSen zu überprüfen.
Im Unterprogramm verwende ich dynamischen Speicher, da ich nicht genau weiß wie groß die Antwort bzw. die Nachricht sein wird.
Ich habe jetzt das problem das alles ohne malloc() und free() klarerweise funktioniert. Um das ganze auch langzeitstabil zu machen habe ich malloc() und free() eingeführt.
Verwende ich nur malloc() um den Speicher zu reservieren funktioniert alles weiterhin einwandfrei.
Schreibe ich jedoch auch free() dazu am Ende des Unterprogramms wird das Unterprogramm ausschließlich zwei mal ausgeführt, nicht öfters. Ich schätze es gibt ein Speicherproblem.
Stundenlanges suchen im internet mit unzähligen Möglichkeiten dyn. Speicherverwaltung zu lösen brachten leider kein Ergebnis.
Habe bereits versucht nur den Speicherbereich des Pointer *txt freizugeben, da ich mir dachte, dass durch die Funktion strstr() ja der zweite Pointer *s auf *txt zeigt und somit nur *txt freigegeben werden darf. Zu häufiges oder mehrmaliges aufrufen von free() führt laut Literatur ebenfalls zu Problemen.
Hier mal das Unterprogramm, ich hoffe ihr hättet eine Idee oder irgendeinen Ansatz woher das problem stammen könnte:
Hier der Aufruf im Hauptprogramm:
void loop()
{
int index = 0;
if( (index = IsSMSAvailable()) > 0 )
{
MEGASerial.print("Ausgabe Hauptprog Unread SMS = ");
MEGASerial.println(index);
delay(100);
}
delay(50000);
}
Und hier das betroffene Unterprogramm, wobei mir readLineISSMSAvailable(GSMSerial) immer eine ganze Zeile der Antwort des GSM Moduls liefert, bis \n kommt. Bei erneutem Aufruf wird die nächste Zeile ermittelt, bis eben keine Nachricht mehr vom GSM Modul ansteht.
READ_BUFFER_SIZE_READLINE wurde als globale Variable mit const unsigned int READ_BUFFER_SIZE_READLINE = 151; deklariert.
int IsSMSAvailable()
{
/*
* 17:34:19.605 -> +CMGL: 1,"REC READ","+43660658xxxx","","2019/10/23 17:12:30+08"
17:34:19.673 -> Neuuuu
17:34:19.741 ->
17:34:19.741 -> +CMGL: 7,"REC UNREAD","+43660658xxxx","","2019/10/23 17:09:48+08"
17:34:19.808 -> Testtt
*/
int repeatswitch = 1;
int index;
int i;
state_t state = SendCMD;
char *txt;
char *s;
txt = malloc(sizeof(*txt)*READ_BUFFER_SIZE_READLINE);
s = malloc(sizeof(*s)*READ_BUFFER_SIZE_READLINE);
MEGASerial.println("- - - Funktion IsSMSAvailable - - -");
if( (txt != NULL) && (s != NULL) )
{
while(repeatswitch)
{
switch( state )
{
case SendCMD:
GSMSerial.write("AT+CMGL=\"REC UNREAD\",1\r");
state = ReadLine;
repeatswitch = 1;
break;
case ReadLine:
txt = readLineISSMSAvailable(GSMSerial);
//Gibt ganze Zeile aus
//17:34:19.605 -> +CMGL: 1,"REC READ","+43660658xxxx","","2019/10/23 17:12:30+08"
if (txt != nullptr)
{
if(strcmp(txt, "\0") != 0) //Wenn im String nur \0 steht, soll nichts am SerialMonitor ausgegeben werden, erst bei richtige Daten
{
MEGASerial.print("Empfangen in Unread: ");
MEGASerial.println(txt);
}
if(strstr(txt, "+CMGL:") != 0) //String gefunden im Buffer
{
s = strstr(txt, ":");
if(s != 0)
{
index = atoi(s+2);
MEGASerial.print("Index Nr.: ");
MEGASerial.println(index);
repeatswitch = 0;
flushGSMSerial();
free(txt);
//free(s);
return index;
}
}
else if(strstr(txt, "OK\r\n") != 0) //Wenn Strings ident
{
MEGASerial.println("OK - Keine neue Nachrichten!");
repeatswitch = 0;
flushGSMSerial();
free(txt);
//free(s);
return false;
}
else if(strstr(txt, "ERROR") != 0) //Falls ERROR ausgegeben wird versuche nochmals CMD zu senden
{
state = SendCMD;
repeatswitch = 1;
flushGSMSerial();
MEGASerial.println("ERROR Unread");
}
else if(strstr(txt, "UNDER_VOLTAGE") != 0)
{
repeatswitch = 1;
MEGASerial.println("UNDER_VOLTAGE");
}
else if(strstr(txt, "OVER_VOLTAGE") != 0)
{
repeatswitch = 1;
MEGASerial.println("OVER_VOLTAGE");
}
}
else
{
repeatswitch = 1;
}
break;
}
}
}
else
{
MEGASerial.println("Achtung: Kein virtueller RAM mehr verfügbar!");
}
free(txt);
//free(s);
}
