Hallo,
Irgendwie stehe ich grad auf dem Schlauch.
Ich möchte mir im Prinzip über ein struct ein Protokollzusammenbauen
welches dann über uart gesendet werden soll.
Der struct sieht wie folgt aus:
1
structdata
2
{
3
unsignedshortheader;
4
unsignedshortdata_a;
5
unsignedshortdata_b;
6
unsignedshortdata_c;
7
unsignedshortdata_d;
8
unsignedshortdata_e;
9
unsignedshortdata_f;
10
unsignedshortdata_g;
11
unsignedshortdata_h;
12
unsignedshorteof;
13
};
Nun habe ich einfach das Problem das ich nicht weiß wie ich dieses
struct am besten zu einem Char array caste um es über USART zu senden.
Ich denke ich muss es irgendwie über einen Zeiger auf die Adresse machen
oder?
Gruß Tobias
Hab mal eben versucht das ganze in c++. Hier auf den Rechner
nachzuvollziehen
Allerdings meckert er bei dem cast :(
Mein Code sieht momentant wie folgt aus:
Klaus Wachtler schrieb:> TM schrieb:>> p_Char = (char*)Daten;>> es müsste ja auch heißen:> p_Char = (char*)&Daten;
Danke das wars.
Er gibt leider nur noch nicht den gesamten Frame aus sondern nur ein
Teil.
TM schrieb:> printf("%s",p_Char);
Nur weil du etwas zu einem char* umcastest, ist das noch lange kein
String. Ein Trabbi wird schliesslich auch nicht zu einem Ferrari, wenn
ich ein springendes Pferd draufklebe.
Was willst du wirklich machen?
TM schrieb:> Er gibt leider nur noch nicht den gesamten Frame aus sondern nur ein>> Teil.
Naja, wie Karl-Heinz schrieb: ein Char-Array ist noch kein String.
Du hast in Deiner Struktur Chars und Short-Integer. Bei den Integern
wird irgendwo auch ein Nullbyte dazwischen sein und dann hört die
String-Ausgabe auf.
Was ist daran überraschend?
Grüße,
Stefan
P.S.: auch von mir: was willst Du machen?
TM schrieb:> Eigentlich wollte ich mir den gesamten Frame nochmal ausgeben.
Dann tu das. Aber du musst berücksichtigen, dass du keinen String hast.
Also kannst du auch keine Stringfunktionen benutzen.
Und ich werden den Verdacht nicht los, das du in Wirklichkeit gar keinen
Cast brauchst, sondern eine ASCII Übertragung machen willst.
Daher nochmal die Frage: Was soll über die Leitung gehen?
Ganz konkret in deinem Beispiel. Wie sollen die Bytes, die über die
Leitung gehen aussehen?
Ok super das funktinoiert soweit, das mit der hexadezimalen ausgabe
kannte ich noch gar nicht.
Allerdings packt er mir nach jedem char das ich ins frame schreibe zwei
hohe Werte mit dazu(also irgendwie einen nicht initialisierten
speicherbereich oder so).
Die Ausgabe sieht wie folgt aus:
68 <-- h für header
ffffffcc
37 <-- data
00
37
00
37
00
37
00
37
00
37
00
37
00
37
00
3b <-- Simikolon
ffffffcc
Dazu nutze ich nun folgenden code:
TM schrieb:> Ok super das funktinoiert soweit, das mit der hexadezimalen ausgabe> kannte ich noch gar nicht.> Allerdings packt er mir nach jedem char das ich ins frame schreibe
Dein Frame besteht aus unsigned short!
Ein unsigned short ist kein char!
> hohe Werte mit dazu(also irgendwie einen nicht initialisierten> speicherbereich oder so).
keinesfalls. Das sind die unsigned short. Die bestehen nun mal aus 2
Bytes.
TM schrieb:> printf("%02x",p_Char[x]);> [/c]
Ich würde das 02 weglassen, sonst schreibt er dir immer 2 Nullen
vorneweg..(bzw in deiner Darstellung hinten dran)
Daniel V. schrieb:> TM schrieb:>>> printf("%02x",p_Char[x]);>> [/c]>> Ich würde das 02 weglassen, sonst schreibt er dir immer 2 Nullen> vorneweg..(bzw in deiner Darstellung hinten dran)
Keinesfalls.
Lies in deinem C Buch über Formatiermöglichkeiten im printf Formatstring
nach. Die für ihn überzähligen 00 haben nichts damit zu tun.
Karl heinz Buchegger schrieb:> TM schrieb:>> Ok super das funktinoiert soweit, das mit der hexadezimalen ausgabe>> kannte ich noch gar nicht.>> Allerdings packt er mir nach jedem char das ich ins frame schreibe>> Dein Frame besteht aus unsigned short!> Ein unsigned shotr ist kein char!
Ist nen bisschen blöd das ich das erste Mal mit structs arbeite ist
alles im struct nach dem größten datentyp geregelt oder wie ?
Mein header und eof sollten doch eigentlich char sein.
TM schrieb:> Ist nen bisschen blöd das ich das erste Mal mit structs arbeite ist> alles im struct nach dem größten datentyp geregelt oder wie ?
Mal wieder: C-Buch lesen und verstehen!
TM schrieb:> Karl heinz Buchegger schrieb:>> TM schrieb:>>> Ok super das funktinoiert soweit, das mit der hexadezimalen ausgabe>>> kannte ich noch gar nicht.>>> Allerdings packt er mir nach jedem char das ich ins frame schreibe>>>> Dein Frame besteht aus unsigned short!>> Ein unsigned shotr ist kein char!>> Ist nen bisschen blöd das ich das erste Mal mit structs arbeite
Das hat mit struct nicht das geringste zu tun.
Unterschiedliche Datentypen haben unterschiedliche
Speicheranforderungen.
Und ein unsigned short braucht nun mal 2 Bytes.
> alles im struct nach dem größten datentyp geregelt oder wie ?
Nein.
Warum sollte es?
Die Byteabfolge ist doch genau so, wie du sie in der Struktur geregelt
hast
1
structdata
2
{
3
unsignedcharheader;// 1 Byte
4
unsignedshortdata_a;// 2 Bytes
5
unsignedshortdata_b;// 2 Bytes
6
unsignedshortdata_c;// 2 Bytes
7
unsignedshortdata_d;// 2 Bytes
8
unsignedshortdata_e;// 2 Bytes
9
unsignedshortdata_f;// 2 Bytes
10
unsignedshortdata_g;// 2 Bytes
11
unsignedshortdata_h;// 2 Bytes
12
unsignedchareof;// 1 Byte
13
};
14
// in Summe: 18 Bytes
und genau das siehst du auch im Kontrollausdruck
> Mein header und eof sollten doch eigentlich char sein.
Sind sie doch auch.
68 <-- h für header
37 -+ <-- data_a
00 -+
37 ---+ <-- data_b
00 ---+
37 -+ <-- data_c
00 -+
37
00
37
00
37
00
37
00
37 -+ <-- data_h
00 -+
3b <-- Simikolon
wiederrum in Summe 18 Bytes. Genau soviele, wie auch in der struct sind.
Daniel V. schrieb:> probiers mal mit:> printf("%c",p_Char[x]);
Daniel halt dich bitte raus. Du bist auf dem Holzweg. Sein gedankliches
Problem liegt ganz woanders.
Karl heinz Buchegger schrieb:> Daniel V. schrieb:>> probiers mal mit:>> printf("%c",p_Char[x]);>>> Daniel halt dich bitte raus. Du bist auf dem Holzweg. Sein gedankliches> Problem liegt ganz woanders.
OK,bin ja auch schon im Feierabend ;-)
Entschuldige bitte, wenn das jetzt harsch geklungen hat. Das war nicht
die Absicht.
Aber im Moment verwirren wir ihn sonst. Das ist jetzt für ihn wichtig.
Er lernt gerade den internen Aufbau von Datentypen. Auch wenn er es noch
nicht weiß :-)
Die nächste lustige Hürde wird dann kommen, wenn ich ihn fragen werde,
wie er auf der Zielmaschine sicherstellen will, dass er seinen Header
aus einem Datenstrom zweifelsfrei herausfischen kann. Aber alles zu
seiner Zeit. Jetzt muss sich erst mal die Erkentnis durchsetzen, dass
die Zahl 300 nicht mehr in ein Byte passt, wohl aber in einen unsigned
short; warum das so ist; und warum daher die Ausgabe nicht so aussieht
wie er das eigentlich erwartet hätte.
Daniel V. schrieb:> Nuja, zumindest bei "%02i" hätte ich diese Wirkung. Bei Hexzahlen hab> ich das noch nicht angewandt, sorry, dann liege ich falsch.
Auch dort nicht.
der 2-er sagt, dass die Ausgabe in einem Feld mit der Feldbreite 2 zu
erfolgen hat und der 0-er sagt, dass anstelle von Leerzeichen führende
0-en zum auffüllen benutzt werden sollen.
%02i angewendet auf 5 ergibt eine Ausgabe von 05. Denn 05 ist 2
Zeichen breit und anstelle eines Leerzeichens wurde eine führende 0
eingefügt.
Brauchen kann man das zb bei Festkommaarithmetik
die Zahl 203 repräsentiere den Wert 2.03
Die Ausgabe sei dann
int j = 203;
printf( "%i.%02i", j / 100, j % 100 );
im 2.ten Teil, beim Modulo, ist es ganz wichtig, dass man führende 0en
hat.
printf( "%i.%i", j / 100, j % 100 );
würde sonst 2.3 ausgeben und das ist offensichtlich falsch.
Oder denk an Uhrzeiten. Bei den Stunden kann man noch darüber
diskutieren, aber bei den Minuten hat man eigentlich meistens immer eine
2 stellige Ausgabe
00:00
00:01
00:50
14:30
printf( "%02i:%02i", hours, minutes );
Hmm. Es ist jetzt schon über eine halbe Stunde her. Ich glaub jetzt hat
ers verstanden.
Leider nicht da ich anstelle von 18 Bytes 20 bekomme, da er nach jeden
char noch 1 Byte hinzufügt.
Wenns jetzt so ein offensichtlicher Fehler ist ich sehe ihn leider
momentan nicht.
Naja ich denk nochmal ganz in Ruhe drüber nach.
TM schrieb:> Leider nicht da ich anstelle von 18 Bytes 20 bekomme, da er nach jeden> char noch 1 Byte hinzufügt.
Auf welchem Rechner?
Der Compiler darf Padding Bytes einfügen, um einzelne Mitglieder der
Struktur aufgrund zb technologischer Beschränkungen auf bestimmte
Adressen zu hieven (zb damit alles auf einer geraden Adresse anfängt)
Da du im GCC Forum gepostet hast, bin ich von einem AVR ausgegangen. Auf
dem gibt es kein Padding.
(Ich muss jetzt leider weg. Bin eh schon spät drann)
TM schrieb:> Ist ein normaler Windows Rechner hab das programm eben in c++
Dann poste das bitte nächstes mal ins PC-Programmierung Forum. Dann gibt
es keine Missverständnisse.
Du musst deine Compilerdoku durchforsten, wie du für diese Struktur das
Padding abschalten kannst. Meistens ist das irgend ein Attribut oder ein
#pragma (zb #pragma pack bei den Microsoft Compilern)
>Ist ein normaler Windows Rechner
Naja. nehmen wir dann also mal an das es sich um eine 80X86-Architektur
handelt (obwohl Windows alleine das nicht zwingend erfordert).
Jedenfalls ist es nach dem C-Standard zulässig, (Du solltest doch mal
ein C-Buch lesen) das der Compiler Bytes in die Struktur reinflickt um
die Elemente der Struktur effizient zugreifbar zu machen.
Wenn Du das verhindern willst musst Du, #pragma pack verwenden.
Hey,
Ja ist eine x86 strucktur.
Ok wo finde ich raus auf welcher processorstrucktur welcher compiler das
macht ?
Welches C oder C++ Buch wäre den da zu empfehlen wo auch solche Sachen
mit drinstehen?
>Ok wo finde ich raus auf welcher processorstrucktur welcher compiler das>macht ?
Eine Übersicht dazu wird es sehr wahrscheinlich nicht geben.
Du hast glaube ich auch noch nicht verstanden, das die C-Regel so
lautet: "Der Compiler kann beliebige Anzahlen von Bytes in die Struktur
patchen."
Es gibt hingegen keine C-Regel die lautet, das man das abstellen kann.
So! Dann gibt es Compiler, die es erlauben mittels #pragma pack oder
Optionen oder ähnlichem, dieses Verhalten zu unterbinden. D.h. Du musst
in der Compilerdokumentation nachschauen ob des so eine Möglichkeit
gibt. (Das hat ja auch Karl heinz schon geschrieben).
Karl heinz Buchegger schrieb:> Daniel V. schrieb:>> Nuja, zumindest bei "%02i" hätte ich diese Wirkung. Bei Hexzahlen hab>> ich das noch nicht angewandt, sorry, dann liege ich falsch.>> Auch dort nicht.>> der 2-er sagt, dass die Ausgabe in einem Feld mit der Feldbreite 2 zu> erfolgen hat und der 0-er sagt, dass anstelle von Leerzeichen führende> 0-en zum auffüllen benutzt werden sollen.>> %02i angewendet auf 5 ergibt eine Ausgabe von 05. Denn 05 ist 2> Zeichen breit und anstelle eines Leerzeichens wurde eine führende 0> eingefügt.
Ja, das hab ich ja auch gemeint, weil er in sein short_int 55
reingeschrieben hat und immer
37
00
37
00
bekommen hat, also "00" für die 0.
Aber offensichtlich gings um das "ffffffcc". Das hab ich völlig
überlesen.
Allerdings hab ich gelernt, dass struct nicht gleich struct ist. Das war
mir nicht so bewusst.
Hab nämlich schon oft Struct-Daten von AVR an den PC geschickt, also mit
Zeiger auf Struct, (über RS232) und das hat immer funktioniert...
Daniel
Daniel V. schrieb:> Aber offensichtlich gings um das "ffffffcc". Das hab ich völlig> überlesen.
Ich auch.
Ich habs für das Echo einer voreiligen Eingabe gehalten.
Nimmt man alles zusammen, dann ergibt es Sinn. Sofern man weiß, dass das
Programm auf einem PC gelaufen ist. Ohne dieses Wissen allerdings ergibt
der Dump keinen Sinn.