Domanda

Sto cercando di aggiungere il rilevamento degli errori CRC16 a un'applicazione microcontrollore Motorola HCS08. I miei checksum non corrispondono, però. Una linea CRC calcolatrice fornisce sia il risultato che vedo nel mio programma e PC il risultato che vedo sul micro.

Si chiama Micro risultato "XModem" e il risultato del PC "Kermit".

Qual è la differenza tra il modo in cui questi due antichi protocolli specificano l'uso di CRC16?

È stato utile?

Soluzione

è possibile implementare a 16 bit IBM, CCITT, XModem, Kermit, e CCITT 1D0F utilizzando la stessa base di codice di base. vedi http://www.acooke.org/cute/16bitCRCAl0.html che utilizza il codice da http://www.barrgroup.com/Embedded- sistemi / How-To / CRC-Calcolo-C-Codice

La tabella seguente mostra come si differenziano:

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

dove significa 'inverso byte' che ogni byte bit invertito prima della trasformazione; 'Risultato inverso' significa che il risultato 16 bit è bit invertito dopo la trasformazione; 'Risultato di swap' significa che i due byte nel risultato vengono scambiati dopo l'elaborazione.

tutto quanto sopra è stato convalidato con vettori di test contro http: //www.lammertbies .nl / comm / informazioni / crc-calculation.html (se questo è sbagliato, siamo tutti perduti ...).

così, nel vostro caso particolare, è possibile convertire il codice per XModem a Kermit per bit-invertendo ogni byte, bit invertendo il risultato finale, e poi scambiare i due byte nel risultato.

[credo, ma non ho controllato o ha lavorato sui dettagli, che invertendo ogni byte è equivalente a invertire il polinomio (più alcuni dettagli in più). ed è per questo vedrete molto diverse spiegazioni in luoghi diversi per quello che è fondamentalmente lo stesso algoritmo.

Inoltre, l'approccio di cui sopra non è efficiente, ma è un bene per il test. se si vuole efficiente] la cosa migliore da fare è di tradurre quanto sopra ad occhiata-tabelle.

modifica che ho chiamato CCITT sopra è documentato nel catalogo RevEng come CCITT-FALSO. per maggiori informazioni, vedere l'aggiornamento al mio post sul blog al link qui sopra.

Altri suggerimenti

Il mio ricordo (ho usato per fare cose modem via del ritorno quando) è che Kermit elabora i bit in ogni byte di dati utilizzando il bit meno significativo per primo.

La maggior parte delle implementazioni software CRC (Xmodem, probabilmente) attraversano il byte di dati bit più significativo per primo.

Se si guarda alla sorgente della libreria (scaricarlo dal http: //www.lammertbies. nl / comm / software / index.html ) usata per la pagina di calcolo CRC si è collegato al, vedrai che XModem utilizza CRC16-CCITT, il polinomio per il quale è:

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

Il polinomio è rappresentato dalla bitmap (nota che il bit 16 è implicato)

0x1021 == 0001 0000 0010 0001  binary

usi di implementazione Il Kermit:

0x8408 == 1000 0100 0000 1000  binary

che è la stessa bitmap come XModem di, solo invertito.

Il file di testo che accompagna la libreria anche menziona la seguente differenza per Kermit:

Solo per CRC-Kermit e CRC-SICK:. Dopo tutta l'elaborazione di input, il complemento a uno della CRC viene calcolato e le due byte del CRC vengono scambiati

Quindi, probabilmente dovrebbe essere facile da modificare la vostra routine CRC per abbinare il risultato PC. Si noti che la sorgente nella libreria CRC sembra avere una licenza molto liberale - potrebbe avere un senso usarlo più o meno come è (almeno le parti che si applicano per la vostra applicazione)

.

X-Modem 1K CRC16.

Processo per Bytewise CRC-16 utilizzando i dati di input {0x01, 0x02} e polinomiale 0x1021

  1. Init CRC = 0
  2. Handle primo byte di ingresso 0x01: 2.1 'Xor-in' primo byte di ingresso 0x01 in MSB di CRC (!): 0000 0000 0000 0000 (CRC) 0000 0001 0000 0000 (byte di ingresso 0x01 sinistra spostata di 8)


    0000 0001 0000 0000 = 0x0100 Il MSB di questo risultato è la nostra di godimento corrente: MSB (0x100) = 0x01. 2.2 Così 0x01 è il di godimento. Ottenere il resto per di godimento dalla nostra tabella: crctable16 [0x01] = 0x1021. (Ebbene questo valore è famila dal calcolo manuale sopra.) Ricordate il valore CRC corrente è 0x0000. Spostare il MSB di crc attuale e XOR con il resto corrente per ottenere il nuovo CRC: 0001 0000 0010 0001 (0x1021) 0000 0000 0000 0000 (CRC 0x0000 sinistra spostato da 8 = 0x0000)


    0001 0000 0010 0001 = 0x1021 = crc intermedio.

  3. gestire l'input byte successivo 0x02: Attualmente abbiamo CRC intermedia = 0x1021 = 0001 0000 0010 0001. 3.1 'Xor-in' ingresso byte 0x02 in MSB di CRC (!): 0001 0000 0010 0001 (CRC 0x1021) 0000 0010 0000 0000 (byte di ingresso 0x02 sinistra spostata di 8)


    0001 0010 0010 0001 = 0x1221 Il MSB di questo risultato è la nostra di godimento corrente: MSB (0x1221) = 0x12. 3.2 Così 0x12 è il di godimento. Ottenere il resto per di godimento dalla nostra tabella: crctable16 [0x12] = 0x3273. Ricordate il valore CRC corrente è 0x1021. Spostare il MSB di crc attuale e XOR con il resto corrente per ottenere il nuovo CRC: 0011 0010 0111 0011 (0x3273) 0010 0001 0000 0000 (CRC 0x1021 sinistra spostato da 8 = 0x2100)


    0001 0011 0111 0011 = 0x1373 = crc finale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top