lcd_write Fehlersuche

Gast #5131180
Lesenswert?

ich habe ein programm das alle 20sec Daten von einem controller auf 
einen anderen überträgt. Auf einem tft werden Text und Zahlenwerte 
angezeigt. Nach etwa einem Tag fällt die Übertragung des Textes aus - 
Zahlenwerte werden weiter angezeigt obwol Zahlen und text die gleiche 
Funktion benutzen. lcd_write("123test456"); wird nicht mehr angezeigt. 
Woran kann das liegen?

Das sind die Funktionen:
1
//==================================================
2
void lcd_write(uint8_t* str)
3
{
4
  uint8_t TempChar;
5
    do
6
    {
7
        TempChar = *str++;
8
        if(TempChar<' '||TempChar>130)return;
9

10
        lcd_char(TempChar);
11

12
           curposx =curposx+ f_width;
13
       if(frame)curposx++;
14
    }
15
    while ( *str != 0 );
16
}
17

18
//=============================================
19
void lcd_int3(uint16_t int1){
20
  uint8_t dum[4]={' ',' ',48,'\0'};
21
  u8 s1=0;
22

23
    if (int1>99){
24
        dum[0]=(int1/100+48);
25
    s1=1;
26
    }
27
        int1=int1%100;
28

29
    if (int1>9 || s1){
30
        dum[1]=(int1/10+48);
31
    }
32
        int1=int1%10;
33
        
34
        dum[2]=int1+48; 
35
   
36
        
37
     lcd_write(dum);
38
}
39
//==================================================
Gast #5131340
Lesenswert?

grundschüler schrieb:

> void lcd_write(uint8_t* str)
> {
>   uint8_t TempChar;
>     do
>     {
>         TempChar = *str++;
>         if(TempChar<' '||TempChar>130)return;
>
>         lcd_char(TempChar);
>
>            curposx =curposx+ f_width;
>        if(frame)curposx++;
>     }
>     while ( *str != 0 );
> }

Was passiert, wenn diese Funktion jemals einen Leerstring übergeben 
bekommt?
Gast #5131353
Lesenswert?

Direkt in dem Code sehe ich keinen Fehler (abgesehen von den 
überflüssigen Zeilen mit curposx). Hast du irgendwo einen Überlauf, der 
sich erst nach einem Tag beobachtbar macht? Oder läuft der Speicher 
voll? Sind die Texte auch immer mit '\0' abgeschlossen?
Gast #5131484
Lesenswert?

Thomas schrieb:
> Sind die Texte auch immer mit '\0' abgeschlossen?

Nein, das ist der einzige Unterschied zu Ziffernfolgen:

lcd_write("123test456");
./.
 uint8_t dum[4]={' ',' ',48,'\0'};
lcd_write(dum);

Aber durch '\' wird doch nur das Ende des strings angezeigt. Nach dem 
letzten Zeichen ist der string doch ohnehin zu Ende?




> Was passiert, wenn diese Funktion jemals einen Leerstring übergeben
> bekommt?

Weiß ich nicht, passiert eigentlich nicht.
Gast #5131505
Lesenswert?

grundschüler schrieb:

> lcd_write("123test456");

Bei einem solchen String-Literal ist die Null am Ende automatisch mit 
drin.

> Nach dem letzten Zeichen ist der string doch ohnehin zu Ende?

Nein. In C sind Strings zuende, wenn eine Null kommt. Wenn keine Null 
kommt, liest die Routine solange zufällig im Speicher weiter, bis eine 
kommt. Der Cursor wird dann natürlich sonstwohin gestellt.

> > Was passiert, wenn diese Funktion jemals einen Leerstring übergeben
> > bekommt?
> Weiß ich nicht

Dann geh der Frage mal nach. Ein bißchen Knobelei muß für Dich ja auch 
noch übrig bleiben. :-)
Gast #5131695
Lesenswert?

Nop schrieb:
> Bei einem solchen String-Literal ist die Null am Ende automatisch mit
> drin.

Das ist natürlich richtig, wusste ich früher auch mal.

Ich such ja erstmal eine Erklärung.

die lcd_write - Funktion müsste grundsätzlich in Ordnung sein.


"123test456" wird zur Laufzeit irgendwo in den RAM geschrieben. kann es 
sein dass sich der Ram dadurch verbraucht und irgendwann kein Platz für 
weiteren Text vorhanden ist?


Macht es Sinn, für solchen Text festen Speicher - u8 dum[] - anzulegen?
Gast #5133094
Lesenswert?

habe jetzt auf
1
u8 tst[]="wzb vl  rl  t0  t1  thm  elt  az ";
2
    lcd_goto(25,1);lcd_write(tst);
geändert.

Der im Ram abgelegte String wird korrekt geschrieben.

Es ist also kein Problem mit der Funktion lcd_write, sondern ein 
Speicherüberlaufproblem. Durch das ständige Schreiben von Text aus dem 
Programmcode entsteht ein Speicherüberlauf. Ist das normal oder ein 
Fehler in meinem Programm???????
Gast #5133865
Lesenswert?

Frank M. schrieb:
> immer eine while- und
> keine do-while-Schleife nehmen.

Danke für den Hinweis. Habe jetzt stark vereinfacht:
1
void lcd_write(uint8_t* str)
2
{
3
  while(*str>31)
4
    {
5
        lcd_char(*str++);
6
        curposx =curposx+ f_width;
7
    if(frame)curposx++;
8
    }
9
}

Bin gespannt, ob der Fehler jetzt weg ist.
Gast #5136301
Lesenswert?

Bin - trotz geänderter lcd_write() - immer noch auf der Fehlersuche:
1
void test(u8 *str){
2
u8 tmp[]="xxx ";
3
u8 i;
4

5
for(i=0;i<3;i++){
6
  tmp[i]=*str++;
7
}
8

9
lcd_write(tmp);
10
}
11

12
.....
13

14
    lg(21,20);test("vl ");
15
    lcd_int4(owx_rx_buffer[17]);
16
    
17
    lg(22,20);lw("elt ");
18
    lcd_int4(kw_elt);
19
    
20
    lg(23,20);lw(thm);//u8 thm[]="thm ";
21
    lcd_int4(kw_therm);


nach ca. 2h wird nur noch die Variante thm angezeigt. Ich kann den code 
jetzt entsprechend ändern, würde aber gerne wissen, was falsch läuft.
Gast #5136660
Lesenswert?

Peter D. schrieb:
> wildgewordenen Pointer

das muss es sein. Kann eigentlich nur die onewire-empfangsroutine sein:
1
in der main:
2
...
3
while(1){
4
//================= owx polling ======================
5

6
if(owx_signal){//
7
led1_on;
8
//sub_owx_slave_polling();
9
u8 ret=  owx_empfangen(owx_rx_buffer);
10
...
11

12

13
volatile uint8_t owx_rx_buffer[30]={0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9};
14
//-------------------------------------------
15
uint8_t  owx_rx_byte(void){
16
uint8_t dat=0,i=0,abfr;
17
//u32 timeout;
18
  for(i=0;i<8;i++){
19
    dat=dat<<1;
20
    dly_med;
21
      if(owx_signal)
22
        abfr=0;
23
        else
24
        abfr=1;
25
    dly_short;
26
      if(owx_signal){
27
        if(abfr)dat++;
28
        while(owx_signal);
29
      }
30
      /*
31
      else{
32
      //???? error
33
      return;
34
      }
35
      */  
36
  }
37
return(dat);
38
}
39

40

41

42

43
//-------------------------------------------
44
uint8_t owx_empfangen(  
45
  uint8_t *buff    /* Pointer to data buffer */
46
){
47
uint8_t len,adr=0;
48
uint8_t  crc=0;
49
while(owx_signal);//Anfangssynchronisierung durch Master
50
dly_short;
51
 //adr
52
  *buff = owx_rx_byte();
53
  adr=*buff;
54
  crc=crc+1+*buff;
55
  *buff++;
56
  
57
//len
58
  *buff = owx_rx_byte();
59
  len=*buff-2;
60
  crc=crc+1+*buff;
61
  *buff++;
62

63
//4xheader + payload
64
do{
65
  *buff = owx_rx_byte();
66
  crc=crc+1+*buff;
67
  *buff++;
68
  } while (--len);
69

70
//crc
71
  *buff = owx_rx_byte();
72
  
73
 return crc;
Gast #5136716
Lesenswert?

Sicher, daß Du *buff++ meinst und nicht (*buff)++?

*buff++ liefert das zurück, worauf buff zeigt (was dann aber nicht 
verwendet wird) und erhöht dann den Zeiger buff.

Außerdem ist die Schleife bei 4xheader + payload schon wieder 
fußgesteuert und wird nicht klappen, wenn die empfangene Länge 0 ist.
Gast #5136722
Lesenswert?

Nop schrieb:
> Sicher, daß Du *buff++ meinst und nicht (*buff)++?

Das werd ich in Ruhe prüfen. Allerdings werden die Daten ja korrekt 
übertragen. Da ist es unwahrscheinlich, dass der Fehler in der 
Berechnungsroutine steckt. Eher pointer - aber ich finde keinen 
undefinierten.
#5136743
Lesenswert?

Nop schrieb:
> Sicher, daß Du *buff++ meinst und nicht (*buff)++?

Nein, er meint eigentlich nur buff++.

grundschüler schrieb:
> Kann eigentlich nur die onewire-empfangsroutine sein:

In die Funktion würde ich auf jeden Fall mal einen Überlaufschutz 
einbauen. In ihrer jetzigen Form ist die in den Puffer geschriebene 
Menge von äußeren Einflüssen abhängig. Was ist z.B. wenn das Paket 
defekt ist und die Längeninfo im Paket daher zu groß ist?
Gast #5136798
Lesenswert?

Peter D. schrieb:
> len = 2

Das könnte der Fehler sein. len ist das 2.Feld und gibt die Anzahl der 
zu übertragenden bytes an. len-2 weil 2 bytes schon gelesen sind. Wenn 
da durch Übertragungsfehler ein Überlauf und damit ein Wert größer als 
der buffer steht, kann es zu Fehlern kommen. Ich werde da einen Abbruch 
einbauen für den Fall, dass len größer als der buffer wird.

Wer denkt denn an so was...

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