Almacenamiento de datos PIC32 en cambio de flash / corrupto

0

Tengo un problema aleatorio con los datos guardados en flash en PIC32MX470F512L.

Dado que no hay EEPROM, parte del almacenamiento flash se utiliza para guardar la configuración y algunas estadísticas (por ejemplo: motivo de reinicio, errores en la comunicación en serie, etc.).

Más de 50 unidades o más, al azar como parte del cambio de configuración, no se encuentra la causa, pero hay algunas hipótesis por el momento:

  • No hay condensador en MCLR
  • Lectura de la configuración en flash antes de VDD completamente estabilizada
  • apagar durante la escritura flash

Estoy seguro de que no hay suficientes escrituras para ir más allá del límite, en algún lugar entre 1 y 25 escrituras por día.

Sin embargo, no he podido reproducir el problema periódicamente.

Aquí hay algunas partes relevantes del código ...

Main

int main()
{
    /* Variables defines */

    //Configure l'horloge systeme
    SYSTEMConfig(GetSystemClock(),SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);


    //Active le watchdog (periode de timeout de 8sec)
    EnableWDT();

    //Initialisation de la configuration non volatile
    config_init();

    /* Other init stuff */

    //Gestion des statistiques de demarrage.
    if(mGetWDTOFlag())
    {      //Reset par watchdog
        mClearWDTOFlag();
        g_stConfiguration.stats[STAT_REBOOT_WATCHDOG]++;
        config_saveStats();
    }
    else if(mGetPORFlag())
    {  //Reset par switch
        mClearPORFlag();
        g_stConfiguration.stats[STAT_REBOOT_NO_POWER]++;
        config_saveStats();
    }
    else if(mGetBORFlag())
    {  //Reset par mauvaise alimentation
        mClearBORFlag();
        g_stConfiguration.stats[STAT_REBOOT_NO_POWER]++;
        config_saveStats();
    }
    else if(mGetMCLRFlag())
    { //Reset par mclr (bouton reset)
        mClearMCLRFlag();
        g_stConfiguration.stats[STAT_REBOOT_OTHER]++;
        config_saveStats();
    }
    else if(mGetSWRFlag())
    {  //Reset software (non implemente encore)
        mClearSWRFlag();
        g_stConfiguration.stats[STAT_REBOOT_OTHER]++;
        config_saveStats();
    }

    /* Going to main loop */
}

Funciones de la utilidad Flash

void config_init() {
    // Lecture de la configuration presente en memoire
    nvm_lireConfig(&g_stConfiguration,NVM_PAGE_CONFIG);

    /*
     * Si le numero d'ordinateur est zero c'est parce qu'il n'y a rien dans la
    * flash, on va charger les valeurs par defaut.
    */
    if(g_stConfiguration.numero_ordinateur == 0)
    {
        config_defaut(&g_stConfiguration);
        nvm_ecrireConfig(&g_stConfiguration,NVM_PAGE_CONFIG);
        nvm_ecrireConfig(&g_stConfiguration,NVM_PAGE_CFG_BKP);
    }
}

void config_saveStats()
{
    nvm_ecrireConfig(&g_stConfiguration,NVM_PAGE_CONFIG);
}

void nvm_lireConfig(void *dataAdr, int pageNumber) {
    memcpy(dataAdr,(void*)eedata_addr[pageNumber],sizeof(ComputerConfiguration));
}

int nvm_ecrireConfig(void * dataAdr, int pageNumber) {
    int pagebuff[1024]; //Buffer d'une page, necessaire pour la fonction NVProgram

    // On efface la page avant d'ecrire dedans
    if(nvm_effacer(pageNumber) == NVM_SUCCESS) {
        // Ecriture des donnees dans la NVM
        if(NVMProgram((void*)eedata_addr[pageNumber],dataAdr,sizeof(ComputerConfiguration),(void*)pagebuff) == 0) {
            // Verification des donnees ecrits
            if(nvm_verifier(dataAdr,pageNumber) == NVM_SUCCESS) {
                return NVM_SUCCESS;
            } else {
                return NVM_VERIFY_ERROR;
            }
        } else {
            return NVM_WRITE_ERROR;
        }
    } else {
        return NVM_ERASE_ERROR;
    }
}

int nvm_effacer(int pageNumber) {
    if(pageNumber < NVM_NUM_PAGES) {
        if(NVMErasePage((void*) eedata_addr[pageNumber]) == 0) {
            return NVM_SUCCESS;
        } else {
            return NVM_ERASE_ERROR;
        }
    } else {
        return NVM_PAGE_OUT_OF_RANGE;
    }
}
    
pregunta Alexandre Lavoie

1 respuesta

2

Después de más investigación y pruebas, parece que Erik Friesen tenía razón, había demasiados ciclos de borrado / escritura en la memoria flash.

El chip utilizado (PIC32MX470) tiene una resistencia de celda mínima de 20000 E / W ciclo (se encuentra en la página de hoja de datos 292).

En el programa encontré varias llamadas a la escritura de configuración que podían suceder muchas docenas de veces al día, también se usó erace dos veces, una manualmente y otra en NVMProgram .

Para confirmar el problema, he cambiado las páginas usadas en el programa y la lectura / escritura funcionaron perfectamente (ya que esas páginas no se usaron antes).

La solución final fue:

  • Limpiando el código, eliminando todas las configuraciones innecesarias guardadas
  • Eliminando el doble borrado
  • Integre la biblioteca de emulación de datos EEPROM de MicroChip a extender la duración aún más
respondido por el Alexandre Lavoie

Lea otras preguntas en las etiquetas