Ram wird follgeschrieben

Gast #5668
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
Gast #5670
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);
Gast #5671
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.
Gast #5672
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
Gast #5673
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?
Gast #5674
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?
#5675
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
Gast #5676
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.
Gast #5677
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?

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