FB_SoEAX5000FirmwareUpdate_ByDriveRef

FB_SoEAX5000FirmwareUpdate_ByDriveRef 1:

The functionblock FB_SoEAX5000FirmwareUpdate_ByDriveRef can be used to check and update the firmware of the AX5000 to a requested version (revision and build) or to the newest build of the configured revision.  

In order to update the following sequence is executed:
- get configured slave type, i.e. AX5103-0000-0010
- get scanned slave type for the slave address, i.e. AX5103-0000-0009
- get current slave firmware, i.e. v1.05_b0009
- compare configured and scanned slave (number of channels, current, revision, firmware)
- create firmware files name and search for the file
- update firmware (if required)
- rescan slave
- switch the slave to the requested EtherCAT state

A successful updatefinishes witheFwUpdateState = eFwU_FwUpdateDone. If the update is not required, then the state returns eFwUpdateState = eFwU_NoFwUpdateRequired. The firmware update is executed via the channel of the drive (A=0 or B=1) set in stDriveRef. With two channel devices, the firmware update can only be executed via one of the channels. The other channel signalseFwUpdateState = eFwU_UpdateViaOtherChannelActive or = eFwU_UpdateViaOtherChannel.

During the firmware update (eFwUpdateState = eFwU_FwUpdateInProgress) the update progress is reported viaiLoadProgress in percent.

During the update the PLC and TwinCAT have to stay in RUN mode, the EtherCAT connection must be maintained and the AX5000 must stay powered up!

VAR_INPUT

VAR_INPUT
   stDriveRef       : ST_DriveRef; 
   bExecute         : BOOL;    
   tTimeout         : TIME := DEFAULT_ADS_TIMEOUT;
   sFirmwareVersion : STRING(20);  (* version string vx_yy_bnnnn, e.g. "v1.05_b0009" for v1.05 Build 0009 *)
   sFirmwarePath    : T_MaxString; (* drive:\path, e.g. "C:\TwinCAT\Io\TcDriveManager\FirmwarePool" *)
   sNetIdIPC        : T_AmsNetId;
   iReqEcState      : UINT := EC_DEVICE_STATE_OP;
END_VAR

stDriveRef: The drive reference can be linked in the System Manager between PLC and drive. The link can be done to an instance of the ST_PlcDriveRef. The structure ST_PlcDriveRef contains the NetID as byte array. The byte array can be converted to a string. See ST_DriveRef.

bExecute: The block is activated by a rising edge at this input.

tTimeout: The firmware update can take a few minutes, the timeout here defines the timeout for internal ADS instances.

sFirmwareVersion: The required firmware version in form of vx.yy_bnnnn, i.e. "v1.05_b0009" for version v1.05 build 0009.

    Release builds:
        "v1.05_b0009"     for specific build, i.e. v1.05 Build 0009
        "v1.05_b00??"     newstest build of a version, i.e. v1.05
        "v1.??_b00??"     newstest build of a major version, i.e. v1
        "v?.??_b00??"     newstest version and newstest build
        ""                              newstest version and newstest build

    Customer specific firmware builds:
        "v1.05_b1009"     for specific build, i.e. v1.05 Build 1009
        "v1.05_b10??"     newstest build of a version, i.e. v1.05
        "v1.??_b10??"     newstest build of a major version, i.e. v1
        "v?.??_b10??"     newstest version and newstest build
        ...

        "v1.05_b8909"     for specific build, i.e. v1.05 Build 8909
        "v1.05_b89??"     newstest build of a version, i.e. v1.05
        "v1.??_b89??"     newstest build of a major version, i.e. v1
        "v?.??_b89??"     newstest version and newstest build

    Debug builds:
        "v1.05_b9009"     for specific build, i.e. v1.05 Build 9009
        "v1.05_b90??"     newstest build of a version, i.e. v1.05
        "v1.??_b90??"     newstest build of a major version, i.e. v1
        "v?.??_b90??"     newstest version and newstest build
 

sFirmwarePath: The path for the firmware pool, where the firmware files are located, i.e. "C:\TwinCAT\Io\TcDriveManager\FirmwarePool".

sNetIdIPC: AMS-NetID of the controller (IPC).

iReqEcState: Requested EtherCAT state after the update (only if an update is executed). The states are defined in the TcEtherCAT.lib as globale constants.

VAR_OUTPUT

VAR_OUTPUT
   bBusy                 : BOOL;
   bError                : BOOL;
   iAdsErrId             : UINT;
   iSercosErrId          : UINT;
   iDiagNumber           : UDINT;
   eFwUpdateState        : E_FwUpdateState;
   iLoadProgress         : INT;
   sSelectedFirmwareFile : STRING(MAX_STRING_LENGTH); (* found firmware file, e.g. "AX5yxx_xxxx_0010_v1_05_b0009.efw" *)
END_VAR

bBusy: This output is set when the function block is activated, and remains set until an acknowledgement is received.

bError: This output is set up after the bBusy output has been reset if there has been an error in transmission of the command.

iAdsErrId: Supplies the ADS error code associated with the most recently executed command if the bError output is set.

iSercosErrId: Supplies the Sercos error code associated with the most recently executed command if the bError output is set.

iDiagNumber: Supplies the drive error code associated with the most recently firmware update if the bError output is set.

eFwUpdateState: Supplies the status of the firmware update. See E_FwUpdateState.

iLoadProgress: Supplies the progress of the firmware load in percent.

sSelectedFirmwareFile: Supplies the name of the searched firmware file.

Sample

VAR CONSTANT
   iNumOfDrives         : INT := 2;
END_VAR
VAR
   bInit                : ARRAY [1..iNumOfDrives] OF BOOL := 2(TRUE);
    fbFirmwareUpdate     : ARRAY [1..iNumOfDrives] OF FB_SoEAX5000FirmwareUpdate_ByDriveRef;

    stPlcDriveRef AT %I* : ARRAY [1..iNumOfDrives] OF ST_PlcDriveRef;
   stDriveRef            : ARRAY [1..iNumOfDrives] OF ST_DriveRef;
    sFirmwareVersion     : ARRAY [1..iNumOfDrives] OF STRING(20) := 2('v1.05_b0009');
   eFwUpdateState       : ARRAY [1..iNumOfDrives] OF E_FwUpdateState;
    sSelectedFirmwareFile: ARRAY [1..iNumOfDrives] OF STRING(MAX_STRING_LENGTH);
   
   iUpdateState         :INT;
   bExecute             : BOOL;
   sNetIdIPC            : T_AmsNetId := '';
   sFirmwarePath        : T_MaxString := 'C:\TwinCAT\Io\TcDriveManager\FirmwarePool';

   I                    : INT;
   bAnyInit             : BOOL;
   bAnyBusy             : BOOL;
   bAnyError            : BOOL;
END_VAR
CASE iUpdateState OF
0:
    bAnyInit := FALSE;
    FOR I := 1 TO iNumOfDrives DO
        IF bInit[I] THEN
           bAnyInit := TRUE;
           stDriveRef[I].sNetId     := F_CreateAmsNetId(stPlcDriveRef[I].aNetId);
           stDriveRef[I].nSlaveAddr := stPlcDriveRef[I].nSlaveAddr;
           stDriveRef[I].nDriveNo   := stPlcDriveRef[I].nDriveNo;

           stDriveRef[I].nDriveType := stPlcDriveRef[I].nDriveType;
           IF (stDriveRef[I].sNetId <> '') AND (stDriveRef[I].nSlaveAddr <> 0) THEN
               bInit[I] := FALSE;
           END_IF
        END_IF
    END_FOR

    IF NOT bAnyInit AND bExecute THEN
        iUpdateState := 1;
    END_IF   

1:
    FOR I := 1 TO iNumOfDrives DO
       fbFirmwareUpdate[I](
           stDriveRef       := stDriveRef[I],
           bExecute         := TRUE,
           tTimeout         :=
T#15s,

           sFirmwareVersion := sFirmwareVersion[I],
           sFirmwarePath    := sFirmwarePath,
           sNetIdIPC        := sNetIdIPC,
           iReqEcState      := EC_DEVICE_STATE_OP,
           eFwUpdateState   => eFwUpdateState[I],
        );
    END_FOR

    iUpdateState := 2;

2:
    bAnyBusy := FALSE;
    bAnyError:= FALSE;
    FOR I := 1 TO iNumOfDrives DO
       fbFirmwareUpdate[I](
           Axis := stNcToPlc[I],
           eFwUpdateState => eFwUpdateState[I],
           sSelectedFirmwareFile => sSelectedFirmwareFile[I],
        );
        IF NOT fbFirmwareUpdate[I].bBusy THEN
           fbFirmwareUpdate[I](bExecute := FALSE, Axis := stNcToPlc[I]);
           IF fbFirmwareUpdate[I].bError THEN
               bAnyError := TRUE;
           END_IF
        ELSE
           bAnyBusy := TRUE;
        END_IF
    END_FOR

    IF NOT bAnyBusy THEN
        bExecute := FALSE;

        IF NOT bAnyError THEN
           iUpdateState := 0; (* OK *)
        ELSE
           iUpdateState := 3; (* Error *)
        END_IF
    END_IF
3:
    (* Error handling *)
    iUpdateState := 0;

END_CASE