Hallo Leute,
ich habe bei einem XMEGA und der CalcCheckSum ein Problem, was ich irgendwie nicht eingrenzen kann.
Bei jeder Änderung der Einstellungen wird die CRC der Konfiguration im EEProm berechnet und im RTC-Ram (Batterie gepuffert) abgelegt und und die Einstellungen aus dem EEProm werden als Config-Datei auf die SD-Card gelegt.
Bei einem Neustart wird die CRC berechnet und mit dem CRC im RTC-Ram verglichen, ist es gleich läuft die Steuerung durch und fertig.
Ist diese unterschiedlich, werden die Einstellungen von der SDCard geladen, sollte die SDCard nicht verfügbar sein, werden die Werkseinstellungen aus dem Flash geladen, diese werden als Datei in den Flash eingelinkt:
Auf der SDCard sind unter umständen verschiedene Konfigs, wenn ich die Konfig ausgewählt habe, lade ich diese in den EEProm Bereich und berechne die CRC:
Danach ruf ich die folgende Funktion auf:
Da der RTC-RAM über ein I2C Bus erreichbar ist, habe ich das über ein USERDEVICE angelegt:
Und jetzt kommt das merkwürdige, wenn ich dann später den Test mit der Funktion:
Beim überprüfen erhalte ich ab und an ein FAIL. Also einen Unterschied zwischen dem errechneten CRC und dem Wert im RTC-RAM. Der Wert im RTC-Ram entspricht dem Wert den der XMEGA aber nach dem Schreiben errechnet hat. Nur wenn ich dann erneut berechnet (ohne Änderung) erhalte ich eine leichte Abweichung.
Jetzt wird es noch merkwürdiger, gehe ich jetzt in die Einstellungen der Steuerung und ändere nur einen Wert, danach wird wieder der CRC berechnet und abgelegt, dann stimmt der Wert. Mache ich jetzt die Änderung in den Einstellungen der Steuerung Rückgängig, stimmen die CRCs wieder.
Ich habe fast das Gefühl, das nach der Übernahme der Datei Einstellungen auf der SCCard, diese noch nicht richtig fertig sind um eine CRC Berechnung zu machen. Als ob der Treiber / XMEGA im Hintergrund erst noch im EEProm speichert. Ein MDELAY(100) bringt leider keinen Unterschied und eigentlich nutze ich mit dem Process und Tasksystem NIE Delays.
Hat Jemand evtl. eine Idee, wo das Problem liegen könnte?
Thorsten
ich habe bei einem XMEGA und der CalcCheckSum ein Problem, was ich irgendwie nicht eingrenzen kann.
Bei jeder Änderung der Einstellungen wird die CRC der Konfiguration im EEProm berechnet und im RTC-Ram (Batterie gepuffert) abgelegt und und die Einstellungen aus dem EEProm werden als Config-Datei auf die SD-Card gelegt.
Bei einem Neustart wird die CRC berechnet und mit dem CRC im RTC-Ram verglichen, ist es gleich läuft die Steuerung durch und fertig.
Ist diese unterschiedlich, werden die Einstellungen von der SDCard geladen, sollte die SDCard nicht verfügbar sein, werden die Werkseinstellungen aus dem Flash geladen, diese werden als Datei in den Flash eingelinkt:
Code
const
gLoadSTDCFG : tLoadSTDCFG = 'STDCFG.CFG'; // Std CFG mit flashen
gLoadSTDCFG : tLoadSTDCFG = 'STDCFG.CFG'; // Std CFG mit flashen
Auf der SDCard sind unter umständen verschiedene Konfigs, wenn ich die Konfig ausgewählt habe, lade ich diese in den EEProm Bereich und berechne die CRC:
Code
//---------------------------------------------------------------
// Load Config
procedure Load_Cfg( inFileName : Pointer to string; BBootCfg : boolean; BZKSCfgLoad : boolean);
var
wXCopy : Word;
wResBlockWrite : Word;
wResBlockWriteAll: Word;
CfgPointer : pointer;
CfgPointerWork : pointer;
strStrFileName : string[12];
BFileLoadOK : boolean;
BlockAnzahl64 : byte;
begin
if bMMCok then // SD Card vorhanden und aktiv
BFileLoadOK:=false;
if BBootCfg then // bootCfg StandardName
DateiNameCfg := 'boot.cfg';
else
strStrFileName:= inFileName^;
DateiNameCfg := strStrFileName;
endif;
if not F16_FileExist(sPathPara, DateiNameCfg,[faArchive]) then // .CFG vorhanden?
return;
else
if ListDirGetEntry( sPathPara, DateiNameCfg, [faArchive]) then // TSearchRecord laden wegen Datum und Uhrzeit
SDCfgDate := SR.Dir.WrAccDate;
SDCfgTime := SR.Dir.WrAccTime;
endif;
if BZKSCfgLoad then BlockAnzahl64:=62; else BlockAnzahl64:= 58; endif;
lock(self); // Lass Dich nicht stören
if not F16_FileAssign(Cfg_Datei, sPathPara, DateiNameCfg) then // Handle mit FileNamen verknüpfen
CheckFileHandle(Cfg_Datei);
return;
endif;
if not F16_FileReset( Cfg_Datei ) then // vorhandene Datei öffnen
CheckFileHandle(Cfg_Datei);
return;
endif;
// Init der Zähler
wResBlockWrite:=0;
wResBlockWriteAll:=0;
CfgPointer:= @Cfg1; // ziehe Pointer für Start vom EEPROM
for wXCopy:= 0 to BlockAnzahl64 do
CfgPointerWork:= CfgPointer+(wXCopy * 64);
BFileLoadOK:= F16_BlockRead (Cfg_Datei, @SDBuf64, 64 ,wResBlockWrite );
if not BFileLoadOK then
F16_FileClose(Cfg_Datei); // schließe evtl offene Datei vor Break
Break;
endif;
CopyBlock( @SDBuf64, EEPromPtr(CfgPointerWork), 64 ); // übertrage es in den EEProm Bereich
wResBlockWriteAll:=wResBlockWriteAll+wResBlockWrite; // für geschriebene Daten berechnen!
endfor;
if not F16_FileClose(Cfg_Datei) then // File schließen
SD_Error := 7;
endif; // CloseFile
unlock(self); // lass Dich wieder stören
endif; // .CFG vorhanden?
endif; // if bMMCok then
end Load_Cfg;
// Load Config
procedure Load_Cfg( inFileName : Pointer to string; BBootCfg : boolean; BZKSCfgLoad : boolean);
var
wXCopy : Word;
wResBlockWrite : Word;
wResBlockWriteAll: Word;
CfgPointer : pointer;
CfgPointerWork : pointer;
strStrFileName : string[12];
BFileLoadOK : boolean;
BlockAnzahl64 : byte;
begin
if bMMCok then // SD Card vorhanden und aktiv
BFileLoadOK:=false;
if BBootCfg then // bootCfg StandardName
DateiNameCfg := 'boot.cfg';
else
strStrFileName:= inFileName^;
DateiNameCfg := strStrFileName;
endif;
if not F16_FileExist(sPathPara, DateiNameCfg,[faArchive]) then // .CFG vorhanden?
return;
else
if ListDirGetEntry( sPathPara, DateiNameCfg, [faArchive]) then // TSearchRecord laden wegen Datum und Uhrzeit
SDCfgDate := SR.Dir.WrAccDate;
SDCfgTime := SR.Dir.WrAccTime;
endif;
if BZKSCfgLoad then BlockAnzahl64:=62; else BlockAnzahl64:= 58; endif;
lock(self); // Lass Dich nicht stören
if not F16_FileAssign(Cfg_Datei, sPathPara, DateiNameCfg) then // Handle mit FileNamen verknüpfen
CheckFileHandle(Cfg_Datei);
return;
endif;
if not F16_FileReset( Cfg_Datei ) then // vorhandene Datei öffnen
CheckFileHandle(Cfg_Datei);
return;
endif;
// Init der Zähler
wResBlockWrite:=0;
wResBlockWriteAll:=0;
CfgPointer:= @Cfg1; // ziehe Pointer für Start vom EEPROM
for wXCopy:= 0 to BlockAnzahl64 do
CfgPointerWork:= CfgPointer+(wXCopy * 64);
BFileLoadOK:= F16_BlockRead (Cfg_Datei, @SDBuf64, 64 ,wResBlockWrite );
if not BFileLoadOK then
F16_FileClose(Cfg_Datei); // schließe evtl offene Datei vor Break
Break;
endif;
CopyBlock( @SDBuf64, EEPromPtr(CfgPointerWork), 64 ); // übertrage es in den EEProm Bereich
wResBlockWriteAll:=wResBlockWriteAll+wResBlockWrite; // für geschriebene Daten berechnen!
endfor;
if not F16_FileClose(Cfg_Datei) then // File schließen
SD_Error := 7;
endif; // CloseFile
unlock(self); // lass Dich wieder stören
endif; // .CFG vorhanden?
endif; // if bMMCok then
end Load_Cfg;
Danach ruf ich die folgende Funktion auf:
Code
//---------------------------------------------------------------
// Errechne Config CRC und lege diese im RTCRAM ab
//
procedure CalcCfgCRC;
var
wCRC_Buffer : word;
begin
wCRC_Buffer:= CalcCheckSum (@Cfg1, @BInvalidateBoot); // Berechne CRC
wCRC_Config_RTC:= wCRC_Buffer; // Lege den Wert im RTC-Ram ab Userdevice
DebugOut('Eprom CRC: '+IntToHex(wCRC_Buffer));
end CalcCfgCRC;
// Errechne Config CRC und lege diese im RTCRAM ab
//
procedure CalcCfgCRC;
var
wCRC_Buffer : word;
begin
wCRC_Buffer:= CalcCheckSum (@Cfg1, @BInvalidateBoot); // Berechne CRC
wCRC_Config_RTC:= wCRC_Buffer; // Lege den Wert im RTC-Ram ab Userdevice
DebugOut('Eprom CRC: '+IntToHex(wCRC_Buffer));
end CalcCfgCRC;
Da der RTC-RAM über ein I2C Bus erreichbar ist, habe ich das über ein USERDEVICE angelegt:
Code
{ functions }
UserDevice UsrDevIni;
begin
// Prüfe ob Speicher init benötigt wird:
if TWIoutE(RTC_MCP_ID, $20+38) then // set the read address
TWIinpE(RTC_MCP_ID, inWordCheck); // read the word
if inWordCheck <> $1A2B then
TWIoutE(RTC_MCP_ID, $20); // Setze Start Adresse
for xInit:= 0 to 63 do
// fülle SRAM mit $00 auf
TWIoutE(RTC_MCP_ID, $20+xInit, $00);
endfor;
// usrW38_CheckSram
TWIoutE(RTC_MCP_ID, $20+38, $1A2B); // Wenn Init dann steht hier 1A2B
endif;
return;
endif;
end;
//-----------------------------------------------------------------------------
UserDevice UsrDevInp(adr : word) : byte;
var ok : boolean;
inp : byte;
begin
lock(self);
ok:= TWIoutE(RTC_MCP_ID, $20+lo(adr)); // set the read address
if ok then
TWIinpE(RTC_MCP_ID, inp); // read the byte
unlock(self);
return(inp);
endif;
unlock(self);
return($ff);
end;
//-----------------------------------------------------------------------------
UserDevice UsrDevOut(adr : word; outp : byte);
var ok : boolean;
begin
lock(self);
ok:= TWIoutE(RTC_MCP_ID, $20+lo(adr), outp);
unlock(self);
end;
UserDevice UsrDevIni;
begin
// Prüfe ob Speicher init benötigt wird:
if TWIoutE(RTC_MCP_ID, $20+38) then // set the read address
TWIinpE(RTC_MCP_ID, inWordCheck); // read the word
if inWordCheck <> $1A2B then
TWIoutE(RTC_MCP_ID, $20); // Setze Start Adresse
for xInit:= 0 to 63 do
// fülle SRAM mit $00 auf
TWIoutE(RTC_MCP_ID, $20+xInit, $00);
endfor;
// usrW38_CheckSram
TWIoutE(RTC_MCP_ID, $20+38, $1A2B); // Wenn Init dann steht hier 1A2B
endif;
return;
endif;
end;
//-----------------------------------------------------------------------------
UserDevice UsrDevInp(adr : word) : byte;
var ok : boolean;
inp : byte;
begin
lock(self);
ok:= TWIoutE(RTC_MCP_ID, $20+lo(adr)); // set the read address
if ok then
TWIinpE(RTC_MCP_ID, inp); // read the byte
unlock(self);
return(inp);
endif;
unlock(self);
return($ff);
end;
//-----------------------------------------------------------------------------
UserDevice UsrDevOut(adr : word; outp : byte);
var ok : boolean;
begin
lock(self);
ok:= TWIoutE(RTC_MCP_ID, $20+lo(adr), outp);
unlock(self);
end;
Und jetzt kommt das merkwürdige, wenn ich dann später den Test mit der Funktion:
Code
//-----------------------------------------------------------------------------
// Prüfe CRC cfg
function CheckCfgCRC : boolean;
var
wCRC_Buffer : word;
begin
wCRC_Buffer:= CalcCheckSum (@Cfg1, @BInvalidateBoot); // Berechne CRC
DebugOut('Eprom CRC: '+IntToHex(wCRC_Buffer)+ ' / RTC RAM CRC: '+IntToHex(wCRC_Config_RTC) );
if wCRC_Config_RTC <> wCRC_Buffer then
return(false);
else
return(true);
endif;
end CheckCfgCRC; // CheckCfgCRC
// Prüfe CRC cfg
function CheckCfgCRC : boolean;
var
wCRC_Buffer : word;
begin
wCRC_Buffer:= CalcCheckSum (@Cfg1, @BInvalidateBoot); // Berechne CRC
DebugOut('Eprom CRC: '+IntToHex(wCRC_Buffer)+ ' / RTC RAM CRC: '+IntToHex(wCRC_Config_RTC) );
if wCRC_Config_RTC <> wCRC_Buffer then
return(false);
else
return(true);
endif;
end CheckCfgCRC; // CheckCfgCRC
Beim überprüfen erhalte ich ab und an ein FAIL. Also einen Unterschied zwischen dem errechneten CRC und dem Wert im RTC-RAM. Der Wert im RTC-Ram entspricht dem Wert den der XMEGA aber nach dem Schreiben errechnet hat. Nur wenn ich dann erneut berechnet (ohne Änderung) erhalte ich eine leichte Abweichung.
Jetzt wird es noch merkwürdiger, gehe ich jetzt in die Einstellungen der Steuerung und ändere nur einen Wert, danach wird wieder der CRC berechnet und abgelegt, dann stimmt der Wert. Mache ich jetzt die Änderung in den Einstellungen der Steuerung Rückgängig, stimmen die CRCs wieder.
Ich habe fast das Gefühl, das nach der Übernahme der Datei Einstellungen auf der SCCard, diese noch nicht richtig fertig sind um eine CRC Berechnung zu machen. Als ob der Treiber / XMEGA im Hintergrund erst noch im EEProm speichert. Ein MDELAY(100) bringt leider keinen Unterschied und eigentlich nutze ich mit dem Process und Tasksystem NIE Delays.
Hat Jemand evtl. eine Idee, wo das Problem liegen könnte?
Thorsten