www.mikrocontroller.net

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


Autor: ZurZeitBlinderGast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

folgende Originalberechnung aus der AVR-libc funktioniert; d.h. ergibt 
0:
 // Dallas iButton test vector.
    uint8_t serno[] = { 0x02, 0x1c, 0xb8, 0x01, 0, 0, 0, 0xa2 };

    int
    checkcrc(void)
    {
        uint8_t crc = 0, i;
        for (i = 0; i < sizeof serno / sizeof serno[0]; i++)
            crc = _crc_ibutton_update(crc, serno[i]);
        return crc; // must be 0
    }

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 ...
uint8_t serno[] = { 0x02, 0x1c, 0xb8, 0x01, 0, 0, 0, 0xa2 };

int checkcrc (uint8_t source[])
    {
        uint8_t crc = 0, i;
        for (i = 0; i < sizeof source / sizeof source[0]; i++)
            crc = _crc_ibutton_update(crc, source[i]);
        return crc; // must be 0
    }

Aufruf dann
if (checkcrc (serno])
   ..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.

Autor: Jörg G. (joergderxte)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int checkcrc (uint8_t source[])
    {
        uint8_t crc = 0, i;
        for (i = 0; i < sizeof source / sizeof source[0]; i++)
//                      ^^^^^^^^^^^^^ == 2, source ist ein POINTER
            crc = _crc_ibutton_update(crc, source[i]);
        return crc; // must be 0
    }

hth, Jörg

Autor: ZurZeitBlinderGast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

uint8_t serno[] = { 0x02, 0x1c, 0xb8, 0x01, 0, 0, 0, 0xa2 };

int main (void)
{
   printf ("Size of serno[]:  %d\n", sizeof (serno));   // 8
   printf ("Size of uint8_t *: %d\n", sizeof (uint8_t *)); // 2 (bzw. 4 bei Linux)
   printf ("Contentss of *serno: %d\n", *serno);        // 2
   printf ("Contents of serno[0]: %d\n", serno[0]);     // 2
   printf ("Contents  of serno: %X\n", serno);          // Bei mir 8049624
   printf ("Size of serno[0] = %d\n", sizeof (serno[0])); // 1
   printf ("Size of serno[] = %d\n", sizeof (serno) / sizeof (serno[0])); // 8

   return 0;
}

Autor: Henry (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.