Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Datenlogger zerstört CompactFlash (CF) Karten (https://www.delphipraxis.net/170316-delphi-datenlogger-zerstoert-compactflash-cf-karten.html)

rhuber 11. Sep 2012 10:56

Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Hallo zusammen,nach einer langen Zeit als nur-Leser brach ich jetzt doch mal eure Hilfe!
Leider hab ich keinen besseren Bereich im Forum gefunden, deshalb versuch ich's mal hier:

Hab ein gröberes Problem mit meinem Datenlogger, der im Minutentakt ca. 10 Temperaturwerte in ein .csv-File schreib. Von 5 Datenloggern ist nach wenigen Monaten bereits bei 3 die CF-Karte defekt(Zugriffsfehler auf Logfile-Ordner,nach aut. Scan durch Win2k alle bisherigen csv-Files weg...)

Das System sieht so aus:
- Embedded-PC Alix 3.d3 (500MHz Geode LX, 256MB RAM,CF-Festplatte)
- Windows 2000 SP4 (praktisch sämtliche Schreibzugriffe unterdrückt)
- Windows und Logs laufen auf CF-Karte (SLC-Typ,sollte >1Million Schreibzugriffe ertragen)
- Alle 60s werden in Logfile neue Werte eingetragen, nach 24h wird neues Logfile erstellt (also max. 1500 Schreibzugriffe auf gleiche Datei,max.600kbyte)
- FileMon gibt jede Minute jedoch 4 Schreibzugriffe an, also max. 6000 auf selbes Logfile

Weshalb sich die CF-Karten so schnell verabschieden ist mir ein Rätsel! Sind es evtl. einfach schlechte Karten, oder liegt es an meiner suboptimalen Schreibfunktion? Ich verwende folgende:

Code:
If FileExists(fileName) Then Begin //fileName=.csv-File des aktuellen Tages
  try
    AssignFile(TxtFile, fileName); //.csv-File Laden
    Append(TxtFile);
    WriteLn(TxtFile,messwerte);   //Neue Zeile mit Messwerte in Logfile hinzufügen (ca.300 Zeichen)
    CloseFile(TxtFile);

Nersgatt 11. Sep 2012 11:00

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Flashdisks haben 10.000 bis 2.000.000 Schreibzyklen - je nach Typ, die vom Hersteller garantiert werden. Ist nunmal so, muss man einplanen.

mkinzler 11. Sep 2012 11:02

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Ich würde die Datei nicht bei jedem Schreibzugriff Öffnen/Schliessen.

rhuber 11. Sep 2012 11:13

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Hmm,die verwendeten SLC-Karten müssten >1.000.000 Schreibzyklen aushalten, im Gegensatz zu den üblichen MLC (>10.000 bis >100.000). Hätte daher eigentlich ausreichend Reserven...

Ok,also am Besten bei Programmstart Logfile öffnen, und dann erst beim Beenden wieder schliessen? Könne ich denn so Schreibzugriffe sparen? Lesezugriffe sollen ja unproblematisch sein.

Danke!

EDIT: Wird etwa erst mit dem Aufruf von CloseFile() geschrieben, solange ich nur WriteLn()ausführe bleibt alles im RAM??

Medium 11. Sep 2012 11:22

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Zitat:

Zitat von rhuber (Beitrag 1182461)
EDIT: Wird etwa erst mit dem Aufruf von CloseFile() geschrieben, solange ich nur WriteLn()ausführe bleibt alles im RAM??

Das kommt auf die Einstellungen von Windows bzw. des Schreib-Caches an. Manche Controller cachen ebenfalls. Bis kein Flush oder Close ausgeführt ist, kann man daher allgemein erstmal nur sagen: Die Daten könnten schon geschrieben sein, vielleicht auch nicht.

himitsu 11. Sep 2012 11:49

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Was loggt denn der Datenlogger?
Nur Zugriffe auf DateiAPIs, die Zugriffe auf den Datenträgercontroler, oder die realen Zugriffe auf die Speicherzellen?


Jupp, beim Öffnen wird das Ende der Datei aisgelesen, dann nochmal darin nach einem "Dateiendezeichen" gesucht, der Zeiger auf das Ende gesett und wenn du dann die Datei schleißt, wird natürlich der komplette Cluster neu beschrieben und womöglich noch ein Annpassung im Volume Bitmap und dann auch noch die Anpassung der Dateigröße und des Änderungsdatums im Verteichnis und womöglich auch noch in allen übergeordneten Verzeichnissen. (Letzteres wurde in Windows 7 mal abgeschafft, vermutlich zum Zeitgewinn und in Hinblick auf SSDs)

Wie stabil läuft denn das System und wie wichtig sind die geloggten Daten?
Erstmal die Datei nicht ständig öffnen/schließen, dann auf Streams ausweichen, welche keine eigene Cache implementieren, so wie so alten Dateifunktionen, womit dann beim Absturz des Programms keine Daten verloren gehen.
Je nach Schreibverhalten und Speicherauslastung werden hier, über die WindowsFileCache, wenn man die Datei nicht ständig schließt, auch die physischen Dateiuzugriffe verringert.

Oder wenn das Schreiben nicht so wichtig ist, dann mit einer größeren eigenen Cache zwischenspeichern und die Dateizugriffe minimieren.

Sind die Daten ganz wichtig, dann müßte man sogar noch die Schreibcache vom Windows und des Datenträgers ausschalten, was aber die realen Zugriffe noch erhöht.

rhuber 11. Sep 2012 12:50

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Vielen Dank für eure Antworten!!!

Das mit dem Schreibcache hab ich gar nicht überlegt; FileMon (zur Überwachung der CF-Zugriffe) loggt ziemlich sicher nur die Datei APIs und nicht die realen Zugriffe...

Das System läuft extrem stabil (im Labor seit über einem Jahr), startet sich jeweils um Mitternacht selbst neu und schreibt die Logfiles des letzten Tages auf einen USB-Stick.
Es ist nicht tragisch wenn mal ein Tag verloren geht, viel wichtiger ist dass das System nicht hängen bleibt (was es aber im Falle eines CF-Defekts tut,dann hängt nämlich mein AutoReboot-Tool ->gemacht mit ExitWindowsEx,gibts da eine "Hardcore-Variante"?).

Nun, ich kenne mich leider mit den Datei APIs nicht sehr gut aus; gibts eine einfache Alternative zu "WriteLn()", mit welcher vorerst noch nichts geschrieben wird? Also zuerst nur in den RAM speichern und erst später die Änderungen schreiben,ohne zuviel am Code ändern zu müssen?

Klaus01 11. Sep 2012 12:57

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Zitat:

Zitat von rhuber (Beitrag 1182486)
gibts eine einfache Alternative zu "WriteLn()", mit welcher vorerst noch nichts geschrieben wird? Also zuerst nur in den RAM speichern und erst später die Änderungen schreiben,ohne zuviel am Code ändern zu müssen?

.. die TStringList
mit der Methode saveToFile zu speichern.

Die LogDaten im ram zu halten nützt natürlich nichts, wenn das Programm abstürzt.


nicht schön ...
Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, classes;
var
  sl : TStringList;

procedure writeLn(s: ansiString);
begin
  sl.add(s);
end;

begin

  { TODO -oUser -cConsole Main : Insert code here }

  sl := TStringList.Create;
  try
    writeLn('test');
    sl.SaveToFile('filePath+fileName');
  finally
    sl.Free;
  end;
end.
:wink:
Grüße
Klaus

Medium 11. Sep 2012 13:28

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
In dem Fall würde ich auch fast sagen: Logs in StringListen, und speichern bei Programmende, Ausnahmefehlern die sich früh genug abfischen lassen und zu einem definierten Zeitpunkt. Und zwar direkt auf den Stick, dann ist die CF Karte überhaupt nicht mehr an Bord.
Hat natürlich den Nachteil, dass Logs flöten gehen, wenn mal einer mutwillig den Stecker zieht, aber die Hardware lässt an der Stelle dann einfach nicht arg viel Spiel für Datensicherheit. Im Zweifel könnte man noch an einen externen DB Server denken, der dann z.B. via WLAN alles schön in Tabellen speichert.

divBy0 11. Sep 2012 13:39

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Es ist ja auch möglich die Stringlist alle 2 Stunden oder so mal zu speichern.

p80286 11. Sep 2012 13:53

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Gibt's keine interne Festplatte?
von da täglich, alle 6Stunden.. auf Stick/CF-Card sichern?

oder vllt eine USB-Festplatte?

Gruß
K-H

himitsu 11. Sep 2012 14:14

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Ich denkie mal das ist eine Preis-, Platz- und vorallem Energiefrage.

CF-Karte als Ersatz für HDDs sind schon seit langem bekannt ... praktisch der Vorgänger der SSDs.

hathor 11. Sep 2012 14:22

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Lösung: RAM-DISK
Nur 1x täglich auf Flash-Speicher schreiben.

shmia 11. Sep 2012 15:11

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Die "richtige" Methode ist wenn man die Datei zum Schreiben öffnet, mit Seek ans Ende geht und dort weiterschreibt.
Was man vermeiden sollte ist den alten Inhalt in eine Stringliste einzulesen, dann Daten anhängen und den gesamten Inhalt wegzuschreiben.
Mit dieser falsche Methode würde man alle Daten, die man bisher geschrieben hat nochmals schreiben (nicht gut für die CF).

Ich habe mal auf die Schnelle eine Hilfsklasse geschrieben, mit der man es besser machen kann.

Delphi-Quellcode:
type
   // Mit dieser Klasse kann man Daten an eine bestehende Datei anhängen
   TAppendFileWriter = class(TObject)
   private
     FStream : TFileStream;
     FFilename : string;
     function GetFilesize: Int64;
   public
     constructor Create(const filename:string);
     destructor Destroy;override;

     procedure WriteString(const s : String);
     procedure WriteLine(const line:string);
     function Flush:Boolean;

     property Filename:string read FFilename;
     property Filesize:Int64 read GetFilesize;
   end;



{ TAppendFileWriter }

constructor TAppendFileWriter.Create(const filename: string);
begin
  inherited Create;
  FStream := TFileStream.Create(filename, fmOpenReadWrite or fmShareDenyWrite);
  FStream.Seek(0, soFromEnd);
end;

destructor TAppendFileWriter.Destroy;
begin
   FStream.Free;
   inherited;
end;

procedure TAppendFileWriter.WriteString(const s: String);
begin
   if s <> '' then
      FStream.WriteBuffer(s[1], Length(s));
end;

procedure TAppendFileWriter.WriteLine(const line: string);
begin
   WriteString(line+#13#10);
end;



function TAppendFileWriter.GetFilesize: Int64;
begin
   Result := FStream.Size;
end;


// Daten sicher schreiben
procedure TAppendFileWriter.Flush;
begin
   if not FlushFileBuffers(FStream.Handle) then
      RaiseLastWin32Error;
end;

rhuber 11. Sep 2012 15:34

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Wow, das ist ja super,besten Dank für eure Vorschläge!!!

Genau, der Embedded-PC braucht im Betrieb mit Win2k nur ca. 2 Watt. Da ich auch auf bewegte Teile verzichten wollte, läuft alles über eine Interne CF-Karte. Das Ganze soll mindestens 2 Jahre ohne Eingriffe (Tastatur,Monitor usw. gibts nicht) betrieben werden, lediglich der USB-Stick wird monatlich gewechselt. Immer nach dem Neustart um Mitternacht werde die Log-Files von der internen CF-Karte auf den USB-Stick kopiert.

Hab jetzt mal eine RAM-Disk gemacht, sollte ja den selben Effekt haben wie eine StringList.

Meine Speichervariante:
Code:
If FileExists(fileName) Then Begin //fileName=.csv-File des aktuellen Tages
   try
     AssignFile(TxtFile, fileName); //.csv-File Laden
     Append(TxtFile);
     WriteLn(TxtFile,messwerte);  //Neue Zeile mit Messwerte in Logfile hinzufügen (ca.300 Zeichen)
     CloseFile(TxtFile);
Ist wohl nicht gerade optimal,richtig? Ich werd auch mal versuchen die vorgeschlagene Klasse einzubauen. Kenn mich mit der Materie leider noch nicht so aus...

Gruss Roman

taveuni 11. Sep 2012 15:38

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Zitat:

Zitat von rhuber (Beitrag 1182514)
Immer nach dem Neustart um Mitternacht werde die Log-Files von der internen CF-Karte auf den USB-Stick kopiert.

Weshalb schreibst Du nicht direkt zyklisch auf den USB Stick?

Uwe Raabe 11. Sep 2012 15:41

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Bei neueren Delphi-Versionen kann man auch was aus IOUtils.pas nutzen:

Delphi-Quellcode:
class procedure TFile.AppendAllText(const Path, Contents: string; const Encoding: TEncoding);
class function TFile.AppendText(const Path: string): TStreamWriter;

rhuber 11. Sep 2012 15:49

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Zitat:

Zitat von taveuni (Beitrag 1182517)
Weshalb schreibst Du nicht direkt zyklisch auf den USB Stick?

Weil man den USB-Stick jederzeit entfernen können muss. Er wird automatisch abgemeldet, sobald nach dem täglichen Neustart die Logfiles des vergangenen Tages von der CF-Karte auf den Stick kopiert wurden.
Zudem haben die Sticks MLC-Speicherzellen, deshalb möchte ich möglichst wenig drauf scheiben...

Der interne (CF-Karte) Speicher dient natürlich auch als Backup, falls mal kein Stick drin ist.

Zitat:

Zitat von Uwe Raabe (Beitrag 1182519)
Bei neueren Delphi-Versionen kann man auch was aus IOUtils.pas nutzen:

Ok, muss mal schauen ob Delphi 7 schon zu den "neueneren" Versionen zählt ;-)

Also wenn ich's jetzt hinkriege, dass der Inhalt der Ram-Disk kurz VOR dem Neustart auf die CF-Karte und den USB-Stick kopiert werden, ist mein Problem ja schon gelöst :thumb:

Gruss Roman

himitsu 11. Sep 2012 20:57

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Tipp: Man kann in seinem Profil angeben, was man benutzt, damit Andere ihre Antworten/Lösungen entsprechend ausrichten können.

Nja, es kommt halt drauf an, wieviele Zugriffe man einsparen will.

- Du kannst natürlich mit der RAM-Disk arbeiten, aber wenn es jetzt nur für diese CSV-Dateien sein soll, dann könnte man auch die Dateizugriffe selber anpassen.

- Du kannst weiterhin die alten Pascalfunktionen belassen, solltest aber nicht ständig die Datei öffnen und schließen
und solltest vorallem das Caching dieser Funktionen verbessern. (128 Byte sind pervers ... mindestens Clustergröße oder besser noch das Mehrfache davhon, wäre schon besser und würde ein Vielfaches der Zugriffe einsparen)

Furtbichler 11. Sep 2012 21:13

AW: Delphi Datenlogger zerstört CompactFlash (CF) Karten
 
Wir loggen in einer SPS unter WXP 5x pro Sekunde in CSV-Dateien. Der Zugriff erfolgt innerhalb der SPS (ca. 50MB pro Tag). Parallel läuft ein Delphi-Programm, das ca. 1x pro Sekunde Daten in eine Log-Datei schreibt.

Mir sind keine Ausfälle der CF Karten (ca. 300 Anwendungen) bekannt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:28 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz