Initial commit: 펌웨어 플래시 도구 (WPF) + 기존 PowerShell 키트

- DB720Flasher: WPF .NET 9 GUI 플래셔
  - 멀티모델 프로파일(flash.json + 빌트인 DB720/DB402S/DB400S/DB400Q/DB300eM)
  - 포트 자동감지(JTAG 우선, 유령 포트 자동 회피), esptool v5 동봉
- flash_app.ps1 / flash_full.ps1 / list_ports.ps1: 기존 PowerShell 키트
- profiles/: 모델별 flash.json 템플릿
- firmware/flash.json: DB720 모델 설정 (서명 실펌웨어 .bin 은 repo 제외)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
insulee
2026-06-23 16:10:40 +09:00
commit 69f4d4754f
25 changed files with 2545 additions and 0 deletions

83
flash_app.ps1 Normal file
View File

@@ -0,0 +1,83 @@
# =====================================================================
# DB720 (ESP32-P4) 앱 적재 — 경우 B: 서명된 부트로더가 이미 있을 때 (brick-safe)
# =====================================================================
# 언제 쓰나
# - 부트로더(0x2000)는 정상이고 펌웨어(앱)만 새로 올릴 때. 일상적 적재는 이쪽.
# - 부트로더(0x2000)를 건드리지 않으므로 eFuse 재굽힘·brick 위험이 없다 (가장 안전).
#
# 무엇을 쓰나 (부트로더 0x2000 제외)
# - 기본: 파티션 0x10000 / ota_data 0x11000 / 앱 0x20000 / www_fs 0x420000
# - -AppOnly: 앱 0x20000 + otadata erase 만 (최소 적재)
#
# ★ 앱이 여러 개일 때 — firmware\ 안의 앱 .bin 을 -App 으로 지정한다.
# 지정 안 하면: 앱이 1개면 자동 선택 / 여러 개면 목록을 보여주고 멈춘다(임의 선택 안 함).
#
# ★ 적재 방식 — 영역을 "하나씩" 개별 esptool 호출로 쓴다.
# eco2 보안 다운로드 모드(SDM)에서 여러 영역을 한 번에 쓰면 중간에
# "Failed to enter Flash download mode"로 실패한다(2026-06-22 실증 — www_fs가 빈 채 남아 부팅 루프).
# =====================================================================
param(
[string]$Port = "COM4", # USB-JTAG 포트 (.\list_ports.ps1 로 확인)
[string]$App = "", # 앱 bin 파일명 (firmware\ 안). 비우면 자동 선택
[switch]$AppOnly # 켜면 앱(0x20000)만 + otadata erase
)
$ErrorActionPreference = "Stop"
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$fw = Join-Path $here "firmware"
$Python = "C:\Users\jyheo\.espressif\python_env\idf5.5_py3.13_env\Scripts\python.exe"
if (-not (Test-Path $Python)) { $Python = "python" }
# eco2 SDM 안정 레시피: --no-stub + 115200 + --after no_reset(이후 별도 hard_reset)
$baud = "115200"
$common = @("--chip","esp32p4","-p",$Port,"-b",$baud,
"--before","default_reset","--after","no_reset","--connect-attempts","30","--no-stub")
# ---- 앱 선택 (여러 개면 -App 으로 지정) ----------------------------------
$support = @("bootloader.bin","partition-table.bin","ota_data_initial.bin","www_fs.bin")
$apps = @(Get-ChildItem (Join-Path $fw "*.bin") -ErrorAction SilentlyContinue | Where-Object { $support -notcontains $_.Name })
if ($App) {
$appPath = Join-Path $fw $App
if (-not (Test-Path $appPath)) { Write-Host "✗ 앱 없음: $appPath" -ForegroundColor Red; exit 1 }
} elseif ($apps.Count -eq 1) {
$appPath = $apps[0].FullName
} elseif ($apps.Count -eq 0) {
Write-Host "✗ firmware\ 에 앱 bin 이 없습니다." -ForegroundColor Red; exit 1
} else {
Write-Host "여러 앱이 있습니다 — -App 으로 하나를 지정하세요:" -ForegroundColor Yellow
$apps | ForEach-Object { Write-Host " $($_.Name)" }
Write-Host "예: .\flash_app.ps1 -Port $Port -App $($apps[0].Name)" -ForegroundColor Gray
exit 1
}
# ---- 영역별 개별 적재 함수 (SDM 다중영역 실패 회피) ----------------------
function Flash-Region([string]$off, [string]$file) {
Write-Host "[flash] $off $(Split-Path -Leaf $file)" -ForegroundColor Cyan
& $Python -m esptool @common write_flash --flash_mode dio --flash_size 16MB --flash_freq 80m $off $file
if ($LASTEXITCODE -ne 0) { Write-Host "$off write 실패 (rc=$LASTEXITCODE)" -ForegroundColor Red; exit 1 }
}
Write-Host "============================================================" -ForegroundColor Yellow
Write-Host " DB720 APP FLASH (경우 B — 서명 부트로더 있음, brick-safe)" -ForegroundColor Yellow
Write-Host " Port=$Port App=$(Split-Path -Leaf $appPath) AppOnly=$AppOnly" -ForegroundColor Yellow
Write-Host " 부트로더(0x2000) 안 건드림 = eFuse 재굽힘/brick 없음" -ForegroundColor Green
Write-Host "============================================================" -ForegroundColor Yellow
if ($AppOnly) {
Flash-Region "0x20000" $appPath
Write-Host "[otadata] erase 0x11000 0x2000 (ota_0 부팅)" -ForegroundColor Cyan
& $Python -m esptool @common erase_region "0x11000" "0x2000"
if ($LASTEXITCODE -ne 0) { Write-Host "✗ otadata erase 실패 (rc=$LASTEXITCODE)" -ForegroundColor Red; exit 1 }
} else {
Flash-Region "0x10000" (Join-Path $fw "partition-table.bin")
Flash-Region "0x11000" (Join-Path $fw "ota_data_initial.bin")
Flash-Region "0x20000" $appPath
Flash-Region "0x420000" (Join-Path $fw "www_fs.bin")
}
Write-Host "[reset] hard_reset (SDM 탈출)" -ForegroundColor Cyan
& $Python -c "from esptool.targets.esp32p4 import ESP32P4ROM; r=ESP32P4ROM('$Port'); r.connect('default_reset'); r.hard_reset(); print('hard_reset OK')"
Write-Host "✓ APP FLASH 완료 — 부팅 확인은 COM2(디버그 콘솔)에서 ![0081!] 응답/배너로." -ForegroundColor Green