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