ethercat-linux/scripts/tc-scan-xae.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

208 lines
5.4 KiB
PowerShell

#Requires -Version 5.1
[CmdletBinding()]
param(
[string]$Solution = $null
)
. "$PSScriptRoot\tc-common.ps1"
if (-not $Solution) { $Solution = $script:DefaultSolution }
New-Log $script:DefaultLogDir
$LogFile = Join-Path $script:DefaultLogDir "scan.log"
function Write-Log($Message) {
$line = "[{0}] {1}" -f (Get-Date -Format 'HH:mm:ss'), $Message
Write-Host $line
Add-Content -Path $LogFile -Value $line -Encoding UTF8
}
Write-Log "=== XAE EtherCAT Scan ==="
try {
$dte = New-Object -ComObject TcXaeShell.DTE.17.0 -ErrorAction Stop
} catch {
Write-Log "FATAL: Cannot create DTE: $_"
exit 1
}
$dte.MainWindow.Visible = $true
$dte.Solution.Open($Solution)
for ($i = 1; $i -le 120; $i++) {
Start-Sleep -Seconds 1
if ($dte.Solution.IsOpen) { break }
}
Write-Log "Solution open: $($dte.Solution.IsOpen)"
$sysMgr = $null
for ($i = 1; $i -le 40; $i++) {
try {
$sysMgr = $dte.Solution.Projects.Item(1).Object
if ($sysMgr) { break }
} catch {}
Start-Sleep -Seconds 3
}
if (-not $sysMgr) {
Write-Log "FATAL: SysManager is null"
exit 1
}
Write-Log "SysManager OK"
# Set target and platform with retry for RPC_E_CALL_REJECTED
$targetNetId = '169.254.176.217.1.1'
$platform = 'TwinCAT RT (x64)'
for ($i = 1; $i -le 10; $i++) {
try {
$sysMgr.SetTargetNetId($targetNetId)
Write-Log "SetTargetNetId $targetNetId OK (try $i)"
break
} catch {
Write-Log "SetTargetNetId try $i error: $_"
Start-Sleep -Seconds 2
}
}
for ($i = 1; $i -le 10; $i++) {
try {
$sysMgr.ConfigurationManager.ActiveTargetPlatform = $platform
Write-Log "ActiveTargetPlatform set to $platform (try $i)"
break
} catch {
Write-Log "Set platform try $i error: $_"
Start-Sleep -Seconds 2
}
}
Start-Sleep -Seconds 5
try {
$cfg = $sysMgr.ConfigurationManager.ActiveConfiguration
Write-Log "Active Target NetId: $($cfg.TargetNetId)"
Write-Log "Active Platform: $($sysMgr.ConfigurationManager.ActiveTargetPlatform)"
} catch {
Write-Log "Get active config error: $_"
}
# Activate configuration
Write-Log "Activating configuration..."
try {
$sysMgr.ActivateConfiguration()
Write-Log "ActivateConfiguration OK"
} catch {
Write-Log "ActivateConfiguration error: $_"
}
Start-Sleep -Seconds 5
# Restart in config mode
$cmdCfgMode = 'TwinCAT.重启TwinCAT配置模式'
Write-Log "Restarting TwinCAT in config mode..."
try {
$dte.ExecuteCommand($cmdCfgMode)
Write-Log "ExecuteCommand($cmdCfgMode) OK"
} catch {
Write-Log "ExecuteCommand($cmdCfgMode) error: $_"
}
Start-Sleep -Seconds 10
try {
Write-Log "IsTwinCATStarted = $($sysMgr.IsTwinCATStarted())"
} catch {
Write-Log "IsTwinCATStarted error: $_"
}
# Find EtherCAT device in tree and select it
$io = $null
for ($i = 1; $i -le 10; $i++) {
try {
$io = $sysMgr.LookupTreeItem('TIID')
if ($io) { break }
} catch {}
Start-Sleep -Seconds 2
}
if (-not $io) {
Write-Log "FATAL: Cannot find TIID"
exit 1
}
$ecat = $null
for ($j = 1; $j -le [int]$io.ChildCount; $j++) {
try {
$ch = $io.Child($j)
if ([int]$ch.ItemSubType -eq 111) {
$ecat = $ch
break
}
} catch {}
}
if (-not $ecat) {
Write-Log "FATAL: No EtherCAT device found under TIID"
exit 1
}
Write-Log "EtherCAT device: $($ecat.Name)"
# Select in Solution Explorer
Write-Log "Selecting EtherCAT device in Solution Explorer..."
try {
$se = $dte.ToolWindows.SolutionExplorer
$se.Parent.Activate()
Start-Sleep -Seconds 2
function Find-Node($items) {
if ($null -eq $items) { return $null }
foreach ($it in $items) {
try { if ($it.Name -like '*EtherCAT*') { return $it } } catch {}
try { $sub = Find-Node $it.UIHierarchyItems; if ($sub) { return $sub } } catch {}
}
return $null
}
$node = Find-Node $se.UIHierarchyItems
if ($node) {
$node.Select(1)
Write-Log "Selected: $($node.Name)"
} else {
Write-Log "WARN: Could not select EtherCAT node in UI"
}
} catch {
Write-Log "Select node error: $_"
}
# Trigger scan command
$cmdScan = 'TwinCAT.扫描'
Write-Log ">>> Invoking $cmdScan -- please confirm scan dialog if it appears <<<"
try {
$dte.ExecuteCommand($cmdScan)
Write-Log "ExecuteCommand($cmdScan) returned"
} catch {
Write-Log "ExecuteCommand($cmdScan) error: $_"
}
Write-Log "Scan dialog should be visible. Please confirm it and report what devices were found."
Write-Log "Waiting 60s (do not close XAE)..."
Start-Sleep -Seconds 60
# Read back after scan
$io2 = $sysMgr.LookupTreeItem('TIID')
$ecat2 = $null
for ($j = 1; $j -le [int]$io2.ChildCount; $j++) {
try {
$ch = $io2.Child($j)
if ([int]$ch.ItemSubType -eq 111) { $ecat2 = $ch; break }
} catch {}
}
if ($ecat2) {
Write-Log "Post-scan EtherCAT ChildCount = $($ecat2.ChildCount)"
for ($j = 1; $j -le [int]$ecat2.ChildCount; $j++) {
try {
$b = $ecat2.Child($j)
Write-Log " Box[$j]: name='$($b.Name)' subtype=$($b.ItemSubType)"
} catch {}
}
$xml = $ecat2.ProduceXml($false)
$xmlFile = Join-Path $script:DefaultLogDir 'scan_ecat.xml'
[System.IO.File]::WriteAllText($xmlFile, $xml, [System.Text.Encoding]::UTF8)
Write-Log "Post-scan XML saved: $xmlFile"
}
Write-Log "=== Scan complete ==="