Hallo,
ich benutze den gcc auf AVR, und meine C-Kenntnisse sind -ähm-
ausbaufähig. Ich habe hier ein struct mit unterschiedlichen Wortbreiten,
also etwa so:
1
typedefstruct{
2
uint8_twert1;
3
uint8_twert2;
4
uint32_twert3;
5
uint16_twert4;
6
}my_struct;
7
my_structdaten;
Ich möchte nun die einzelnen Werte in eine Schleife bekommen, um eine
Prüfsumme zu berechnen. Zwei Verständnisschwierigkeiten türmen sich vor
mir. Wie bekomme ich Zugriff auf die einzelnen Werte, also etwa in der
Art:
1
for(i=0;i<4;i++)
2
{
3
machmirdiePruefsumme(daten.wert[i]);
4
}
Zum anderen, ich müsste wohl vermutlich zur Berechnung die struct-Werte
auf 32bit casten. Wie müsste das aussehen?
Ihr seht schon, ich bin da etwas planlos. Hoffentlich habe ich mich
zumindest verständlich ausgedrückt, und es gibt eine Lösung für die
Sache.
Danke.
Bernd F. schrieb:
> ausbaufähig. Ich habe hier ein struct mit unterschiedlichen Wortbreiten,> also etwa so:>>
1
>typedefstruct{
2
>uint8_twert1;
3
>uint8_twert2;
4
>uint32_twert3;
5
>uint16_twert4;
6
>}my_struct;
7
>my_structdaten;
8
>
>> Ich möchte nun die einzelnen Werte in eine Schleife bekommen, um eine> Prüfsumme zu berechnen.
Soll die Prüfsumme die Summe der Werte sein oder soll sie die Summe der
Bytes sein.
> Zwei Verständnisschwierigkeiten türmen sich vor> mir. Wie bekomme ich Zugriff auf die einzelnen Werte, also etwa in der> Art:>
1
>for(i=0;i<4;i++)
2
>{
3
>machmirdiePruefsumme(daten.wert[i]);
4
>}
5
>
so gar nicht. Zumindest macht man das nicht so. Hängt aber auch darvon
ab, was du unter Prüfsumme verstehst.
> Zum anderen, ich müsste wohl vermutlich zur Berechnung die struct-Werte> auf 32bit casten.
Komtm drauf an, was du unter Prüfsumme verstehst.
> Wie müsste das aussehen?> Ihr seht schon, ich bin da etwas planlos. Hoffentlich habe ich mich> zumindest verständlich ausgedrückt, und es gibt eine Lösung für die> Sache.
Kommt drauf an, was eigentlich genau das Problem ist. Fangen wir doch
einfach mal damit an, was denn mit der Prüfsumme geschehen soll.
Wenn es sich um eine byteweise Prüfsumme handelt, die du zb irgendwohin
übertragen musst, gibt es eine ganz einfache Lösung, indem man den
Compiler zwingt die struct komplett zu ignorieren und den
Speicherbereich einfach nur als Abfolge von Bytes anzusehen.
Hm, wenn du die Adresse der Struktur auf uint8_t* casten würdest, sehe
ich das Problem, dass du die Prüfsumme auch über evtl. eingefügte
Füll-Bytes berechnest. Du könntest das Alignment mit
__attribute__((packed)) verhindern, allerdings dann alles GCC
spezifisch. Ansonsten wirst du dir wohl die einzelnen Bytes mit
Bitoperationen rausschneiden müssen, falls du für die
Prüfsummenberechnen Bytes brauchst.
Man sollte die Struktur noch mit #pragma pack 1 packen und für die
Schleifengrenzen unbedingt die sizeof()-Funktion verwenden. Prinzipiell
sollte die Prüfsummenfunktion auf Basis von Bytes berechnen, da man
ansonsten das Mischen mit kleineren Datentypen nicht korrekt ist.
Karl heinz Buchegger schrieb:
> Kommt drauf an, was eigentlich genau das Problem ist. Fangen wir doch> einfach mal damit an, was denn mit der Prüfsumme geschehen soll.
Das struct wird am Stück ins Eeprom geschrieben und von dort gelesen.
Die "Prüfsumme" soll mir eventuelle Schreibfehler aufzeigen.
Wie die Prüfsumme genau aussieht, soweit war ich noch garnicht, ob das
jetzt eine einfache Summe oder ein CRC wird. Ich lass' mich auch dazu
gerne beraten.
Danke,
Bernd
Du kannst ne Union machen aus der Struct und einem Bytearray und dann
die CRC über das Bytearray bis sizeof(struct).
Um Paddingbytes zu vermeiden, zuerst die 32Bit, dann 16bit und dann 8Bit
Variablen in die Struct packen.
Peter
> Du kannst ne Union machen aus der Struct und einem Bytearray
Warum schlägt da eigentlich jeder gleich mit Unions um sich? Ein
einfacher Zeigercast tut's auch.
> Um Paddingbytes zu vermeiden, zuerst die 32Bit, dann 16bit und dann> 8Bit Variablen in die Struct packen.
Das spielt beim AVR keine Rolle, weil der eh keinerlei
Alignment-Anforderungen hat.
Bernd hat oben in seinem Beispiel angegeben in welcher Art er die
struct-Komponenten in der Schleife der Funktion übergeben möchte. Wie
und wohin die Prüfsumme gerechnet wird??? - sorry steht da nicht. Also
finde ich den Aufruf für jede Komponente immer gut.
Wenn ich die komplette Prüfsumme über alle Komponenten rechnen will
brauch ich auch keine Schleife. Dann würde ich nen Zeiger auf die struct
in der Funktion übergeben und die Prüfsumme zurückgeben.
tom
> Bernd hat oben in seinem Beispiel angegeben in welcher Art er die> struct-Komponenten in der Schleife der Funktion übergeben möchte. Wie> und wohin die Prüfsumme gerechnet wird??? - sorry steht da nicht.
"Das struct wird am Stück ins Eeprom geschrieben und von dort gelesen.
Die "Prüfsumme" soll mir eventuelle Schreibfehler aufzeigen."
> Wenn ich die komplette Prüfsumme über alle Komponenten rechnen will> brauch ich auch keine Schleife. Dann würde ich nen Zeiger auf die> struct in der Funktion übergeben und die Prüfsumme zurückgeben.
Dann steht die Schleife halt in dieser Funktion.
Rolf Magnus schrieb:
> Wenn ich die komplette Prüfsumme über alle Komponenten rechnen will> brauch ich auch keine Schleife. Dann würde ich nen Zeiger auf die struct> in der Funktion übergeben und die Prüfsumme zurückgeben.
Mir ist nicht klar wie das auszusehen hätte. Könntest Du das genauer
beschreiben?
Michael H. schrieb:
> Rolf Magnus schrieb:>> Wenn ich die komplette Prüfsumme über alle Komponenten rechnen will>> brauch ich auch keine Schleife. Dann würde ich nen Zeiger auf die struct>> in der Funktion übergeben und die Prüfsumme zurückgeben.>> Mir ist nicht klar wie das auszusehen hätte. Könntest Du das genauer> beschreiben?
Die Schleife ist dann in der Funktion drinnen :-)
1
uint8_tCheckSumm(uint8_t*startByte,size_tsize)
2
{
3
uint8_tcheck=0;
4
size_ti;
5
6
for(i=0;i<size;++i)
7
check+=*startByte++;
8
9
returnstartByte;
10
}
und aufgerufen wird es mit Umcasten der Adresse auf den Beginn der
struct-Variablen
Udo R. S. schrieb:
> @Peter: Nicht wenn die Funktion "machmirdiePruefsumme" den> Prüfsummenwert auf eine globale Variable addiert.
Wie unfein.
Dann fehlt aber noch das initialisieren dieser Variablen.
Ich mag mehrfache Aufrufe überhaupt nicht. Ich schreibe schon ne
Schleife, wenn etwas nur zweimal ausgeführt wird.
Damit bin ich deutlich flexibler.
Laß mal in die Struktur noch weitere Elemente einfügen, dann mußt Du an
der Schleife nix ändern, die läuft immer bis sizeof(struct).
Peter
Ich würde zu
uint8_t CheckSumm( const void * start, size_t size )
{
uint8_t * startByte = (uint8_t*) start;
tendieren und in der Funktion caste, so sehen die Aufrufe sauberer aus
Eine eigene Frage?
Dieser Thread ist über 16 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.