Forum: Mikrocontroller und Digitale Elektronik meine CRC-Funktion ähnlich <util/crc16.h> will nicht.


von ZurZeitBlinderGast (Gast)


Lesenswert?

Hallo,

folgende Originalberechnung aus der AVR-libc funktioniert; d.h. ergibt 
0:
1
 // Dallas iButton test vector.
2
    uint8_t serno[] = { 0x02, 0x1c, 0xb8, 0x01, 0, 0, 0, 0xa2 };
3
4
    int
5
    checkcrc(void)
6
    {
7
        uint8_t crc = 0, i;
8
        for (i = 0; i < sizeof serno / sizeof serno[0]; i++)
9
            crc = _crc_ibutton_update(crc, serno[i]);
10
        return crc; // must be 0
11
    }

Nun komme ich seit einer Stunde nicht dahinter, was ich verkehrt mache 
(Denkblockade, kann ja nur ein trivialer Fehler sein). Ich wollte die 
Funktion so abändern, daß ich das zu prüfende Array als 
Funktionsparameter übergebe, also flexibel bin, welches Array geprüft 
werden soll. Es kommt aber nicht 0 raus ...
1
uint8_t serno[] = { 0x02, 0x1c, 0xb8, 0x01, 0, 0, 0, 0xa2 };
2
3
int checkcrc (uint8_t source[])
4
    {
5
        uint8_t crc = 0, i;
6
        for (i = 0; i < sizeof source / sizeof source[0]; i++)
7
            crc = _crc_ibutton_update(crc, source[i]);
8
        return crc; // must be 0
9
    }

Aufruf dann
1
if (checkcrc (serno])
2
   ..Fehler...

Und der Fehlerfall wird abgearbeitet; also kommt nicht 0 raus (mit der 
anderen Funktion ja). Es kann nur ein Dummheitsfehler sein, aber den 
sehe ich heute wohl nicht mehr. Ich hatte Anfangs Sorgen bezüglich 
uint8_t crc und Rückgabewert int, aber im Original gehts ja auch.

von Jörg G. (joergderxte)


Lesenswert?

1
int checkcrc (uint8_t source[])
2
    {
3
        uint8_t crc = 0, i;
4
        for (i = 0; i < sizeof source / sizeof source[0]; i++)
5
//                      ^^^^^^^^^^^^^ == 2, source ist ein POINTER
6
            crc = _crc_ibutton_update(crc, source[i]);
7
        return crc; // must be 0
8
    }
hth, Jörg

von ZurZeitBlinderGast (Gast)


Lesenswert?

Hallo Jörg,

Danke für die Antwort. Auf jeden Fall scheint mein Problem nichts mit 
CRC o.ä. zu tun zu haben, sondern eher mit dem Verständnis Array, 
Pointer, deren Beziehungen, Adressarithmetik usw.. Ich dachte eigentlich 
daß ich "es" (zumindest grundsätzlich) so verstanden hatte, um nicht in 
solche Fallen zu tappen. Schade, aber ich will ja was lernen. Was ich 
nun doch nicht mehr ganz verstehe:
Der Name eines Arrays ist gleichzeitig ein Pointer auf den Anfang des 
Arrays; also auf den Anfang des ersten Elements (je nach dem, wieviel 
byte es auf der Maschine hat, kann das erste Element z.B. 2 Byte lang 
sein).
Also müßte "*serno" und "serno[0]" das Gleiche sein, nämlich der Inhalt 
des ersten Elements des Arrays. Das klappt auch mit dem Programm unten 
(3. und 4. Zeile). Wenn aber "serno" ein Pointer ist (wie Du ja 
geschrieben hast und ich auch dachte), müßte "sizeof (serno)" ja 
tatsächlich "2" ergeben (oder bei mir halt 4, je nach Maschine). In der 
1. Zeile wird aber "8" ausgegeben. In der 2. Zeile die korrekte Ausgabe 
der größe eines Pointers auf uint8_t.
Kurzum: Die Ausgabe müßte wie im ersten Post funktionieren, zumal an 
diesem Teil von mir auch nichts verändert wurde. Kann ich die Größe 
eines Arrays eigentlich zur Laufzeit ermitteln, also a la "Lese so viele 
Elemente ein, bis ENDE eingelesen wird. Dann ermittle die Größe mit 
sizeof"? Oder geht das so gar nicht und ich muß die bytes anders zählen 
(was ja auch nicht schwer ist, ich mich aber gerne konsistent auf eine 
Art und Weise festlegen würde)? Wie kann ich eigentlich die Größe des 
Arraynamens (besser: die Größe des Pointers) ermitteln? Mit "sizeof 
ARRAYNAME" geht es ja nicht. Hört sich alles ziemlich wirr an, ich weiß, 
ich habe anscheinend immer noch Probleme mit den Grundlagen.
P.S.: Den ehrenwerten Kernighan/Ritchie nenne ich seit kurzem schon mein 
Eigen. Echt schade, daß der kein Stichwortverzeichnis hat.
1
#include <stdio.h>
2
#include <stdint.h>
3
#include <stdlib.h>
4
5
uint8_t serno[] = { 0x02, 0x1c, 0xb8, 0x01, 0, 0, 0, 0xa2 };
6
7
int main (void)
8
{
9
   printf ("Size of serno[]:  %d\n", sizeof (serno));   // 8
10
   printf ("Size of uint8_t *: %d\n", sizeof (uint8_t *)); // 2 (bzw. 4 bei Linux)
11
   printf ("Contentss of *serno: %d\n", *serno);        // 2
12
   printf ("Contents of serno[0]: %d\n", serno[0]);     // 2
13
   printf ("Contents  of serno: %X\n", serno);          // Bei mir 8049624
14
   printf ("Size of serno[0] = %d\n", sizeof (serno[0])); // 1
15
   printf ("Size of serno[] = %d\n", sizeof (serno) / sizeof (serno[0])); // 8
16
17
   return 0;
18
}

von Henry (Gast)


Lesenswert?

int checkcrc (uint8_t source[])
int checkcrc (uint8_t *source)

Diese zwei Schreibweisen sind identisch. Bei der Zweiten sieht man 
eindeutig, dass es ein Pointer ist. Die Erste nimmt man zur besseren 
Verdeutlichen, dass es sich um einen Pointer zu einem Array handelt.

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.