ethercat-linux/scripts/tc-dte-activate-run.ps1
Tony Cao 309aaba342 EL6695 8-byte bidirectional exchange with per-byte verification
- 8B PDO config: ULINT-sized payload, no 0x1A01 diag PDO on SM3
  (device rejected SM3=8 with diag assigned: 'size not allowed, min/max 0xa')
- twin_layout_blob_sized(): single 64-bit mapping entry for 8B payloads
- Ticker: per-byte XOR 0x5A transform in 8B mode so TwinCAT can verify
  every byte individually (1KB path unchanged, const-guarded)
- TwinCAT automation scripts: deploy with RPC retry, LinkVariables-based
  whole-array relink (element links only carry 1 byte), ADS watch, diag
- Docs: 8B design, verification methodology, test report
2026-07-27 19:01:05 +08:00

125 lines
4.2 KiB
PowerShell

#Requires -Version 5.1
<#
.SYNOPSIS
Open TwinCAT solution via DTE, ActivateConfiguration + StartRestartTwinCAT, poll for Run.
.DESCRIPTION
Invisible DTE automation path proven in free/activate-and-run.ps1.
#>
param(
[string]$Solution = 'C:\Users\tonycao\work\twincat3-auto-cli\TwinCAT_EL6695_Primary\TwinCATProject1.sln',
[string]$LogFile = 'C:\Users\tonycao\work\twincat3-auto-cli\TwinCAT_EL6695_Primary\Logs\tc-dte-activate-run.log'
)
$ErrorActionPreference = 'Continue'
function Log($m) {
$line = (Get-Date -Format 'yyyy-MM-dd HH:mm:ss') + ' ' + $m
Add-Content -Path $LogFile -Value $line -Encoding utf8 -ErrorAction SilentlyContinue
Write-Host $line
}
New-Item -ItemType Directory -Force -Path (Split-Path $LogFile) | Out-Null
# Load TwinCAT.Ads.dll (same working copy used by tc-ads-readstate)
$adsDll = 'C:\Program Files (x86)\Beckhoff\TwinCAT\3.1\Components\Base\v170\TwinCAT.Ads.dll'
Add-Type -Path $adsDll -ErrorAction SilentlyContinue
function Get-State {
try {
$c = New-Object TwinCAT.Ads.TcAdsClient
$c.Connect('169.254.176.217.1.1', 10000)
$s = $c.ReadState()
$c.Dispose()
return "$($s.AdsState)"
} catch { return "ERR: $($_.Exception.Message)" }
}
function Read-PortState($port) {
try {
$c = New-Object TwinCAT.Ads.TcAdsClient
$c.Connect('169.254.176.217.1.1', $port)
$s = $c.ReadState()
$c.Dispose()
return "$($s.AdsState)"
} catch { return "ERR: $($_.Exception.Message)" }
}
Log '=== tc-dte-activate-run start ==='
Log ("state before: " + (Get-State))
try {
$dte = New-Object -ComObject TcXaeShell.DTE.17.0
} catch {
Log ("DTE 17.0 failed, trying 15.0: " + $_)
$dte = New-Object -ComObject TcXaeShell.DTE.15.0
}
$dte.SuppressUI = $true
$dte.MainWindow.Visible = $false
Log "Opening solution: $Solution"
$dte.Solution.Open($Solution)
for ($i = 1; $i -le 120; $i++) {
Start-Sleep -Seconds 1
if ($dte.Solution.IsOpen) { Log ("IsOpen=True after " + $i + "s"); break }
}
if (-not $dte.Solution.IsOpen) { throw 'Solution did not open' }
Log 'Waiting 40s for project tree ...'
Start-Sleep -Seconds 40
$project = $dte.Solution.Projects.Item(1)
$sm = $project.Object
Log ("SysManager type: " + $sm.GetType().FullName)
try {
$sm.SetTargetNetId('169.254.176.217.1.1')
Log 'SetTargetNetId OK'
} catch { Log ("SetTargetNetId warning: " + $_.Exception.Message) }
# Step 1: ActivateConfiguration
$actOK = $false
for ($a = 1; $a -le 3; $a++) {
try {
$sm.ActivateConfiguration()
Log "ActivateConfiguration OK (attempt $a)"
Start-Sleep -Seconds 2
try { $err = $sm.GetLastErrorMessages(); if ($err) { Log "ActivateConfiguration messages: $err" } } catch { Log ("GetLastErrorMessages err: " + $_.Exception.Message) }
$actOK = $true
break
} catch {
Log ("ActivateConfiguration err (attempt $a): " + $_.Exception.Message)
Start-Sleep -Seconds 2
try { $err = $sm.GetLastErrorMessages(); if ($err) { Log "ActivateConfiguration messages: $err" } } catch {}
Start-Sleep -Seconds 15
}
}
# Step 2: enter Run via StartRestartTwinCAT
if ($actOK) {
Log 'Waiting 10s, then StartRestartTwinCAT...'
Start-Sleep -Seconds 10
try {
$r = $sm.StartRestartTwinCAT()
Log ("StartRestartTwinCAT() returned: " + $r)
Start-Sleep -Seconds 2
try { $err = $sm.GetLastErrorMessages(); if ($err) { Log "StartRestartTwinCAT messages: $err" } } catch { Log ("GetLastErrorMessages err: " + $_.Exception.Message) }
} catch {
Log ("StartRestartTwinCAT err: " + $_.Exception.Message)
try { $err = $sm.GetLastErrorMessages(); if ($err) { Log "StartRestartTwinCAT messages: $err" } } catch {}
}
}
# Step 3: poll for Run
for ($i = 1; $i -le 12; $i++) {
Start-Sleep -Seconds 5
$st = Get-State
Log ("state +" + ($i*5) + "s: " + $st)
if ($st -eq 'Run') { break }
}
# Check PLC port 851
Log ("port 851 state: " + (Read-PortState 851))
# Save and quit
try { $dte.Solution.SaveAll(); Log 'SaveAll OK' } catch { Log ("SaveAll err: " + $_.Exception.Message) }
try { $dte.Quit(); Log 'DTE quit' } catch { Log ("Quit err: " + $_.Exception.Message) }
Log ("final state: " + (Get-State))
Log '=== tc-dte-activate-run end ==='