www.mikrocontroller.net

Forum: Compiler & IDEs Ram wird follgeschrieben


Autor: Florian Pfanner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe einen Controller Programmiert, welcher über den UART Texte 
ausgibt. Sobald ich aber mehr text ausgeben will, so hängt er sich auf. 
Ich hab das Programm mal im AVR-Studio schritt für schritt angeschaut 
und da viel mir auf, dass das ganze Ram mit dem Text für den UART 
follgeschrieben wird und damit die anderen Variablen löscht. Auch den 
Text in mehrere kleine stücke unterteilen bringt nichts, die alten 
stücke im Ram.

Danke, Florian

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja und wie sieht dieses Programm aus?

Autor: Florian Pfanner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier sind die Code-Fragmente:

static volatile unsigned char *uart_data_ptr;
static volatile unsigned char uart_counter;

SIGNAL(SIG_UART_TRANS)
{
    uart_data_ptr++;
    if (--uart_counter)
      outp(*uart_data_ptr, UDR);
}


void uart_send(unsigned char *buf, unsigned char size)
{
  if (!uart_counter)
  {
    uart_data_ptr  = buf;
    uart_counter   = size;
    outp(*buf, UDR);
  }
}


Text ausgeben mit:
uart_send("Text",länge);

Autor: Jonas Diemer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmm, hat das evtl. damit zu tun, dass er (aus welchem grund auch immer, 
so firm bin ich da nicht) den stack mit deinem text vollklatscht? Kann 
eigentlich nur so sein. die frage ist: wieso? wie gesagt, bin da nicht 
so firm.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sehe ich das richtig, es wird einfach ein Zeiger ohne allokierten 
Speicherbereich angelegt und dann munter hineingeschrieben? Das ist aber 
schon ein grober Schnitzer! Irgendwann treffen sich Heap und Stack und 
dann ist Ende im Gelände ;-)

Gruss,

Peter

Autor: Jonas Diemer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
yo, uart_data_ptr zeigte einst auf buf, welches ja aber nur in uart_send 
gültig ist. Das war mir auch aufgefallen... allerdings wird da ja nix 
hingeschrieben, sondern von dort an den UART gesendet...

und uart_counter ist ja global, müsste also tatsächlich irgendwann auf 0 
stehen...

oder seh ich das falsch?

Autor: Florian Pfanner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Problematik habe ich nun erkannt: Der zeiger uart_data_ptr wird 
immer um eins erhöht und zeigt so auf immer einen anderen wert. Also 
auch beim laden von neuen Texten. Kann ich den Zeiger irgendwie 
zurückstellen, also auf einen festen Speicherbereich zeigen lassen?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Florian,

Du must überhaupt erstmal Speicher für den UART-Puffer zuweisen.
Ansonsten schreibst Du mit Deinem Pointer irgendwo ins RAM.

char buffer[40];

char * ptr = buffer;

und dann im Interrupt:

ptr++;
if( ptr == (buffer + sizeof(buffer)) ) // am Ende angelangt ?
  ptr = buffer; // dann wieder von vorne


Peter

Autor: Florian Pfanner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe nun die Routienen umgeschrieben. Sie sehen so aus:

char buffer[41];
char *ptr = buffer;
int laenge;

SIGNAL(SIG_UART_TRANS)
{
  ptr++;
  laenge--;
  if (laenge)
    outp(*ptr,UDR);
}

void uart_send(unsigned char *buf, unsigned char size)
{
  for(;;)
  {
    if (laenge==0)
    {
      laenge=size;
      int t;
      for (t=0;t<=size;t++)
      {
        if (t<=40);
        {
          buffer[t]=PRG_RDB(buf+t);
        }
      }
      ptr=&buffer[0];
      outp(*ptr,UDR);
      break;
    }
  }
}

wenn ich nur den Aufruf:
  char *line1 = PSTR("1.Test von Florian");
  uart_send(line1,18);
schreibe, so funktionierts.

wenn ich aber
  char *line1 = PSTR("1.Test von Florian");
  uart_send(line1,18);
  char *line2 = PSTR("2.Test von Florian");
  uart_send(line2,18);
schreibe, so wird zwar der 1.Text ausgegeben, jedoch der 2.Text nicht 
mehr und der Controller reagiert nicht mehr.

Ich weiß nicht ob ich einen Fehhler in meiner Denkweise oder in meinem 
Algoritmus suchen muss.

Autor: Jonas Diemer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das liegt daran, dass er nach dem ersten interrupt weitermacht. d.h. er 
gibt das erste zeichen aus ('1'), springt, macht dann weiter (Line 2 
laden). dann mach er die zeile

 uart_send(line2,18);

Irgendwann (wenn er fertig ist, mit dem ersten zeichen, keine ahnung, 
wielange das dauert), springt er in den interrupt... verstehst?

Autor: Florian Pfanner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke - Jetzt gehts (ich hab zwischen den Send-Befehle eine 
Pauseroutiene geschrieben). An das Problem habe ich nicht gedacht.

Danke, Florian

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.