GARANTINDO A CONFIGURAÇÃO NA FLASH (ARDUINO, ESP8266) VIA CRC32

Ao inicializar o dispositivo, normalmente carrego as configurações na flash. Mas como garantir que 

o conteúdo é válido. Para garantir isso, utilizei um pequeno código que verifica um CRC32 da estrutura de dados

carregada da flash.O primeiro campo é o próprio CRC32 que é checado com o resultado do cálculo do CRC32 do resto da estrutura, Caso o resultado não seja igual ao CRC32 armazenado, "reseto" o dispositivo para valores default.

De repente essa idéia já em prática pode ser útil para alguém daqui.

As rotinas (SERVEM PARA ARDUINO E ESP8266) :

#include <EEPROM.h>

typedef struct _REGCONFIG_ {

  unsigned int crc32; //  SE CRC DIF RESET

  char ssid[65]; //
  char pwdssid[65]; //

  char ip[32];

  int porta;

}REGCONFIG;

/*
// Reverses (reflects) bits in a 32-bit word.
*/
unsigned int reverse(unsigned int x) {
  x = ((x & 0x55555555) 1) | ((x >> 1) & 0x55555555);
  x = ((x & 0x33333333) 2) | ((x >> 2) & 0x33333333);
  x = ((x & 0x0F0F0F0F) 4) | ((x >> 4) & 0x0F0F0F0F);
  x = (x 24) | ((x & 0xFF00) 8) |
  ((x >> 8) & 0xFF00) | (x >> 24);
  return x;
}


/*
* This is the basic CRC algorithm with no optimizations. It follows the
logic circuit as closely as possible.
*
*/
unsigned int crc32a(unsigned char *message, unsigned int len) {
  int i, j;
  unsigned int byte, crc;

  i = 0;
  crc = 0xFFFFFFFF;
  for (i = 0; i < len; i++) {
    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);
}

/*
*
*/
void gravaCFGEeprom() {
  EEPROM.begin(sizeof(REGCONFIG));
  unsigned char* p = (unsigned char*)&regEeprom.ssid[0];
  regEeprom.crc32 = crc32a(p, sizeof(REGCONFIG) - sizeof(unsigned int));
  p = (unsigned char*)&regEeprom;
  for (int i = 0; i < sizeof(REGCONFIG); i++, p++) {
    EEPROM.write(i, p[0]);
  }
  EEPROM.commit();
  EEPROM.end();
}


/*
*
*/
void resetEeprom() {
  yield();
  memset(&regEeprom, 0, sizeof(REGCONFIG));

  memmove(&regEeprom.ssid, SSIDDEFAULT, strlen(SSIDDEFAULT)); 

  memmove(&regEeprom.pwdssid, PWDDEFAULT, strlen(SSIDDEFAULT));

  memmove(&regEeprom.ip, IPDEFAULT, strlen(IPDEFAULT)); 

  regEeprom.porta = PORTADEFAULT;

  gravaCFGEeprom();
}

 

/*
*
*/
void loadConfig() {

  EEPROM.begin(sizeof(REGCONFIG));

  unsigned char* p = (unsigned char*)&regEeprom;
  for (int i = 0; i < sizeof(REGCONFIG); i++, p++) {
    p[0] = EEPROM.read(i);
  }
  EEPROM.end();

  p = (unsigned char*)&regEeprom;
  p += sizeof(unsigned int);
  unsigned int crc = crc32a(p, sizeof(REGCONFIG) - sizeof( unsigned int));

  Serial.print("CALCULADO=");
  Serial.println(crc);
  Serial.print("GUARDADO=");
  Serial.println(regEeprom.crc32);

  if (crc != regEeprom.crc32) {
    resetEeprom();
  }

}

void setup() {

  loadConfig().

}

Exibições: 283

Comentar

Você precisa ser um membro de Laboratorio de Garagem (arduino, eletrônica, robotica, hacking) para adicionar comentários!

Entrar em Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço