Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

File.Write auf RAMDisk funktioniert nur 1x

blaggejoe
2016-06-04
2016-06-10
  • blaggejoe - 2016-06-04

    Hi

    Mit folgendem Programm schreibe ich jeweils die Datei "Zeiten.txt" auf eine RAMDisk des Raspi:

    PROGRAM Datei
    VAR
       xFileStdInit:       BOOL:=FALSE;
            uiFileStdState:     UINT:=0;
            sFileName:          CAA.FILENAME:= '/mnt/RAMDisk/Zeiten.txt';
            hFile:              CAA.HANDLE;
            sFileString:        STRING;
            szFileSize1:        CAA.SIZE := 0;
            szFileSize2:        CAA.SIZE := 0;
            filop:              File.Open;
            filwr:              File.Write;
            filfl:            File.Flush;
            filcl:              File.Close;
            filsp:              File.SetPos;
    END_VAR
    IF NOT xFileStdInit THEN
        filop(xExecute:=FALSE);
        filcl(xExecute:=FALSE);
        filwr(xExecute:=FALSE);
        filfl(xExecute:=FALSE);
        xFileStdInit:=TRUE;
        uiFileStdState:=0;
    ELSE
        CASE uiFileStdState OF
          0: (* Wait to start *)
             IF GVL.xFileSchreiben THEN
                (* String füllen mit 10 Zeiten *)
                sFileString := '123, 345';
                 uiFileStdState := 1;
             END_IF
            1:(* create a new file *)
                filop.sFileName:=sFileName;
                filop.eFileMode:=File.MODE.MWRITE;
                filop.xExclusive:=TRUE;
                filop( xExecute:=TRUE);
                IF filop.xDone  THEN
                    hFile:=filop.hFile;
                    uiFileStdState:=2;
                END_IF
                IF filop.xError THEN
                    (* error handling*)
                    ;
                END_IF
            2:(* write text in the file *)
                filwr.hFile:=hFile;
                filwr.pBuffer:=ADR(sFileString);
                szFileSize1:=SIZEOF(sFileString);
                filwr.szSize:=szFileSize1;
                filwr.udiTimeOut:=100000;    (* 100ms Timeout *)
                filwr( xExecute:=TRUE);
                IF filwr.xDone THEN
                    uiFileStdState:=3;
                END_IF
                IF filwr.xError THEN
                    (* error handling*)
                    ;
                END_IF
          3: (* Daten SICHER auf Festplatte schreiben *)
             filfl.hFile := hFile;
             filfl(xExecute:=TRUE);
             IF filfl.xDone THEN
                    uiFileStdState:=4;
                END_IF
                IF filfl.xError THEN
                    (* error handling*)
                    ;
                END_IF      
            4:(* close file  - TestFile.txt *)
                filcl.hFile:=hFile;
                filcl( xExecute:=TRUE);
                IF filcl.xDone THEN
                    uiFileStdState:=5;
                END_IF
                IF filcl.xError THEN
                    (* error handling*)
                    ;
                END_IF
          
          5: (* Warten auf Signal low *)
          IF GVL.xFileSchreiben=FALSE THEN
              uiFileStdState:=0;
          END_IF
        END_CASE
    END_IF
     
    

    Das funktioniert jeweils nach Neustart der SPS 1x.
    Wenn ich nun die Datei mit root-Rechten lösche im Raspberry und sie erneut schreibe (xFileSchreiben auf FALSE und wieder auf TRUE) wird die Statemachine zwar durchlaufen, aber die Datei nicht erneut geschrieben. Es werden aber alle States ohne Fehler durchlaufen.
    Ich habe auch extra die File.Flush eingebaut, um allfälligen Dateisystemfunktionen aus dem Weg zu gehen.

    Weiss da jemand Rat?

    Merci
    Ralf

     
  • blaggejoe - 2016-06-05

    Ich habs selbst gefunden:
    die

    filop(xExecute:=FALSE);
    filcl(xExecute:=FALSE);
    filwr(xExecute:=FALSE);
    filfl(xExecute:=FALSE);
    

    müssen natürlich bei jedem Durchgang neu gesetzt werden, nicht nur nach Neustart...

    Cheers
    Ralf

     
  • blaggejoe - 2016-06-10

    Ãœbrigens, was mit noch aufgefallen ist - im Beispiel hats noch einen Fehler drin:
    Die Länge des zu schreibenden String sollte nicht mittels

    szFileSize1:=SIZEOF(sFileString);
    

    sondern mittels

    szFileSize1:=LEN(sFileString);
    

    ermittelt werden. Spätestens wenn z.B. $n$r geschrieben wird, stimmt die Anzahl der Zeichen sonst nicht mehr.

    Cherrs Ralf

     

Log in to post a comment.