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 제외.
142 lines
6 KiB
PowerShell
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
|