simotion读写CF卡,保存/读取变量

simotion读写CF卡功能

1

使用西门子的Simotion运动控制器时,有时需要用到 读/写 CF卡的功能。主要来自以下几个方面的需求。

1)用户数据量较大,可保持(retain)存储区的容量不够(D435-2 为 384K),需要将数据写入CF卡。
2)在极其罕见的情况下,例如在启动过程中出现断电,可保持(retain)存储区的数据可能丢失。用户希望在CF卡中对数据进行备份

2

为了方便实现以上需求,在标准库的基础上,编写了两个FB块。

  • FB_VariablesStorageHandling 保存和读取单个unit中的变量的
  • FB_SaveRestoreMultiUnit 保存和读取多个unit中的变量

上述两个FB块中使用了系统函数_exportUnitDataSet_importUnitDataSet

什么是unit?
unit是simotion中的一个编程单元。
一个unit中可以通过var_global定义多组全局变量。一个unit中,也可以定义和实现多个程序、FB、FB。

3

保存后的文件,路径在CF卡的 /USER/SIMOTION/USER_DIR/UPP/UNITDS

4

FB_VariablesStorageHandling的接口描述

name type data type function
boEnable in bool 激活程序
in_boResetError in bool 复位故障和内部变量
in_String_UnitName in string unit名称
in_KindofData in EnumDeviceKindOfData 数据类型
in_out_boSavetoCFCard in_out bool 命令,保存数据到CF卡
in_out_boReadFromCFCard in_out bool 命令,从CF卡读取数据
out_boSaveOK out bool 保存完成
out_boReadOK out bool 读取完成
out_boSaveFail out bool 保存失败
out_boReadFail out bool 读取失败
out_boUnitNotExist out bool unit不存在

枚举类型EnumDeviceKindOfData

  • NO_RETAIN_GLOBAL unit中的非可保持变量
  • _RETAIN unit中的可保持变量
  • ALL_GLOBAL unit中的所有全局变量

FB_SaveRestoreMultiUnit的接口描述

name type data type function
In_unitName xx in string unit名称
In_saveDat in bool 命令,保存数据到CF卡
In_readData in bool 命令,从CF卡读取数据
In_reset in bool 复位程序内部状态和故障
save_OK in_out bool 保存完成
save_Fail in_out bool 保存失败
read_OK in_out bool 读取完成
read_Fail in_out bool 读取失败

5

如果你需要使用此程序,可以使用以下代码

INTERFACE
    FUNCTION_BLOCK FB_VariablesStorageHandling;
    FUNCTION_BLOCK FB_SaveRestoreMultiUnit;
END_INTERFACE

IMPLEMENTATION

    FUNCTION_BLOCK FB_VariablesStorageHandling
    //--------------------------------------------------------------------------
    // Siemens SFAE / Beijing, China
    //--------------------------------------------------------------------------
    //functionality:    1)Write an unit data to CF card, memory -> CF card
    //                  2)Read unit data from CF card, CF card -> memory
    //assignment:       background 
    //dependence:       none
    //--------------------------------------------------------------------------
    //change log table:
    //version   date        expert in charge            changes applied
    //01.00.00  2016        xxxx                   Created
    //==========================================================================
    
        VAR_INPUT
            boEnable                                :BOOL;
            in_boResetError                         :BOOL; 
            in_String_UnitName                      :STRING;
            in_KindofData                           :EnumDeviceKindOfData;
        END_VAR
    
        VAR_IN_OUT
            in_out_boSavetoCFCard                   :BOOL;
            in_out_boReadFromCFCard                 :BOOL;
        END_VAR
        
        VAR_OUTPUT
            boBusy                                  : BOOL;
            boError                                 : BOOL;
            ErrorID                                 : UINT;
            out_boSaveOK                            : BOOL;
            out_boReadOK                            : BOOL;
            out_boSaveFail                          : BOOL;
            out_boReadFail                          : BOOL;
            out_boUnitNotExist                      : BOOL;
        END_VAR
        
        VAR
            i16SaveReadStep                         : INT;
            old_boSavetoCFCard                      : BOOL;
            old_boReadFromCFCard                    : BOOL;
            myRetStructRetUnitDataSetCommand        :StructRetUnitDataSetCommand;
            myRetEnumDeviceUnitDataSetCommand       :EnumDeviceUnitDataSetCommand;
        END_VAR
        
        
        IF boEnable=TRUE THEN
            
            boBusy  := TRUE;
           
            //Error Reset
            IF in_boResetError THEN
                out_boSaveOK := FALSE;
                out_boReadOK := FALSE;
                
                out_boSaveFail := FALSE;
                out_boReadFail := FALSE;
                boError:=FALSE; 
                ErrorID:=0;
                in_out_boSavetoCFCard    := FALSE;
                in_out_boReadFromCFCard  := FALSE;
                i16SaveReadStep := 0;
            END_IF;
            
            //save to CF Card
            IF in_out_boSavetoCFCard=TRUE
                AND old_boSavetoCFCard<>in_out_boSavetoCFCard THEN
                i16SaveReadStep := 10;
                out_boSaveOK := FALSE;
                out_boSaveFail := FALSE;
            END_IF;
            old_boSavetoCFCard := in_out_boSavetoCFCard;
            
            //Read From CF Card
            IF in_out_boReadFromCFCard=TRUE
                AND old_boReadFromCFCard<>in_out_boReadFromCFCard THEN
                i16SaveReadStep := 100;
                out_boReadOK := FALSE;
                out_boReadFail := FALSE;
                out_boUnitNotExist := FALSE;
            END_IF;
            old_boReadFromCFCard := in_out_boReadFromCFCard;
            
            CASE i16SaveReadStep OF
                10://Save Unite Dataset to CF card
                    myRetStructRetUnitDataSetCommand := _exportUnitDataSet(
                        unitName := in_String_UnitName
                        ,id :=1 
                        ,storageType :=PERMANENT_STORAGE  
                        // ,path := ''
                        ,overwrite := TRUE
                        ,nextCommand := IMMEDIATELY
                        ,dataScope := _INTERFACE
                        ,kindOfData := in_KindofData
                    );
                    i16SaveReadStep:=20;
                
                
                20://wait for save finish
                    myRetEnumDeviceUnitDataSetCommand :=
                    _getStateOfUnitDataSetCommand(handle :=myRetStructRetUnitDataSetCommand.handle);
                    IF myRetEnumDeviceUnitDataSetCommand<>done AND myRetEnumDeviceUnitDataSetCommand<>active THEN
                        i16SaveReadStep:=190;//Error
                        out_boSaveFail := TRUE;
                    ELSIF myRetEnumDeviceUnitDataSetCommand=done THEN
                        out_boSaveOK := TRUE;
                        i16SaveReadStep:=200;
                    END_IF; 

                
                100://Check Unit Dataset exist or not
                    myRetStructRetUnitDataSetCommand := _checkExistingUnitDataSet(
                        unitName :=in_String_UnitName
                        ,id :=1 
                        ,storageType :=PERMANENT_STORAGE 
                        // ,path := ''
                        ,nextCommand := IMMEDIATELY
                    );
                    i16SaveReadStep:=110;
                
                
                110://wait for check finish
                    myRetEnumDeviceUnitDataSetCommand :=
                    _getStateOfUnitDataSetCommand(handle :=myRetStructRetUnitDataSetCommand.handle);
                    IF myRetEnumDeviceUnitDataSetCommand<>done AND myRetEnumDeviceUnitDataSetCommand<>active THEN
                        out_boUnitNotExist := TRUE;
                        i16SaveReadStep:=190;//Error
                        out_boReadFail := TRUE;
                    ELSIF myRetEnumDeviceUnitDataSetCommand=done THEN 
                        i16SaveReadStep:=120;               
                    END_IF;
                
                120://Read Unit Dataset from CF card
                    myRetStructRetUnitDataSetCommand := _importUnitDataSet( //_loadUnitDataSet(
                        unitName :=in_String_UnitName 
                        ,id :=1 
                        ,storageType :=PERMANENT_STORAGE  
                        // ,path := ''
                        ,nextCommand := IMMEDIATELY
                        ,dataScope := _INTERFACE
                        ,kindOfData := in_KindofData
                    );
                    i16SaveReadStep:=130;
                
                130://Read finish
                    myRetEnumDeviceUnitDataSetCommand :=
                    _getStateOfUnitDataSetCommand(handle :=myRetStructRetUnitDataSetCommand.handle);
                    IF myRetEnumDeviceUnitDataSetCommand<>done AND myRetEnumDeviceUnitDataSetCommand<>active THEN
                        i16SaveReadStep:=190;
                        out_boReadFail := TRUE;
                    ELSIF myRetEnumDeviceUnitDataSetCommand=done THEN 
                        out_boReadOK := TRUE;
                        i16SaveReadStep:=200;
                    END_IF;
                
                190://Save or Read Error
                    boError     := TRUE; 
                
                200://Check Finish
                    in_out_boSavetoCFCard    := FALSE;
                    in_out_boReadFromCFCard  := FALSE;    
                
            END_CASE;
            
        ELSE
            boBusy  :=FALSE;
        END_IF;
  
    END_FUNCTION_BLOCK 
 
    FUNCTION_BLOCK FB_SaveRestoreMultiUnit
    //--------------------------------------------------------------------------
    // Siemens SFAE / Beijing, China
    //--------------------------------------------------------------------------
    //functionality:    1)Write several unit data to CF card, memory -> CF card
    //                  2)Read several unit data from CF card, CF card -> memory
    //assignment:       background 
    //dependence:       "FB_VariablesStorageHandling"
    //--------------------------------------------------------------------------
    //change log table:
    //version   date        expert in charge            changes applied
    //01.00.00  17-11-2017  Zhenglei                    Created
    //
    //==========================================================================
    
        VAR_INPUT
            In_unitName1    :STRING := 'empty';
            In_unitName2    :STRING := 'empty';
            In_unitName3    :STRING := 'empty';
            In_unitName4    :STRING := 'empty';
            In_unitName5    :STRING := 'empty';
            In_unitName6    :STRING := 'empty';
            In_unitName7    :STRING := 'empty';
            In_unitName8    :STRING := 'empty';
            In_saveData     :BOOL;
            In_readData     :BOOL;
            In_reset        : BOOL;
        END_VAR
        
        VAR_IN_OUT
            save_OK     :BOOL;
            save_Fail   :BOOL;
            read_OK     :BOOL;
            read_Fail   :BOOL;
        END_VAR
            
            
        VAR
            unitName            : ARRAY[1..8] OF STRING;
            bo_saving,bo_reading          : BOOL;
            rtrig_save,rtrig_read : R_TRIG;
            bo_SavetoCFCard     : ARRAY[1..8] OF BOOL;
            bo_ReadFromCFCard   : ARRAY[1..8] OF BOOL;
            SavetoCFCard_OK     : ARRAY[1..8] OF BOOL;
            ReadFromCFCard_OK   : ARRAY[1..8] OF BOOL;
            SavetoCFCard_Fail   : ARRAY[1..8] OF BOOL;
            ReadFromCFCard_Fail : ARRAY[1..8] OF BOOL;
            UnitNotExist        : ARRAY[1..8] OF BOOL;
            i,J,K    : INT;
            inst_FB_VariablesStorage :ARRAY[1..8] OF FB_VariablesStorageHandling;
        END_VAR
        
        
        unitName[1]:= In_unitName1; unitName[2]:= In_unitName2;
        unitName[3]:= In_unitName3; unitName[4]:= In_unitName4;
        unitName[5]:= In_unitName5; unitName[6]:= In_unitName6;
        unitName[7]:= In_unitName7; unitName[8]:= In_unitName8;
        
        rtrig_save(In_saveData);
        rtrig_read(In_readData);
        
        IF rtrig_save.q AND unitName[1] <> 'empty' THEN
            bo_saving:= TRUE; J:=1;
        END_IF;
        
        IF rtrig_read.q AND NOT bo_saving THEN
            bo_reading := TRUE; K:=1;
        END_IF;
        
        //cyclic operation
        FOR i:= 1 TO 8 DO
            inst_FB_VariablesStorage[i](
                boEnable := TRUE 
                ,in_boResetError := in_reset
                ,in_String_UnitName := unitName[i]
                ,in_KindofData :=  _RETAIN 
                ,in_out_boSavetoCFCard := bo_SavetoCFCard[i]
                ,in_out_boReadFromCFCard := bo_ReadFromCFCard[i] 
                ,out_boSaveOK => SavetoCFCard_OK[i]
                ,out_boReadOK => ReadFromCFCard_OK[i]
                ,out_boSaveFail => SavetoCFCard_Fail[i]    
                ,out_boReadFail => ReadFromCFCard_Fail[i]                     
                ,out_boUnitNotExist => UnitNotExist[i] 
            );
                
            IF rtrig_save.q OR rtrig_read.q THEN
                //reset commands
                bo_SavetoCFCard[i]     := FALSE;
                bo_ReadFromCFCard[i]   := FALSE;
                //reset status
                SavetoCFCard_OK[i]     := FALSE;
                ReadFromCFCard_OK[i]   := FALSE;
                SavetoCFCard_Fail[i]   := FALSE;
                ReadFromCFCard_Fail[i] := FALSE;
                UnitNotExist[i]        := FALSE;
            END_IF;
        END_FOR;
        
        //write several unit data to CF card
        IF bo_saving THEN
            bo_SavetoCFCard[J] := TRUE;
            IF J < 8 AND J > 0 THEN//not last "unit"
                IF SavetoCFCard_OK[J] AND unitName[J + 1] <> 'empty' THEN
                    J := J + 1;//next "unit"
                ELSIF SavetoCFCard_OK[J] AND unitName[J + 1] = 'empty' THEN
                    //finish
                    Save_OK := TRUE;save_Fail:= FALSE;
                    bo_saving := FALSE;
                END_IF;
                
                IF SavetoCFCard_Fail[J] OR UnitNotExist[J] THEN
                    //error
                    Save_OK := FALSE; save_Fail:= TRUE;
                    bo_saving := FALSE;
                END_IF;
            ELSIF J = 8 THEN //last "unit"
                IF SavetoCFCard_OK[J] THEN
                    //finish
                    Save_OK := TRUE;save_Fail:= FALSE;
                    bo_saving := FALSE;
                END_IF;
                
                IF SavetoCFCard_Fail[J] OR UnitNotExist[J] THEN
                    //error
                    Save_OK := FALSE; save_Fail:= TRUE;
                    bo_saving := FALSE;
                END_IF;
            END_IF;
        END_IF;
                
        //read data from CF card to Memory
        IF bo_reading THEN
            bo_ReadFromCFCard[K] := TRUE;
            IF J < 8 AND J > 0 THEN//not last "unit"
                IF ReadFromCFCard_OK[K] AND unitName[K + 1] <> 'empty' THEN
                    K := K + 1;//next "unit"
                ELSIF ReadFromCFCard_OK[K] AND unitName[K + 1] = 'empty' THEN
                    //finish
                    read_OK := TRUE;read_Fail:= FALSE;
                    bo_reading := FALSE;
                END_IF;
                
                IF ReadFromCFCard_Fail[K] THEN
                    //error
                    read_OK := FALSE; read_Fail:= TRUE;
                    bo_reading := FALSE;
                END_IF;
            ELSIF J = 8 THEN //last "unit"
                IF ReadFromCFCard_OK[K] THEN
                    //finish
                    read_OK := TRUE;read_Fail:= FALSE;
                    bo_reading := FALSE;
                END_IF;
                
                IF ReadFromCFCard_Fail[K] THEN
                    //error
                    read_OK := FALSE; read_Fail:= TRUE;
                    bo_reading := FALSE;
                END_IF;
            END_IF;
        END_IF;    
            
    END_FUNCTION_BLOCK
END_IMPLEMENTATION

posted on 2017-11-17 10:39  lion_zheng  阅读(3281)  评论(0编辑  收藏  举报

导航