폴더·csproj·어셈블리명·RootNamespace·코드 namespace·x:Class·app.manifest 전부 변경. 빌드 결과가 네이티브로 FirmwareFlasher.exe 로 나온다(dist 수동 리네임 불필요). README 빌드/구조 경로도 갱신. 모델명 "DB720"은 그대로 유지. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
114 lines
5.8 KiB
Markdown
114 lines
5.8 KiB
Markdown
# 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. 끝나면 보드 전원 재인가.
|
|
|
|
## 지원 모델
|
|
|
|
| 모델 | 칩 | 부트로더 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)로 같은 일을 더 안전하게 한다.
|