Forum: PC-Programmierung Fehler bei der auswertung eines Char Arrays


von Sir.Tom (Gast)


Lesenswert?

Hallo,


in einem Char Arry habe ich Daten, die ein AVR per RS232 sendet.

Hier der Code des AVRs
1
void uart_putint (uint64_t data)  
2
{
3
  int j;
4
  for (j=0;j<(sizeof(data));j++)
5
  {
6
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
7
    {
8
    }
9
    UDR = data;                      /* sende Zeichen */
10
    data = data >> 8;
11
  }
12
}
13
14
uart_putint( 0x0123456789223344 );

Damit sollte der AVR dann 8 Byte in einem rutsch versenden.



Dann der Code des Linux-PC's:
1
res = read(fd232,BufferRX,32);
2
printf("\nRead:%i %s\n",res,BufferRX); // testausgabe
3
for (j=0;j<8;j++) 
4
{
5
  printf("data %i: %X\n",j,BufferRX[j]);  
6
}


Und nun der Fehler in der Ausgabe: Irgendwie scheint es hier
einen Überlauf oder so zugeben:

Read:8 D3"�gE#
data 0: 44
data 1: 33
data 2: 22
data 3: FFFFFF89
data 4: 67
data 5: 45
data 6: 23
data 7: 1


Warum ist beim 4. Datensatz ein FFFFFF vor den eigentlichen Daten?
Überlauf? Sonst ist im Prinzip alles richtig.

Vielen Dank schon einmal vorab!

Gruß,
Thomas

von Peter II (Gast)


Lesenswert?

der linux code muss schon mal falsch sein, dann wie kann ein einen byte 
"FFFFFF89" drin stehen.

Warum liest du 32byte ein, du hast doch nur 64bit als 8byte?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Das "byte" wird sign-extended und dann als unsigned 32-bit dargestellt

von Rolf M. (rmagnus)


Lesenswert?

Vermutlich ist BufferRX ein Array aus char, welcher unter Linux signed 
ist.  Und in dieser Zeile:

Sir.Tom schrieb:
> printf("data %i: %X\n",j,BufferRX[j]);

wird BufferRX[i] implizit zu int erweitert, was, wie Johann schon 
screibt, eine sign-extension bewirkt.

von Peter II (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Vermutlich ist BufferRX ein Array aus char, welcher unter Linux signed
> ist.  Und in dieser Zeile:

dann ist aber die Frage warum er 32byte liest

res = read(fd232,BufferRX,32);

von Rolf M. (rmagnus)


Lesenswert?

Die Frage verstehe ich nicht. Was hat die Größe damit zu tun, ob die 
Elemente signed oder unsigned sind?
Ich nehme an, es sind 32 Byte, weil das Protokoll das an der Stelle so 
vorsieht oder weil der Puffer halt so groß ist.

von Sir.Tom (Gast)


Lesenswert?

Hallo,

sorry ersteinmal .. Ihr habt aber schon richtig geraten ;)

also BufferRX ist ein char Array.

BufferRX[j] ist ja dann auch nur 1 Byte. Die Interpretation dann ist 
wohl
falsch. Aber wie macht man es dann richtig?
Wenn ich in der Ausgabe ein %u einsetze wird -119 angezeigt.
Komme da irgendwie nicht weiter!

Das ich bei Read immer 32 Byte einlese ist im Prinzio auch ein Fehler,
ich hatte das für Testzwecke so hoch gesetzt. Aber das hat ja
mit dem eigentlichen Problem das da FFFFFF angezeigt wird nichts zu tun.

Also, wie wäre denn jetzt die Richtige Lösung?

Ich habe jetzt nochmals was anderes getestet, aber auch so funktioniert 
nicht:
1
for (j=0;j<8;j++) 
2
{
3
  if (j == 0)  
4
    rxb = BufferRX[j];
5
  else
6
    rxb = rxb<<8 | BufferRX[j];
7
  printf("rxdata %i: %016x\n",j,rxb);
8
}

Mit dieser Routine sieht es so aus:

rxdata 0: 0000000000000044
rxdata 1: 0000000000004433
rxdata 2: 0000000000443322
rxdata 3: 00000000ffffff89
rxdata 4: 00000000ffff8967
rxdata 5: 00000000ff896745
rxdata 6: 0000000089674523
rxdata 7: 0000000067452301

Auch hier wieder dieses ominöse FFFFFF. Ich weiß einfach nicht wo
das herkommt. Auch merkwürdig das die ersten 4 Bytes in diesem Fall leer 
bleiben. rxb habe ich als unsigned long long initialisiert, sollte also 
groß genug sein.

Vielen Dank schon vorab!

Thomas

von Peter II (Gast)


Lesenswert?

dann verwende doch mal kein char array, sonder ein unsigned char array, 
dann sollte es passen.

von Walter S. (avatar)


Lesenswert?

Sir.Tom schrieb:
> rxb = rxb<<8 | BufferRX[j];

schreib mal
rxb = rxb<<8 | (unsigned char)BufferRX[j];

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Sir.Tom schrieb:
> Auch hier wieder dieses ominöse FFFFFF.

Das ist nicht ominös, sondern Folge der Vorzeichenerweiterung. 0x89 ist 
ein negativer Wert, jedenfalls wenn es in einem signed char gespeichert 
wird. Und wenn das einem signed int zugewiesen wird, erfolgt eben jene 
Vorzeichenerweiterung, damit das Resultat auch ja negativ bleibt.

Also, wie Dir schon mehrere Leute geschrieben haben:

Nutze unsigned char!

von Sir.Tom (Gast)


Lesenswert?

Hi,

also das FFFFFF ist weg wenn ich BufferRX als unsigned char
definiere. Bleibt jetzt nur noch die Frage warum ich wenn ich das in rxb 
shifte nur 4 byte in rxb habe ...

Danke und Gruß,
Thomas

von Sir.Tom (Gast)


Lesenswert?

wow, das ging aber schnell.

Mir war nicht klar das ein Zeichen auch unsigned sein kann ...

Vielen vielen Dank!

von Peter II (Gast)


Lesenswert?

Sir.Tom schrieb:
> Mir war nicht klar das ein Zeichen auch unsigned sein kann ...

es es nicht genau definert char sollte man also nur für text verwenden, 
wenn du zahlen verwenden willst, dann schreibe auch extra unsigned oder 
signed davor. Oder nimm gleich uint8_t.

von Sir.Tom (Gast)


Lesenswert?

So, jetzt werden mir auch die ganzen 8 Bytes angezeigt.
War nur der Platzhalter für das printf. habe jetzt %llx.

Das read braucht einen Array zum reinschreiben. Da ist uint8_t wohl auch
besser. Hatte an dies möglichkeit noch nicht gedacht.

Nunja, vielen Dank!
Thomas

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.