es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo funciona el CRC16 utilizando datos de bytes? (para la implementación de CAN bus)

Tengo problemas para implementar un CRC16 para mensajes de CAN, he seguido las instrucciones dadas por este sitio web https://barrgroup.com/embedded-systems/how-to/crc-calculation-c-code y http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html#ch5, además de otras implementaciones que he visto aquí (por ejemplo https://stackoverflow.com/questions/10564491/function-to-calculate-a-crc16-checksum).

No entiendo cómo se procesa.
Mi mensaje aquí está en forma de bytes, por ejemplo char message[4] = {0x12, 0x34, 0x56, 0x78}. Cuando paso por el primer bucle solo tomo el primer byte, lo desplazo en 8 y calculo el remainder con un POLYNOME de 16 bits.
Eso significa que tenemos 0x1200 y pasamos por el segundo bucle con él, lo que significa que hago un XOR con el POLYNOME que guardo en el remainder pero no entiendo muy bien por qué esto funciona, especialmente cuando miro este código, los 2do, 3er y 4to bytes de mi mensaje que deberían ser XORed por los 8 primeros bits del POLYNOME en algún momento no pasan por él en absoluto.
Según la explicación de Wikipedia https://en.wikipedia.org/wiki/Cyclicredundancycheck el polinomio pasa por todo el mensaje a la vez y no byte por byte.
No sé cómo se traduce eso a hacer el CRC de 0x12345678 byte por byte.

uint16<em>t Compute</em>CRC16<em>Simple(char* message, int nbOfBytes)
{
    uint16</em>t POLYNOME = 0xC599; 
    uint16_t remainder = 0; 
    for (int byte = 0;byte < nbOfBytes; byte++)
    {
        remainder ^= (message[byte] << 8); 

<pre><code>    for (int i = 0; i < 8; i++)
    {
        if (remainder  & 0x8000) 
        {
            remainder = (remainder << 1) ^ POLYNOME ;
        }
        else
        {
            remainder <<= 1;
        }
    }
}
return remainder;
</code></pre>

}
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El código que has proporcionado es una implementación simple de un algoritmo CRC16, en el cual el mensaje se procesa byte por byte. La idea del algoritmo es dividir el mensaje por un polinomio predefinido (en este caso, 0xC599) y generar un valor de CRC que se puede agregar al mensaje.

    En el primer bucle, el residuo se XOR con el primer byte del mensaje desplazado a la izquierda por 8 bits. Esto crea un valor inicial para el residuo que representa los primeros 8 bits del mensaje.

    En el segundo bucle, el residuo se desplaza a la izquierda por 1 bit, y si el bit más significativo (MSB) es 1, el polinomio se XOR con el residuo. Este proceso continúa hasta que se hayan procesado los 8 bits del residuo. Después de esto, el siguiente byte del mensaje se XOR con el residuo, y el proceso se repite hasta que se hayan procesado todos los bytes del mensaje.

    Entonces, para responder tu pregunta, el polinomio recorre todo el mensaje a la vez, pero en esta implementación, solo recorre 8 bits a la vez, comenzando con los primeros 8 bits del mensaje. El polinomio se aplica al residuo en cada iteración del bucle hasta que se hayan procesado todos los bytes del mensaje.

    Espero que esta explicación te ayude a entender el algoritmo CRC16 y cómo se implementa en este código. Si tienes más preguntas, ¡no dudes en preguntar!

Comments are closed.