Pages: 1 2 [3] 4 5   Go Down
Author Topic: Librerie per il calcolo del CRC16 e CRC32  (Read 4737 times)
0 Members and 1 Guest are viewing this topic.
Switzerland
Offline Offline
Faraday Member
**
Karma: 113
Posts: 5954
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Se ben ricordo NON avevo strutturato la cosa come una vera libreria, ma come due moduli C separati dei quali includevi solo quello che ti serviva direttamente nel tuo progetto (copiando il .h ed il .c nella cartella dove hai il tuo .ino) smiley-wink

Guglielmo
Logged

Search is Your friend ... or I am Your enemy !

0
Offline Offline
Newbie
*
Karma: 0
Posts: 38
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, quindi dovrei utilizzere o quello a 16crc o 32crc?
Cioè dato questo sketch:

Code:
#include "crc16.h"
#include "crc32.h"

unsigned int myCrc16;
unsigned long myCrc32;

void setup() {

   delay(3000);
  
   Serial.begin(9600);
  
   myCrc16 = calc_crc16("123456789", 9);
   myCrc32 = calc_crc32("123456789", 9);
  
   #ifdef __SAM3X8E__
      Serial.println("Calculate CRC on string 123456789");
      Serial.print("CRC16 = 0x");
      Serial.println(myCrc16, HEX);
      Serial.print("CRC32 = 0x");
      Serial.println(myCrc32, HEX);
   #else
      Serial.println(F("Calculate CRC on string 123456789"));
      Serial.print(F("CRC16 = 0x"));
      Serial.println(myCrc16, HEX);
      Serial.print(F("CRC32 = 0x"));
      Serial.println(myCrc32, HEX);
   #endif
}

void loop() {

}
Cosa devo cancellare?

Grazie
« Last Edit: July 04, 2013, 02:38:41 pm by leo72 » Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 113
Posts: 5954
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

... devi usare ... quello che ti serve nella TUA applicazione ... smiley-lol

Quindi includi solo il .h del crc che vuoi calcolare (o crc16.h per calcolare il crc16 oppure crc32.h se invece vuoi calcolare il crc32) ed, ovviamente, solo le variabili che ti servono smiley-wink

Guglielmo

P.S. : Il codice DEVE SEMPRE essere racchiuso negli appositi tag "code" e "/code" ... te li mette automaticamente con il bottoncino # che trovi in alto quando scrivi il messaggio. Grazie.
Logged

Search is Your friend ... or I am Your enemy !

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 329
Posts: 22782
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

A chi mai servisse, vi allego anche una semplicissima routine che calcola il CRC-8 usando le formule di Dallas/Maxim.

Code:
//CRC-8 - algoritmo basato sulle formule di CRC-8 di Dallas/Maxim
byte CRC8(const byte *data) {
    byte crc = 0x00;

    while (*data) {
        byte extract = *data++;
        for (byte tempI = 8; tempI; tempI--) {
            byte sum = (crc ^ extract) & 0x01;
            crc >>= 1;
            if (sum) {
                crc ^= 0x8C;
            }
            extract >>= 1;
        }
    }
    return crc;
}

Per usarlo basta passare un array di byte e si ha indietro il CRC8.
Esempio:
Code:
byte vettore[5] = {2, 3, 56, 10, 1};
....
byte risultato = CRC8(vettore);

E' comodo nella trasmissione di piccoli pacchetti dati, giusto come somma di controllo. Se serve maggior sicurezza, usate CRC16 o CRC32.
Logged


Switzerland
Offline Offline
Faraday Member
**
Karma: 113
Posts: 5954
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bella Leo ... la metto assieme alle altre due ... cosÌ si ha l'imbarazzo della scelta  smiley-lol smiley-lol smiley-lol

Guglielmo

P.S. : Sai che non mi è chiaro da dove pesca la lunghezza del vettore che gli passi ... riceve solo un pointer ... come fa a sapere quanti bytes contiene ??? O deve terminare con un byte a 0x00 ???
« Last Edit: July 04, 2013, 03:29:03 pm by gpb01 » Logged

Search is Your friend ... or I am Your enemy !

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 329
Posts: 22782
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Dovrebbe funzionare per il fatto che byte in Arduino è un alias di unsigned char. In pratica un array di byte altro non è che un array di unsigned char. Il compilatore dovrebbe mettere il valore \0 alla fine come nel caso dei *char.

Non ho disassemblato il binario però, quindi congetturo.
Logged


Switzerland
Offline Offline
Faraday Member
**
Karma: 113
Posts: 5954
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

... ok ... quindi, per stare tranquilli al 100%, ho si inserisce a manina un ultimo valore 0x00 alla fine o si modifica la routine per accettare un parametro in più ... il numero di caratteri (così inoltre diventa congrua con le altre due) ...  smiley-twist smiley-twist smiley-twist smiley-twist

Guglielmo
Logged

Search is Your friend ... or I am Your enemy !

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 112
Posts: 7113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mi spieghi questo  smiley-sweat

Code:
crc >>= 1;

EDIT
ci sono arrivato
Code:
crc = crc >> 1;
« Last Edit: July 05, 2013, 02:48:58 am by PaoloP » Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

0
Online Online
Shannon Member
****
Karma: 131
Posts: 10468
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ma per la lunghezza non si potrebbe usare la funzione "sizeof"?

NO! sizeof ritorna la lunghezza dell'array solo se usato sull'array originale, qualsiasi suo altro riferimento (aka puntatore) ritorna la grandezza in byte del PUNTATORE, ovvero 2 byte (da cui ne deriva che al massimo possiamo usare una ram con 65536 byte... poi in realtà grazie ad indirizzo di sfasamento e altri trucchetti puoi incrementare questo valore, ma sto divagando)
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 329
Posts: 22782
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

... ok ... quindi, per stare tranquilli al 100%, ho si inserisce a manina un ultimo valore 0x00 alla fine o si modifica la routine per accettare un parametro in più ... il numero di caratteri (così inoltre diventa congrua con le altre due) ...  smiley-twist smiley-twist smiley-twist smiley-twist

Guglielmo
La precedente versione di quella routine funzionava proprio così, ossia passando 2 parametri: il vettore e la sua lunghezza.
Però giorni fa mi era venuta in mente questa cosa del byte/unsigned char, l'ho voluta provare e pare che funzioni alla perfezione  smiley-wink
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 329
Posts: 22782
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sono stato una buona mezz'ora a studiare il disassemblato della funzione. A me pare che sui vettori con dimensione fissa non ci siano problemi perché nel codice il compilatore prima di chiamare la funzione carica l'indirizzo di fine del vettore e nella routine di calcolo del CRC semplicemente confronta il valore corrente del puntatore con la fine precedentemente memorizzata per cui quando arriva in fondo al vettore, lui esce.
Logged


0
Online Online
Shannon Member
****
Karma: 131
Posts: 10468
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

... ok ... quindi, per stare tranquilli al 100%, ho si inserisce a manina un ultimo valore 0x00 alla fine o si modifica la routine per accettare un parametro in più ... il numero di caratteri (così inoltre diventa congrua con le altre due) ...  smiley-twist smiley-twist smiley-twist smiley-twist

Guglielmo
La precedente versione di quella routine funzionava proprio così, ossia passando 2 parametri: il vettore e la sua lunghezza.
Però giorni fa mi era venuta in mente questa cosa del byte/unsigned char, l'ho voluta provare e pare che funzioni alla perfezione  smiley-wink

non può funzinare alla perfezione: se io ho un array di byte in cui chessò, ho inviato il gezzo dell'intero 126, avrò inviato 2 byte: 0x00 0x7E però con questo "trucco" il valore 0x7E NON verrà mai controllato. In pratica state dando per scontato che il valore 0x00 NON sia mai contenuto nell'array di byte, cosa che non è assolutamente vera.

Un trucco che si può usare è usare 2 0x00 di fila, e se la stringa di byte contiene due 0x00 di fila nel suo contenuto allora dividerli con un valore noto; in pratica come fa il C con i caratteri di escape. (ha un nome questo sistema, si usa per le comunicazioni, ma non ricordo)

Quote
A me pare che sui vettori con dimensione fissa
se ti riferisci a me, sappi che la funzione prende un PUNTATORE all'array di dimensione fissa. quindi un test veritiero deve tenerne conto.

In oltre, lato ricezione, spesso si usa un array a dimensione fissa bello grosso, e lo si riempie finchè ci sono dati; con il sistema dimensione dell'array automatico con sizeof, sei costretto a ridimensionare l'array (o usare un array mallocato sul momento), antrambi i sistemi giocano col l'allocazioe dinamica, che come disse anche astro più volte, è spesso pura follia su un micro come gli atmega.
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 329
Posts: 22782
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Non mi riferivo a nessuno.  smiley-wink
Comunque disassemblando il codice la prima analisi, cioè quella del carattere \0 finale, è errata. Come detto, il compilatore carica l'indirizzo della cella finale e con un semplice confronto controlla quando è arrivato ad essa.
Logged


Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 112
Posts: 7113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quindi l'array potrebbe contenere tutti 0x00 ma verrebbe elaborato ugualmente?
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Switzerland
Offline Offline
Faraday Member
**
Karma: 113
Posts: 5954
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

...
non può funzinare alla perfezione: se io ho un array di byte in cui chessò, ho inviato il gezzo dell'intero 126, avrò inviato 2 byte: 0x00 0x7E però con questo "trucco" il valore 0x7E NON verrà mai controllato. In pratica state dando per scontato che il valore 0x00 NON sia mai contenuto nell'array di byte, cosa che non è assolutamente vera.
...

Concordo al 100% ...
... se si deve fare una routine la si deve fare indipendente dal blocco di bytes che deve elaborare e l'unico modo è ... puntatore al blocco, lunghezza del blocco  smiley-twist smiley-twist smiley-twist

Guglielmo
Logged

Search is Your friend ... or I am Your enemy !

Pages: 1 2 [3] 4 5   Go Up
Jump to: