Quería verificar la redundancia en eeprom y verificar los datos en busca de errores o no y terminé leyendo el código CRC. Lo encontré útil pero tengo algunas dudas que necesitan claridad.
Mi objetivo es verificar las ubicaciones de direcciones de memoria 0-15k de eeprom y almacenar la suma de verificación en la memoria y hacer lo mismo para las siguientes ubicaciones de direcciones de 15k-30k. Las ubicaciones de ambas direcciones almacenan los mismos datos y se hace para que se utilice la memoria eeprom.
Bueno, cuando comencé a leer los documentos. Terminé con un código útil:
unsigned int crc32(unsigned char *message) {
int i, j;
unsigned int byte, crc;
i = 0;
crc = 0xFFFFFFFF;
while (message[i] != 0) {
byte = message[i]; // Get next byte.
byte = reverse(byte); // 32-bit reversal.
for (j = 0; j <= 7; j++) { // Do eight times.
if ((int)(crc ^ byte) < 0)
crc = (crc << 1) ^ 0x04C11DB7;
else crc = crc << 1;
byte = byte << 1; // Ready next msg bit.
}
i = i + 1;
}
return reverse(~crc);
}
Aquí, según tengo entendido, el ' mensaje ' espera bytes y continúa el cálculo de CRC hasta que no se recibe el carácter. Si quisiera revisar los dos bloques de memoria eeprom como dije antes. ¿Cómo puedo agregar la memoria eeprom a la variable del mensaje?
Bueno, mi otra * duda es si la lectura de eeprom tiene algún límite con respecto a la lectura de la dirección de lectura de 0-15k en un tramo en lugar de la escritura de eeprom * Necesito sus aportes para que este intento sea útil y gratificante Saludos
Si bien el enfoque sugerido por PeterJ está bien, es más limpio desacoplar la lógica de "capa de datos" (acceso a EEPROM) de la rutina CRC.
Este CRC-32 se puede usar universalmente, no está sujeto a un comportamiento específico del programa:
// CCITT CRC-32 (Autodin II) polynomial
uint32_t CalcCRC32(uint32_t crc, uint8_t *buffer, uint16_t length) {
while(length--) {
crc = crc ^ *buffer++;
for (uint8_t j=0; j < 8; j++) {
if (crc & 1)
crc = (crc >> 1) ^ 0xEDB88320;
else
crc = crc >> 1;
}
}
return crc;
}
Luego, simplemente alimenta bloques de datos a la función CRC como mejor le parezca y según lo requiera su aplicación.
Este ejemplo de uso se acaba de escribir. Utiliza la función ficticia eeprom_read() que lee un bloque de datos de EEPROM. Empezamos en la dirección 0 de la EEPROM.
const uint8_t BLOCKLENGTH = 128;
uint32_t crc32;
uint8_t buffer[BLOCKLENGTH]; // temporary data buffer
crc32 = 0xFFFFFFFF; // initial CRC value
for (uint16_t i=0; i < NUMBEROFBLOCKS; i++) {
eeprom_read(BLOCKLENGTH * i, buffer, BLOCKLENGTH); // read block number i from EEPROM into buffer
crc32 = CalcCRC32(crc32, buffer, BLOCKLENGTH); // update CRC
}
// crc32 is your final CRC here
Tenga en cuenta que NUMBEROFBLOCKS es solo un marcador de posición. Espero que captes la idea.
i
variable, ¿por qué no solo while(length--)
en lugar del primer bucle for?Si está utilizando un microcontrolador con RAM limitada, probablemente no querrá intentar cargar una porción de datos de 16k en la memoria. Al reorganizar el código anterior, puede probar la siguiente función (no probada) que lee la EEPROM byte por byte dentro del ciclo. La función read_eeprom
es algo que inventé, por lo que deberá encontrar la función adecuada para su compilador.
#include <stdint.h>
uint32_t crc32(uint16_t start_address, uint16_t number_of_bytes) {
uint8_t j;
uint32_t crc, byte;
crc = 0xFFFFFFFF;
while (number_of_bytes--) {
byte = read_eeprom(start_address++);
byte = reverse(byte); // 32-bit reversal.
for (j = 0; j <= 7; j++) { // Do eight times.
if ((int32_t)(crc ^ byte) < 0)
crc = (crc << 1) ^ 0x04C11DB7;
else
crc = crc << 1;
byte = byte << 1; // Ready next msg bit.
}
}
return reverse(~crc);
}
También reemplacé sus declaraciones de variables para usar stdint.h ; probablemente sea bueno leer sobre eso y usarlo. En algunos compiladores integrados, unsigned int
por ejemplo, no será de 32 bits, por lo que esto hace que el código sea más portátil.
usuario30985
message
. Pero desea el CRC de (casi) toda su EEPROM, así que simplemente reemplace lawhile
cláusula con un bucle sobre (la mayor parte) de su espacio de direcciones EEPROM, ymessage[i]
con una lectura de la i-ésima palabra de 32 bits de su EEPROM. A diferencia de la escritura, leerlo no lo degradará. Recuerde excluir la parte de la EEPROM donde almacena la suma de verificación CRC para comparar.