Ayuda - Ejemplos de rutinas de Checksum

Hola, :)
Quisiera tener una mejor idea y ver ejemplos de algoritmos o programas en distintos lenguajes de programacion que realicen un Cheksum de la informacion, He leido al respecto pero se me hace dificil entender como hacer un programa en especifico para lenguaje C/C++ concretamente AVR/GCC, estoy haciendo un bus rs-485 en modo half-duplex donde las distancias pueden ser largas y quizas existan errores de comunicacion, ya casi tengo listo el sistema controlador por eso necesito una rutina que me ayude a realmente comprobar si la informacion que ha llegado es la correcta o si ha variado algun bit de datos.

|Inicio...|Direccion...|1er Byte datos... |2do Byte de datos... |Checksum|

pero lo que me falta es hacer el Checksum de la informacion y no se como hacerlo :confused:

Si alguno tiene alguna rutina o programa o formula matemática que me ayude a hacer el Checksum de la informacion le agradeceria su ayuda. :D
 
Del lado del emisor simplemente tenes que ir sumando los valores de los datos que mandas en una variable, sin importar que haya desborde y enviarlo en la trama.

Del lado del receptor, haces exactamente lo mismo, sumas todos los datos que te lleguen en una variable, obviando el checksum que mandaste. Por ultimo comparas el checksum que te mando el emisor y el checksum que le dio al receptor, si todo esta bien deberia dar igual.

Te doy un ejemplo con codigo del lado del emisor:

Código:
...

unsigned char flag_tx=0;

void rutina_int_tx()
{
  flag_tx=1;
}

unsigned char enviar_dato(unsigned char dato,unsigned char checksum,unsigned char flag_reset)
{
  registro_tx=dato;
  if(flag_reset)
    checksum=0;
  return (checksum+dato);
}
...

void main()
{
  unsigned char checksum=0;
  ...
  while(1)
    {
     ...
     if(flag_tx)
       {
       flag_tx=0; 
       checksum=enviar_dato(dato_a_enviar,checksum,1er_dato); //envio el 1er dato de la trama y reseteo o no
       }
    }
}

Obviamente la estructura principal dependera de tu forma de programar.

Del lado del receptor seria lo mismo, pero con el registro RX.
 
Gracias por responder, ahora entiendo mejor como con una comparacion se puede saber si los datos son correctos , si el checksum no es igual entonces sera necesario mandar de nuevo la trama, pero entonces la longitud de los bytes de datos deberia ser fija, ahora supongo que si quisiera mandar solo un byte de datos entonces deberia mandar en la trama un byte que contenga la informacion de cuantos bytes de datos se esta mandando y segun eso hacer el Checksum, me parece una buena solucion pero ahora me pregunto para que tipo de tramas se utiliza el CRC no entiendo bien el metodo de CRC:
 
Calculo del checksum por Somarda
-------------------------------------------------------------------------
En un fichero Intel HEX cada linea se descompone de la siguiente forma:
:10008000AF5F67F0602703E0322CFA92007780C3FD
:10.....................................................Número de bytes de datos en Hexadecimal
0080....................................................Dirección de memoria donde se cargarán los datos
00......................................................Tipo de datos (00: Datos, 02:Memoria extendida, 01:Fin del fichero)
AF5F67F0602703E0322CFA92007780C3........................Datos.
FD......................................................Checksum
La última fila de un fichero Intel HEX es siempre:
:00000001FF
:00.....................................................No hay datos
0000...................................................No hay dirección
01......................................................Fin del fichero
FF......................................................Checksum
El checksum se calcula de la siguiente forma: Se suman todos los bytes de la linea agrupados de 2 en 2,
excepto los dos últimos que son el checksum,
por ejemplo en la linea primera la suma (en Hexadecimal) sería:
10+00+80+00+AF+5F+67+F0+60+27+03+E0+32+2C+FA+92+00+77+80+C3=
803 (en Hexadecimal)
El checksum es el valor que hay que sumar para que los dos últimos bytes de la suma sean 00
(Se desechan los bytes altos) es decir:
803+Checksum=xx00,
en la práctica se coge el siguiente valor que tenga dos ceros y sea mayor que la suma,
(en nuestro ejemplo 900) y se le resta la suma obtenida.
El resultado es el checksum.
900-803=FD (Checksum)
También se puede calcular restando con la calculadora de Windows (en modo científico/hexadecimal):
0 - el resultado de la suma anterior en este caso 803 = FFFFFFFFFFFFF7FD
Y tomamos los dos últimos bytes (FD)
Este sería el checksum.
 
Bueno gracias por los ejemplos, ahora tengo otra pregunta mas, en el caso que la comprobacion por suma (Checksum) sea incorrecta, supongo que lo mas apropiado seria que el Tx reenvie la trama completa y el Rx envie el resultado de la comprobación por suma y hasta que el Checksum no sea igual se deberá seguir enviando la informacion, ahora si es un bus Rs-485 cuantas veces seria prudente que el Tx reenvie la trama de información antes de suponer que el otro dispositivo no responde...
 
Bueno gracias por los ejemplos, ahora tengo otra pregunta mas, en el caso que la comprobacion por suma (Checksum) sea incorrecta, supongo que lo mas apropiado seria que el Tx reenvie la trama completa y el Rx envie el resultado de la comprobación por suma y hasta que el Checksum no sea igual se deberá seguir enviando la informacion, ahora si es un bus Rs-485 cuantas veces seria prudente que el Tx reenvie la trama de información antes de suponer que el otro dispositivo no responde...

La idea es que el receptor haga la suma y compruebe que esta todo bien, para hacer la comunicacion totalmente confiable, hace que el receptor envie un byte que certifique que todo esta bien y que el Tx pueda continuar con otra trama, incluso tambien podrias hacer lo mismo en caso de error para que se reenvie la trama.

Por otro lado, tene en cuenta que si empleas un byte como verificacion y haces que el TX se quede esperando la respuesta del Rx, en el transmisor tal vez te conviene hacer una rutina de time-out en caso de que la comunicacion con el Rx falle.
 
Atrás
Arriba