Berechnen einer LIN-Bus Checksumme mit Carry Überlauf



  • Hallo Leute,

    ich bin grade dabei meine Diplomarbeit zu schreiben und hab nun vor ein LIN Bus in betrieb zu nehmen.

    Als einfachen Anfang wollte ich mich mit dem Berechnen der Checksumme auseinander setzten und bin recht frühzeitig im Sand stecken geblieben. Nun hoffe ich auf ein paar kleine Tips von euch, damit ich weiter machen kann.

    Im Prinzip geht es darum 2,4 oder 8 Hexwerte zu addieren was so ja nicht wirklich schwer klingt. Dumm nur das ich Mr. "Carry" berücksichtigen muss.

    Bsp:
    0x4A + 0x55 = 0x9F (kein Überlauf) weiter gehts ...
    0x9F + 0x93 = 0x132 (add carry) = 0x33
    0x33 + ...

    Jetzt habe ich hier im Forum gelesen das C denkbar ungeeigenet dafür ist, was mich ziemlich traurig stimmt. aber kann man das nicht mit einer if - schleife irgendwie abfragen?

    if (summe > 0xFF) oder so. Wenn ja, wie kann ich ihm sagen das er die erste Stelle abschneiden soll. Dann müsste man ja nur noch 1 zur Summe addieren und könnte so weiter rechnen.

    Und eine 2te Frage habe ich auch noch:
    Gibt es eine Möglichkeit eine Hexzahl zu invertieren ohne sie von 0xFF anzuziehen? Es würde zwar das richtige Ergebniss raus kommen, würde den Sinn einer Checksumme aber im Keim ersticken.

    Danke schonmal



  • Du kannst die Berechnung mit einem größeren Datentyp als 'char' durchführen und das Endergebnis anschließend wieder in seine Bytes zerlegen:

    unsigned char data[]={...}
    
    unsigned short sum=0;
    for(i=0;i<datalen;++i)
      sum+=data[i];
    unsigned char res = sum&0xFF,carry=sum>>8;
    return res+carry;
    

    PS: Du kannst die Hex-Zahl auch mit 0xFF ver-XOR-en, um sie zu invertieren 😉 Das ist im Gegensatz zu "von 0xFF anzuziehen" sogar protabel.



  • CStoll schrieb:

    return res+carry;
    

    und wenn dabei ein überlauf stattfindet? 😉



  • Dann kannst du entweder diesen Überlauf ignorieren oder die beiden Bytes rekursiv mit dem selben Checksummen-Verfahren addieren.



  • CStoll schrieb:

    Dann kannst du entweder diesen Überlauf ignorieren oder die beiden Bytes rekursiv mit dem selben Checksummen-Verfahren addieren.

    aussuchen kann man sich dabei nix.
    wie prüfsummen berechnet werden steht in der LIN spec.
    🙂



  • vista schrieb:

    wie prüfsummen berechnet werden steht in der LIN spec.
    🙂

    Die habe ich leider nicht hier vorliegen 😉

    OK, dann anders: In dem Fall mußt du in der LIN spec. nachsehen, welches der oben genannten Verfahren richtig ist (ich weiß gar nicht, ob es überhaupt dazu kommen kann, daß bei dieser Summe wieder ein Übertrag auftritt).



  • Das geht ja super schnell bei euch hier 🙂

    Danke für die Antworten und die brauchbaren Tips.
    @CStoll:
    kannst du mir vielleicht in ein paar Worten die folgende Codezeile erläutern?

    unsigned char res = sum&0xFF,carry=sum>>8

    Was C angeht bin ich, naja vorsichtig ausgedrückt, Anfänger, und jeden Tag fleissig am lernen.

    Ich wollte jetzt versuchen die Abfrage für den carry in eine if-Schleife zu packen, da ja praktisch bei jeder Addition ein Überlauf stattfinden kann. Wenn ich einen Überlauf habe kann ich "sum=res+1;" zuweisen und haben meine aktuelle summe. sobald ich in der additions-for-schleife aber 2 überlaufe habe, ist da ende, oder? zuminest bei mir 😉

    die o.g. zeile in einer if schleife, wurde das sicher beheben, sodass er nach jeder Addition auf Überlauf prüft, oder?

    Ich steh in eurer Schuld



  • McFanatic schrieb:

    unsigned char res = sum&0xFF,carry=sum>>8

    In Kurzfassung: das zerlegt den Wert sum in seine Bytes. Etwas ausführlicher: 'sum&0xFF' nutzt bitweises UND, um alle Bits außer den untersten 8 (0xFF = 111111112), 'sum>>8' schiebt das Bitmuster um 8 Bit nach unten (und damit die untersten 8 Bit aus dem Speicher).

    Und ein short ist groß genug, um dort etliche char-Werte ohne Überlauf reinzuaddieren, das heißt im Inneren der Schleife mußt du dich nicht um die Überläufe kümmern.

    PS: Es gibt keine "if-Schleife" 😉



  • Hossa,

    ich hab auch grad meinen Fehler gefunden. Warum 1 zur Summe addieren, wenn ich carry addieren kann 😉

    Ich danke euch allen, ich bin nun ein ganzen Stück weiter.

    Ich denke ich werd euch noch weiter mit fragen belöschern wenn noch welche komme, und irgenwdwie hab ich den Eindruck es werden noch etliche kommen 😉



  • Es gibt in MS-VC die Funktion _lrotl bzw _lrotr (kein ANSI) die eventuell auch mithelfen kann so einen Überlaufin der Berrechnung zu berücksichtigen.


Anmelden zum Antworten