POSA_LEAKSMS/firmware/scripts/flash.ps1
유창욱 90f121e14c chore: import codebase with security hardening
SHT30 온습도 모니터링 시스템 전체 소스(서버 PHP, STM32 펌웨어, SQL, 테스트).
전체 코드리뷰에서 도출된 보안 하드닝 10건 반영:
- 요청 서명 HMAC-SHA256 전환(펌웨어 sig.c/서버 config.php/호스트 패리티 동시)
- 재전송 방어 + 기본 API_KEY fail-closed + 디바이스 문자열 정제(api/sensor_data.php)
- 오프라인 SMS 중복 발송 경합 제거(cron_heartbeat.php, 원자적 선점)
- CSV 수식 주입 방지(monthly_report.php), 감사로그 회전 락(retention_cleanup.php)
- 브루트포스 카운터 원자화(login.php), 예시 TOTP 비밀키 무효화, 마이그레이션 멱등화

_backup/(하드코딩 실 비밀값 포함)·config.local.php·런타임 상태는 .gitignore 제외.
2026-06-20 09:37:40 +09:00

142 lines
6 KiB
PowerShell

<#
.SYNOPSIS
STM32F407 펌웨어 플래싱 (sht30_fw) — ST-LINK 경유.
.DESCRIPTION
빌드된 .bin/.hex 또는 .elf 를 STM32F407VGT6 에 기록한다. 사용 가능한
프로그래머를 자동 탐지하여 사용한다(우선순위):
1) STM32_Programmer_CLI (STM32CubeProgrammer)
2) st-flash (stlink-tools)
3) openocd (st-link 인터페이스 + stm32f4x 타깃)
폐쇄망/현장 배포: 이 스크립트는 네트워크에 접속하지 않는다(로컬 프로그래머만 사용).
.PARAMETER Programmer
강제 프로그래머 선택: auto | cubecli | stflash | openocd. 기본 auto.
.PARAMETER Address
플래시 시작 주소(.bin 기록 시). 기본 0x08000000.
.PARAMETER BuildDir
산출물 디렉터리. 기본 firmware/build.
.PARAMETER NoVerify
기록 후 검증 단계를 생략한다(빠른 반복용).
.EXAMPLE
pwsh firmware/scripts/flash.ps1
pwsh firmware/scripts/flash.ps1 -Programmer openocd
#>
[CmdletBinding()]
param(
[ValidateSet('auto', 'cubecli', 'stflash', 'openocd')]
[string]$Programmer = 'auto',
[string]$Address = '0x08000000',
[string]$BuildDir,
[switch]$NoVerify
)
$ErrorActionPreference = 'Stop'
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$FwRoot = Split-Path -Parent $ScriptDir
if (-not $BuildDir) { $BuildDir = Join-Path $FwRoot 'build' }
# SHT30 단일 보드 타깃.
$target = 'sht30_fw'
# ── 산출물 탐색 (.elf / .hex / .bin) ─────────────────────────────────────────
function Find-Artifact([string]$ext) {
$hits = Get-ChildItem -Path $BuildDir -Recurse -Filter "$target.$ext" -ErrorAction SilentlyContinue
if ($hits) { return $hits[0].FullName }
return $null
}
$elf = Find-Artifact 'elf'
$hex = Find-Artifact 'hex'
$bin = Find-Artifact 'bin'
if (-not ($elf -or $hex -or $bin)) {
throw "$target 산출물을 찾을 수 없습니다($BuildDir). 먼저 빌드하세요: build.ps1"
}
Write-Host "==== 플래싱: $target ====" -ForegroundColor Cyan
Write-Host " build dir : $BuildDir"
Write-Host " elf/hex/bin: $elf / $hex / $bin"
Write-Host " address : $Address (.bin 기록 시)"
function Test-Tool([string]$name) {
return [bool](Get-Command $name -ErrorAction SilentlyContinue)
}
# ── 프로그래머 선택 ──────────────────────────────────────────────────────────
if ($Programmer -eq 'auto') {
if (Test-Tool 'STM32_Programmer_CLI') { $Programmer = 'cubecli' }
elseif (Test-Tool 'st-flash') { $Programmer = 'stflash' }
elseif (Test-Tool 'openocd') { $Programmer = 'openocd' }
else {
throw @"
. PATH :
- STM32_Programmer_CLI (STM32CubeProgrammer)
- st-flash (stlink-tools)
- openocd
"@
}
}
Write-Host " programmer: $Programmer" -ForegroundColor Green
# ── 실행 헬퍼 ────────────────────────────────────────────────────────────────
function Invoke-Flash([string]$exe, [string[]]$flashArgs) {
Write-Host " > $exe $($flashArgs -join ' ')" -ForegroundColor DarkGray
& $exe @flashArgs
if ($LASTEXITCODE -ne 0) { throw "$exe 실패 (exit $LASTEXITCODE)" }
}
switch ($Programmer) {
# ── STM32CubeProgrammer CLI ──────────────────────────────────────────────
'cubecli' {
if (-not (Test-Tool 'STM32_Programmer_CLI')) { throw "STM32_Programmer_CLI 가 PATH 에 없습니다." }
# .hex 우선(주소 내장), 없으면 .elf, 그다음 .bin(+주소).
$img = if ($hex) { $hex } elseif ($elf) { $elf } else { $bin }
$args = @('-c', 'port=SWD', 'mode=UR', '-w', $img)
if ($img -eq $bin) { $args += $Address }
if (-not $NoVerify) { $args += '-v' }
$args += @('-rst') # 기록 후 리셋하여 실행
Invoke-Flash 'STM32_Programmer_CLI' $args
}
# ── st-flash (stlink-tools) — .bin + 주소 ────────────────────────────────
'stflash' {
if (-not (Test-Tool 'st-flash')) { throw "st-flash 가 PATH 에 없습니다." }
if (-not $bin) { throw "st-flash 는 .bin 이 필요합니다(빌드 산출물 없음): $target.bin" }
# st-flash 는 자체 검증 후 기록. --reset 로 기록 후 리셋.
$args = @('--reset', 'write', $bin, $Address)
Invoke-Flash 'st-flash' $args
Write-Host " (st-flash 는 기록 중 자동 검증함)" -ForegroundColor DarkGray
}
# ── OpenOCD (ST-LINK + stm32f4x) ─────────────────────────────────────────
'openocd' {
if (-not (Test-Tool 'openocd')) { throw "openocd 가 PATH 에 없습니다." }
# .elf 우선(주소 불필요), 없으면 .hex.
$img = if ($elf) { $elf } elseif ($hex) { $hex } else { $bin }
if ($img -eq $bin) {
throw "OpenOCD 경로는 .elf 또는 .hex 를 권장합니다(.bin 은 주소 지정 필요 — TODO(hw)로 별도 처리)."
}
# program <img> verify reset exit : 기록→검증→리셋→종료.
$verifyTok = if ($NoVerify) { '' } else { ' verify' }
$cmd = "program `"$img`"$verifyTok reset exit"
$args = @(
'-f', 'interface/stlink.cfg'
'-f', 'target/stm32f4x.cfg'
'-c', $cmd
)
Invoke-Flash 'openocd' $args
}
}
Write-Host "`n==== 플래싱 완료: $target ====" -ForegroundColor Cyan
Write-Host " 보드가 리셋되어 펌웨어가 실행됩니다. USART3(PD8/PD9, 115200)로 로그 확인." -ForegroundColor Green