Search code examples
installationauto-updatetwincattwincat-ads

How to successfully copy files to a slow Beckhoff PLC running WinCE7?


I’m trying to create an automated installer for a PLC that is based on WinCE7 having very slow processor and memory card (CX9020). The installer will run on Windows Server 2019 PC connected to the PLC. To install the new version, I want to copy boot folder content over the existing one and then restart TwinCAT.

I cannot use SMB because Windows Server2019 doesn’t fully support SMB1, and I don’t want to make it less secure by forcing the SMB1. WinCE doesn’t support SMB2 or SMB3. I cannot use built in FTP as it fails to copy large files (timeout) or small empty files.

I know that Beckhoff use ADS protocol for activating configuration and it does copy the boot folder over to the PLC when I use visual studio (VS) to do that. The PC upgrading the PLC should not have VS or the source code for the PLC. Is there a way to do it like Beckhoff and copy the boot folder to the PLC without using VS?

I have tried to change the timeout of the FTP but found no way to do that. But even if I succeed, there are other limitations to FTP.


Solution

  • Beckhoff includes a PowerShell module as part of the TwinCAT installation. Full documentation can be found in this file - Twincat ADS Module

    # Import the TwinCAT ADS module
    $originalpaths = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PSModulePath).PSModulePath
    $newPath = $originalpaths + ';C:\TwinCAT\AdsApi\Powershell'
    Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PSModulePath -Value $newPath
    $env:PSModulePath = [System.Environment]::GetEnvironmentVariable("PSModulePath", "Machine")
    
    # Check if the module was imported
    if (-not (Get-Module TcXaeMgmt -listavailable)) { Throw 'The Twincat ADS module was not found!' }
    

    Then a list of files to be copied must be generated.

    $variant = 'Put your variant here'
    $source = '$PSScriptRoot + "\$variant"'
    $plcFiles = Get-ChildItem -Path $source -Recurse -Force -File
    

    Set the destination paths.

    # Windows 10
    $destination = '\TwinCAT\3.1\Boot'
    # Windows CE
    $destination = '\Hard Disk\TwinCAT\3.1\Boot'
    

    Iterate through the list and copy each file.

     # Upload the files
        foreach ($file in $plcFiles) {
            Copy-AdsFile -Path $file.FullName -SessionId $session.Id -Destination   $file.FullName.Replace($source, $destination) -Force -Upload
        }