Files
Cognitive_Agent/tools/build_seat_firmware.ps1

142 lines
5.7 KiB
PowerShell
Executable File

[CmdletBinding()]
param(
[ValidateSet('combined')]
[string]$Profile = 'combined',
[string]$Configuration = 'rev_d',
[string]$RepositoryRoot = '',
[string]$IarBuild = ''
)
$ErrorActionPreference = 'Stop'
$repositoryCandidate = if ($RepositoryRoot) {
$RepositoryRoot
} else {
Join-Path $PSScriptRoot '..'
}
$resolvedRepository = (Resolve-Path -LiteralPath $repositoryCandidate).Path
$firmwareRoot = Join-Path $resolvedRepository 'firmware\t2g'
$repositoryFirmware = Join-Path $firmwareRoot 'Seat_Controller_demo'
$repositoryProject = Join-Path $repositoryFirmware 'IAR\Seat_Controller_demo.ewp'
$vendorCommon = Join-Path $firmwareRoot 'common'
$vendorDevice = Join-Path $firmwareRoot 'tviibh8m'
function Resolve-IarBuild {
param([string]$ConfiguredPath)
$candidates = @()
if ($ConfiguredPath) {
$candidates += $ConfiguredPath
}
if ($env:COGNITIVE_AGENT_IAR_BUILD) {
$candidates += $env:COGNITIVE_AGENT_IAR_BUILD
}
$command = Get-Command iarbuild.exe -ErrorAction SilentlyContinue
if ($command) {
$candidates += $command.Source
}
$candidates += @(
'D:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin\iarbuild.exe',
'C:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin\iarbuild.exe'
)
foreach ($candidate in $candidates) {
if ($candidate -and (Test-Path -LiteralPath $candidate -PathType Leaf)) {
return (Resolve-Path -LiteralPath $candidate).Path
}
}
throw 'IAR iarbuild.exe was not found; pass -IarBuild or set COGNITIVE_AGENT_IAR_BUILD.'
}
foreach ($required in @($repositoryProject, $vendorCommon, $vendorDevice)) {
if (-not (Test-Path -LiteralPath $required)) {
throw "Self-contained firmware dependency is missing: $required"
}
}
$resolvedIarBuild = Resolve-IarBuild -ConfiguredPath $IarBuild
function Invoke-IarBuild {
param([string]$ProjectPath)
Write-Host "Building Seat_Controller_demo ($Configuration)..."
& $resolvedIarBuild $ProjectPath -build $Configuration -log all
if ($LASTEXITCODE -ne 0) {
throw "IAR build failed with exit code $LASTEXITCODE"
}
}
function Write-ImageSummary {
param([string]$ImagePath)
if (-not (Test-Path -LiteralPath $ImagePath -PathType Leaf)) {
throw "Build completed but HEX image was not found: $ImagePath"
}
$hash = Get-FileHash -LiteralPath $ImagePath -Algorithm SHA256
Write-Host "Seat_Controller_demo HEX: $ImagePath"
Write-Host "Seat_Controller_demo SHA256: $($hash.Hash.ToLowerInvariant())"
}
# Preserve the IAR project's original ../../common and ../../tviibh8m layout
# while keeping both vendor trees inside this repository. Building in a
# temporary staging root avoids committing IAR Obj/BrowseInfo/List products.
$temporaryParent = Join-Path $resolvedRepository '.codex_tmp'
New-Item -ItemType Directory -Path $temporaryParent -Force | Out-Null
$stagingRoot = Join-Path $temporaryParent (
'seat-firmware-build-' + [guid]::NewGuid().ToString('N')
)
$stagingRootFull = [System.IO.Path]::GetFullPath($stagingRoot)
$temporaryParentFull = [System.IO.Path]::GetFullPath($temporaryParent)
if (-not $stagingRootFull.StartsWith(
$temporaryParentFull + [System.IO.Path]::DirectorySeparatorChar,
[System.StringComparison]::OrdinalIgnoreCase)) {
throw "Firmware staging directory escaped repository temporary root: $stagingRootFull"
}
try {
New-Item -ItemType Directory -Path $stagingRootFull | Out-Null
$stagingProjectRoot = Join-Path $stagingRootFull 'Seat_Controller_demo'
Copy-Item -LiteralPath $repositoryFirmware -Destination $stagingProjectRoot -Recurse
New-Item -ItemType Junction -Path (Join-Path $stagingRootFull 'common') -Target $vendorCommon | Out-Null
New-Item -ItemType Junction -Path (Join-Path $stagingRootFull 'tviibh8m') -Target $vendorDevice | Out-Null
$stagedProject = Join-Path $stagingProjectRoot 'IAR\Seat_Controller_demo.ewp'
Invoke-IarBuild -ProjectPath $stagedProject
$stagedExe = Join-Path $stagingProjectRoot "IAR\$Configuration\Exe"
$repositoryExe = Join-Path $repositoryFirmware "IAR\$Configuration\Exe"
New-Item -ItemType Directory -Path $repositoryExe -Force | Out-Null
foreach ($artifact in @('Seat_Controller_demo.hex', 'Seat_Controller_demo.out')) {
$sourceArtifact = Join-Path $stagedExe $artifact
if (-not (Test-Path -LiteralPath $sourceArtifact -PathType Leaf)) {
throw "IAR build did not produce $sourceArtifact"
}
Copy-Item -LiteralPath $sourceArtifact -Destination (
Join-Path $repositoryExe $artifact
) -Force
}
Write-ImageSummary -ImagePath (
Join-Path $repositoryExe 'Seat_Controller_demo.hex'
)
}
finally {
if (Test-Path -LiteralPath $stagingRootFull) {
foreach ($dependencyLink in @('common', 'tviibh8m')) {
$linkPath = Join-Path $stagingRootFull $dependencyLink
if (Test-Path -LiteralPath $linkPath) {
$link = Get-Item -LiteralPath $linkPath -Force
if (($link.Attributes -band [System.IO.FileAttributes]::ReparsePoint) -eq 0) {
throw "Refusing to remove non-junction dependency path: $linkPath"
}
[System.IO.Directory]::Delete($linkPath, $false)
}
}
$remainingLinks = @(
Get-ChildItem -LiteralPath $stagingRootFull -Recurse -Force -Attributes ReparsePoint -ErrorAction SilentlyContinue
)
if ($remainingLinks.Count -ne 0) {
throw "Refusing recursive cleanup because a reparse point remains in $stagingRootFull"
}
[System.IO.Directory]::Delete($stagingRootFull, $true)
}
}
Write-Host 'Build complete. This script never flashes or starts a physical actuator.'