Question

Je suis en train d'ajouter la détection d'erreur CRC16 à une application microcontrôleur Motorola HCS08. Mes checksums ne correspondent pas, cependant. Un calculatrice en ligne CRC fournit à la fois le résultat que je vois dans mon programme PC et le résultat que je vois sur le micro.

Il appelle le résultat de micro "XModem" et le résultat du PC "Kermit".

Quelle est la différence entre la façon dont ces deux protocoles anciens spécifient l'utilisation de CRC16?

Était-ce utile?

La solution

vous pouvez mettre en œuvre 16 bits IBM, CCITT, XModem, Kermit et CCITT 1D0F en utilisant la même base de code de base. voir http://www.acooke.org/cute/16bitCRCAl0.html qui utilise le code de http://www.barrgroup.com/Embedded- systèmes / Manuels pratiques / CRC-calcul-C-code

le tableau suivant montre comment ils diffèrent:

name    polynomial  initial val  reverse byte?  reverse result?  swap result?
CCITT         1021         ffff             no               no            no
XModem        1021         0000             no               no            no
Kermit        1021         0000            yes              yes           yes
CCITT 1D0F    1021         1d0f             no               no            no
IBM           8005         0000            yes              yes            no

où on entend par « octet » inverse que chaque octet est le bit inversée avant le traitement; on entend par « résultat inverse » que le résultat de 16 bits est peu inversée après le traitement; « Résultat de swap » signifie que les deux octets du résultat sont échangés après le traitement.

tout ce qui précède a été validé avec des vecteurs de test contre http: //www.lammertbies .nl / comm / info / crc-calculation.html (si cela est faux, nous sommes tous perdus ...).

, dans votre cas particulier, vous pouvez convertir le code pour XModem à Kermit par bit d'inversion de chaque octet, le bit d'inversion du résultat final, puis échanger les deux octets dans le résultat.

[je crois, mais je n'ai pas vérifié ou travaillé les détails, que l'inversion chaque octet équivaut à inverser le polynôme (ainsi que quelques détails supplémentaires). ce qui est la raison pour laquelle vous verrez des explications très différentes dans des endroits différents pour ce qui est fondamentalement le même algorithme.

En outre, l'approche ci-dessus n'est pas efficace, mais il est bon pour les tests. si vous voulez efficace la meilleure chose à faire est de traduire ci-dessus pour rechercher des tables.]

modifier ce que j'ai appelé CCITT ci-dessus est documenté dans le catalogue RevEng CCITT-FAUX. Pour plus d'informations, voir la mise à jour mon blog sur le lien ci-dessus.

Autres conseils

Mon souvenir (I utilisé pour faire des choses modem chemin de retour quand) est que Kermit traite les bits dans chaque octet des données à l'aide du bit le moins significatif en premier.

La plupart des implémentations de logiciels CRC (Xmodem, probablement) traversent les octets de données premier bit le plus significatif.

Lorsque l'on regarde à la source bibliothèque (le télécharger à partir de http: //www.lammertbies. nl / comm / logiciel / index.html ) utilisé pour la page de calcul du CRC lié à, vous verrez que XModem utilise CRC16-CCITT, le polynôme pour ce qui est:

x^16 + x^12 + x^5 + 1  /* the '^' character here represents exponentition, not xor */

Le polynôme est représenté par la bitmap (note que le bit 16 est implicite)

0x1021 == 0001 0000 0010 0001  binary

La mise en œuvre Kermit utilisations:

0x8408 == 1000 0100 0000 1000  binary

qui est la même que bitmap de XModem, seulement inversé.

Le fichier texte qui accompagne la bibliothèque mentionne également la différence suivante pour Kermit:

  

Uniquement pour CRC-Kermit et CRC-SICK. Après tout traitement d'entrée, le complément de celui de la CRC est calculé et les deux octets de la CRC sont permutées

Il devrait probablement être facile de modifier votre routine CRC pour correspondre le résultat PC. Notez que la source dans la bibliothèque CRC semble avoir une licence assez libérale - il pourrait être judicieux d'utiliser plus ou moins (au moins les parties qui demandent l'application)

.

X-Modem 1K CRC16.

Processus de CRC-16 par octet à l'aide des données d'entrée {0x01, 0x02} et polynôme 0x1021

  1. Init crc = 0
  2. Poignée premier octet d'entrée 0x01: 2,1 'Xor-in' premier octet d'entrée 0x01 dans MSB de crc (!): 0000 0000 0000 0000 (crc) 0000 0001 0000 0000 (octet d'entrée 0x01 décalée à gauche par 8)


    0000 0001 0000 0000 = 0x0100 Le MSB de ce résultat est notre divident actuelle: MSB (0x100) = 0x01. 2.2 Alors 0x01 est le divident. Obtenez le reste pour divident de notre table: crctable16 [0x01] = 0x1021. (Eh bien cette valeur est famila du calcul manuel ci-dessus.) Rappelez-vous la valeur actuelle est crc 0x0000. Maj le MSB de crc actuelle et XOR avec le reste en cours pour obtenir le nouveau CRC: 0001 0000 0010 0001 (0x1021) 0000 0000 0000 0000 (CRC 0x0000 décalée à gauche par 8 = 0x0000)


    0001 0000 0010 0001 = 0x1021 = crc intermédiaire.

  3. Poignée octet d'entrée suivante 0x02: À l'heure actuelle, nous avons crc intermédiaire = 0x1021 = 0001 0000 0010 0001. 3,1 'Xor-in' octet d'entrée 0x02 dans MSB de crc (!): 0001 0000 0010 0001 (0x1021 crc) 0000 0010 0000 0000 (0x02 octet d'entrée décalée à gauche par 8)


    0001 0010 0010 0001 = 0x1221 Le MSB de ce résultat est notre divident actuelle: MSB (0x1221) = 0x12. 3.2 Alors 0x12 est le divident. Obtenez le reste pour divident de notre table: crctable16 [0x12] = 0x3273. Rappelez-vous la valeur actuelle est crc 0x1021. Maj le MSB de crc actuelle et XOR avec le reste en cours pour obtenir le nouveau CRC: 0011 0010 0111 0011 (0x3273) 0010 0001 0000 0000 (CRC 0x1021 décalée à gauche par 8 = 0x2100)


    0001 0011 0111 0011 = 0x1373 = crc final.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top