Electronic – CRC for eeprom data check

crceeprom

I wanted to check redundancy in eeprom and crosscheck the data for any errors occurred or not and I ended up reading CRC code. I found it useful but have some doubts that need clarity.

My objective is to check the memory address locations 0-15k of eeprom and store the checksum in memory and do the same for next 15k-30k address locations. The Both address locations store the same data and it is done so that eeprom memory is utilized.

Well When I began reading the docs. I ended up with a useful code:

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);
}

Here as far as my understanding the 'message' awaits bytes and continues CRC calculation until the character is not received. If I wanted to check the two blocks of eeprom memory as said before. How can I append the eeprom memory to the message variable.

Well my
another *doubt is whether eeprom read have any limit regarding reading reading address from 0-15k at a stretch rather like eeprom write *
I need your inputs to make this attempt useful and rewarding
Regards

Best Answer

While the suggested approach from PeterJ is fine, its cleaner to decouple the "data layer" logic (EEPROM access) from the CRC routine.

This CRC-32 can be universally used, its not bound to program specific behavior:

// 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; 
}

Then you just feed blocks of data to the CRC function like you see fit and as required by your application.

This usage example is just written down. It uses the fictional function eeprom_read() which reads a block of data from EEPROM. We start at EEPROM address 0.

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

Note that NUMBEROFBLOCKS is just a placeholder. I hope you get the idea.