# firmware-flasher ESP32 계열 컨트롤러(DB720·DB402S·DB400S 등)에 펌웨어를 굽는 **Windows GUI 도구**. 설치·파이썬 없이 도는 단일 실행본으로 배포되고, 모델별 설정은 `flash.json` 하나로 갈아끼운다. > 시작은 DB720(ESP32-P4) 전용 PowerShell 키트였고, 지금은 여러 모델을 GUI로 다룬다. > 기존 `.ps1` 스크립트도 그대로 남아 있다([아래](#powershell-키트-기존)). ## 특징 - **멀티모델** — 칩·offset·baud·쓰기방식이 다른 모델을 프로파일로 분리. 드롭다운에서 고르거나 폴더의 `flash.json`으로 자동. - **포트 자동 감지** — USB-JTAG(`303A:1001`)를 꽂는 즉시 잡아 자동 선택. 리셋으로 COM 번호가 바뀌어 생기는 **유령 포트**를 열기-probe로 걸러 살아있는 포트로 자동 전환. - **esptool 동봉** — esptool v5 단독 실행본을 같이 묶어, 받는 PC에 파이썬이 없어도 동작. - **안전장치** — "앱만"이 기본(부트로더 안 건드림). "전체"(부트로더 재작성)는 eFuse 영구 굽힘 경고 + 확인 체크. ## 빠른 시작 (사용자) 1. 배포 zip을 풀고 `FirmwareFlasher.exe` 실행. 2. **펌웨어 폴더** 선택 → **앱**·**모델** 확인(폴더에 `flash.json` 있으면 자동). 3. **포트**는 자동으로 잡힘(안 잡히면 `↻ 새로고침`). 4. **모드** 고르고 **플래시 시작**. - 평소: **앱만**(가장 안전) - 새 보드 첫 굽기/복구: **전체** (eFuse 주의) 5. 끝나면 보드 전원 재인가. ## 펌웨어 파일 넣는 곳 서명된 펌웨어 `.bin`은 보안상 repo·배포본에 **들어 있지 않다**(`.gitignore`로 제외). **직접 넣어야 한다.** 모델 폴더 하나에 아래 파일을 모아 둔다: ``` <펌웨어 폴더>/ ├─ flash.json ← 모델 설정 (없으면 앱 "모델" 드롭다운에서 선택) ├─ bootloader.bin ├─ partition-table.bin ├─ ota_data_initial.bin ├─ DIBD*.bin ← 앱 (예: DIBD720Te_…, DIBD402S_…) └─ www_fs.bin ← DB720 만 ``` - 앱은 **exe 옆 `firmware/` 폴더를 자동으로** 찾는다 — 거기에 넣으면 바로 잡힌다. - 다른 위치에 두려면 앱에서 **[폴더…]** 로 그 폴더를 고른다. - **"앱만" 모드**는 앱 `DIBD*.bin` 하나만 있으면 된다(부트로더·파티션 등 불필요). ## 지원 모델 | 모델 | 칩 | 부트로더 offset | 포트·방식 | |---|---|---|---| | DB720 | `esp32p4` | `0x2000` | USB-JTAG · no-stub · 115200 · 영역별 | | DB402S | `esp32s3` | `0x0000` | UART(TTL) · stub · 921600 · 한 번에 | | DB400S / DB400Q / DB300eM | `esp32` | `0x1000` | UART(TTL) · stub · 921600 · 한 번에 | 공통 offset: 파티션 `0x10000` · ota_data `0x11000` · 앱 `0x20000` · (DB720만) www_fs `0x420000`. ## 모델 추가 — `flash.json` 펌웨어 폴더에 `flash.json`을 넣으면 앱이 **그 폴더만 보고** 그대로 굽는다. `profiles/`에 모델별 템플릿이 있다. ```json { "name": "DB402S (ESP32-S3)", "chip": "esp32s3", "baud": 921600, "noStub": false, "perRegion": false, "regions": [ { "file": "bootloader.bin", "offset": "0x0000", "kind": "bootloader" }, { "file": "partition-table.bin", "offset": "0x10000", "kind": "support" }, { "file": "ota_data_initial.bin", "offset": "0x11000", "kind": "support" }, { "app": true, "offset": "0x20000" } ], "consolePortHint": "10C4:EA60", "downloadModeHint": "TTL(COM2) 연결, SW1 누른 채 SW2 눌렀다 떼고 SW1 떼면 다운로드 모드" } ``` 주요 키: `chip` / `baud` / `noStub`(스텁 여부) / `perRegion`(영역별 vs 한 번에) / `flashSize`·`flashMode`·`flashFreq`(생략 시 자동) / `flashPortHint`(자동선택 우선 VID:PID) / `consolePortHint` / `appOnlyErasesOtadata`. > `flash.json`이 없어도 됨 — DB720·DB402S·DB400S·DB400Q·DB300eM 설정은 앱에 내장돼 있어 "모델" 드롭다운에서 골라도 동작. ## 포트 — 유령 COM 주의 ESP32 USB-JTAG는 보드가 리셋될 때마다 USB를 다시 잡아 **COM 번호가 올라간다**(예: COM17→COM18). 옛 번호는 목록엔 "정상"으로 남지만 열 수 없다(유령 포트). 앱은 **최신 번호 우선 + 열기-probe**로 살아있는 포트를 자동으로 쓴다. 그래도 안 되면 케이블을 다시 꽂고 `↻ 새로고침`. > 적재 포트는 측정/표출 중에는 열지 말 것 — DTR/RTS가 보드를 리셋한다. ## secure 보드 / eFuse 서명(secure boot) 보드는 부트로더(`0x8000` 아래) 쓰기를 거부하는 게 **정상**이다. 그땐 **표준/앱만**으로(부트로더 건너뜀). 꼭 부트로더를 다시 써야 하면 `--force`. eFuse는 한 번 구워지면 **되돌릴 수 없으니** 서명 키 백업 필수. ## 빌드 (개발) 요구: **.NET 9 SDK** (Windows), WPF(`net9.0-windows`). ```powershell dotnet build FirmwareFlasher\FirmwareFlasher.csproj dotnet run --project FirmwareFlasher\FirmwareFlasher.csproj ``` ## 배포 (단일 실행본) ```powershell dotnet publish FirmwareFlasher\FirmwareFlasher.csproj -c Release -r win-x64 ` --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true ``` > ⚠ 단일 파일 publish는 동봉 `esptool.exe`를 exe 안으로 삼킨다. publish 후 `tools\esptool\`와 `firmware\`를 **exe 옆에 따로 복사**해 배포 폴더를 만든다(그래야 앱이 esptool을 찾음). 받는 사람은 폴더 통째로 받아 `FirmwareFlasher.exe` 실행 — 설치 불필요. ## 폴더 구조 ``` firmware-flasher/ ├─ FirmwareFlasher/ WPF 앱 소스 (+ tools/esptool/ 동봉 엔진) ├─ firmware/ 펌웨어 폴더 (flash.json 포함; 서명 .bin 은 git 제외) ├─ profiles/ 모델별 flash.json 템플릿 (DB720·DB402S·DB400S) ├─ flash_app.ps1 / flash_full.ps1 / list_ports.ps1 기존 PowerShell 키트 └─ README.md ``` > `firmware/*.bin`(서명 실펌웨어)와 `dist/`(배포본), 빌드 출력은 git에 올리지 않는다(`.gitignore`). 배포본 zip은 Gitea **Releases**로. ## PowerShell 키트 (기존) GUI 없이 명령으로 굽는 원래 방식(여전히 사용 가능). DB720 기준: ```powershell .\list_ports.ps1 # 적재 포트(303A:1001) 확인 .\flash_app.ps1 -Port COM4 -AppOnly # 앱만 (brick-safe, 권장) .\flash_full.ps1 -Port COM4 # 전체 (부트로더 포함, eFuse 주의) ``` > 일상 적재는 `flash_app.ps1`(앱만)으로 충분하다. `flash_full.ps1`은 부트로더가 비어 부팅이 안 될 때만 쓰는 복구 전용. GUI 앱은 동봉 esptool(v5)로 같은 일을 더 안전하게 한다.