Forum: Mikrocontroller und Digitale Elektronik Arduino 328P Resettet sich bei Programmstelle


von Chris J. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich befasse mich mal wieder mit dem AVR nach langer Zrit, eine 
Umstellung wenn man vom STM32 kommt.

Da kein richtiges JTAG Debugging möglich ist ist es schwer 
Programabstürze einzukreisen, vor allem wenn sie hier mit dem 
Verschicken von sms erzeugt werden. Nach dem versenden der sms "aus dem 
RAM", resettet sich der 328P. Die Routine kann mit PROGMEN Inhalten 
befüllt werden aber eben auch mit RAM.

Im DebugMode, wo keine sms verschickt wird, sondern nur der Inhalt per 
debugln() dargestellt wird resettet er sich nicht.

Wenn ich mich recht erinnere kommt dieser Reset gerne vor, wenn das RAM 
knapp wird oder der Stack in den RAM rein läuft. Den WDT habe ich auf 
eine ISR umgelegt.

Wie könnte ich es festellen, ob
int SIM800_SendSMS(const char* text,int mode)
SIM800_CheckForSMS()

und dann noch sprintf vielleicht zu viel RAM brauchen? Die sind ja 
abhängig voneinander.  Die Ausgabe beim Kompilieren sagt mir

954 global
1500 für lokale Variablen frei.

Hat das schon mal jemand gehabt und es gelöst?

Gruss,
Christian

1
  else if (strstr(buf,"info"))
2
  {
3
    char tm[6];
4
    if (flags.AlarmEnable)  strcpy(tm,"ON");
5
    else           strcpy(tm,"OFF");
6
    sprintf(buf,"Mode: %d\rAlarm: %s\rCelsius: %d Grad\rBatterie: %02u%%",modus,tm,(int)Temperature,BattProzent);
7
    SIM800_SendSMS(buf,RAM);
8
  }
1
 /* Kopiert einen Text aus dem Flash ins Ram */
2
void ReadFromFlash(char* target, const char* source)
3
{
4
  for (word k = 0; k < strlen_P(source);k++) {
5
    *(target + k)    = pgm_read_byte_near(source + k);
6
    *(target + k + 1) = '\0';  /* NUL Terminieren */
7
  }
8
}

von Carl D. (jcw2)


Lesenswert?

Sicher daß ihm nicht das GSM-Teil einfach nur den Strom unter dem 
Hintern wegzieht?

von Carl D. (jcw2)


Lesenswert?

Hab mal das Attachment angeschaut. Wenn man so lange Funktionen hat und 
all lokalen Variablen auf dem albernsten Scope (innerhalb der Funktion) 
hat, dann braucht man max. Stack. Wenn die Debug-Puffer nicht mehr 
benötigt werden, dann sollte man die nicht länger existieren lassen. Der 
Trick sind die geschweiften Klammern. So wie geschrieben, braucht das 
SMS-Senden 256+128+256+Kleinzeug Bytes an Stack.

von Chris J. (Gast)


Lesenswert?

Carl D. schrieb:
> Sicher daß ihm nicht das GSM-Teil einfach nur den Strom unter dem
> Hintern wegzieht?

Nee, das ist mit 4700uf+100nf direkt über dem GSM schon sauber, 200mW 
zieht er maximal nur runter.

Debug hat keine Puffer, die Puffer brauche ich nur für die Strings. 
sprintf dürfte sicherlich aber auch einiges brauchen. Es stürtzt ja nur 
da ab, alles andere läuft einwandfrei.

Wie ginge es denn noch? Die Funktionen entschachteln, zb mit Flags? 
Malloc?
Wichtig wäre mir zu klären, ob das überhaupt die Ursache ist aber wenn 
man nur ein printf als Ausgabe hat, dann kann man das schlecht 
einkreisen.

Christian

von Joachim B. (jar)


Lesenswert?

Chris J. schrieb:
> ....die Puffer brauche ich nur für die Strings.
> sprintf dürfte sicherlich aber auch einiges brauchen. Es stürtzt ja nur
> da ab, alles andere läuft einwandfrei.

aus dem flash oder aus dem SRAM?

nutzt du progmem für die Strings und PSTR()?

von Chris J. (Gast)


Lesenswert?

Joachim B. schrieb:
> Chris J. schrieb:
>> ....die Puffer brauche ich nur für die Strings.
>> sprintf dürfte sicherlich aber auch einiges brauchen. Es stürtzt ja nur
>> da ab, alles andere läuft einwandfrei.
>
> aus dem flash oder aus dem SRAM?
>
> nutzt du progmem für die Strings und PSTR()?

Yupp..... daher muss ich auch unterscheiden wo was her kommt
1
const char flash_sms_empty[]    PROGMEM = "Batterie leer! Powerdown!";
2
const char flash_admin[]        PROGMEM = "Admin OK";
3
const char flash_sysdown[]      PROGMEM = "Shutdown!";

Zum Auslesen ins RAM
1
 /* Kopiert einen Text aus dem Flash ins Ram */
2
void ReadFromFlash(char* target, const char* source)
3
{
4
  for (word k = 0; k < strlen_P(source);k++) {
5
    *(target + k)    = pgm_read_byte_near(source + k);
6
    *(target + k + 1) = '\0';  /* NUL Terminieren */
7
  }
8
}

von Jim M. (turboj)


Lesenswert?

Chris J. schrieb:
> 1500 für lokale Variablen frei.

Nur die lokalen Variablen im o.g. Codeschnipsel brauchen schon 720 
Bytes.

Wenn anderer Code ähnlich aussieht, würde ich hier auf Stack Overflow 
tippen.

von Chris J. (Gast)


Lesenswert?

Jim M. schrieb:
> Wenn anderer Code ähnlich aussieht, würde ich hier auf Stack Overflow
> tippen.

Kann man das irgendwie nachweisen? Ich meine je größer das Programm 
wird, desto enger ist man an den Grenzen und weiss nie ob man sie 
erreicht hat oder knapp verfehlt.

von Oliver S. (oliverso)


Lesenswert?


von Joachim B. (jar)


Lesenswert?

Chris J. schrieb:
> Joachim B. schrieb:
>> nutzt du progmem für die Strings und PSTR()?
>
> Yupp..... daher muss ich auch unterscheiden wo was her kommt
> Zum Auslesen ins RAM
>
>
1
>  /* Kopiert einen Text aus dem Flash ins Ram */
2
>

warum machst du das wenn das RAM knapp wird?

von Thorsten R. (Gast)


Angehängte Dateien:

Lesenswert?

Joachim B. schrieb:
> warum machst du das wenn das RAM knapp wird?

Weil es nicht möglich ist Strings aus dem Flash direkt als Parameter zu 
übergeben bei Arduino. Die müssen erst einzeln ins Ram geholt werden.

Die Schose läuft aber jetzt, nachdem ich den Speicher dynamisch belegt 
habe und wieder freigebe.

Christian

von Christian J. (Gast)


Lesenswert?

Blöde Autoergänzung...

also nochmal: Scheinbar ist es nicht möglich das zur Kompilierzeit raus 
zu kriegen, sondern nur abzuschätzen oder eben genau zu zählen. In 
diversen Foren wird davon abgeraten den heap zu benutzen, zudem ich 
nicht weiss wie gross dieser überhaupt ist. Kann man ja einstellen in 
der Linker Datei.

Somit bleibt es beim Ausprobieren und hoffen.....

Gruss,
Christian

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.