refactor: 프로젝트명 DB720Flasher → FirmwareFlasher
폴더·csproj·어셈블리명·RootNamespace·코드 namespace·x:Class·app.manifest 전부 변경. 빌드 결과가 네이티브로 FirmwareFlasher.exe 로 나온다(dist 수동 리네임 불필요). README 빌드/구조 경로도 갱신. 모델명 "DB720"은 그대로 유지. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
103
FirmwareFlasher/Services/ProfileStore.cs
Normal file
103
FirmwareFlasher/Services/ProfileStore.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace FirmwareFlasher;
|
||||
|
||||
/// <summary>빌트인 모델 프로파일 + 폴더 flash.json 로더 + 앱 파일명 자동매칭.</summary>
|
||||
public static class ProfileStore
|
||||
{
|
||||
static readonly JsonSerializerOptions JsonOpts = new()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
ReadCommentHandling = JsonCommentHandling.Skip,
|
||||
AllowTrailingCommas = true,
|
||||
};
|
||||
|
||||
static FwRegion Boot(string off) => new() { File = "bootloader.bin", Offset = off, Kind = "bootloader" };
|
||||
static FwRegion Part() => new() { File = "partition-table.bin", Offset = "0x10000", Kind = "support" };
|
||||
static FwRegion Ota() => new() { File = "ota_data_initial.bin", Offset = "0x11000", Kind = "support" };
|
||||
static FwRegion Www() => new() { File = "www_fs.bin", Offset = "0x420000", Kind = "support" };
|
||||
static FwRegion AppAt(string off = "0x20000") => new() { App = true, Offset = off, Kind = "app" };
|
||||
|
||||
public static List<FlashProfile> BuiltIns() => new()
|
||||
{
|
||||
new FlashProfile
|
||||
{
|
||||
Name = "DB720 (ESP32-P4)", Chip = "esp32p4", Baud = 115200, NoStub = true, PerRegion = true,
|
||||
ConnectAttempts = 30, FlashSize = "16MB", FlashMode = "dio", FlashFreq = "80m",
|
||||
AppOnlyErasesOtadata = true,
|
||||
Regions = { Boot("0x2000"), Part(), Ota(), Www(), AppAt() },
|
||||
FlashPortHint = "303A:1001", ConsolePortHint = "10C4:EA60",
|
||||
DownloadModeHint = "USB-JTAG 케이블 연결. 포트가 안 잡히면 케이블만 다시 꽂으면 됩니다(자동 감지).",
|
||||
Notes = "secure_release · db250513 서명. 영역별 개별 호출(SDM). 부트로더(0x2000)는 이미 구워진 보드면 거부될 수 있음(정상 → 표준/앱만 사용).",
|
||||
},
|
||||
new FlashProfile
|
||||
{
|
||||
Name = "DB402S (ESP32-S3)", Chip = "esp32s3", Baud = 921600,
|
||||
Regions = { Boot("0x0000"), Part(), Ota(), AppAt() },
|
||||
ConsolePortHint = "10C4:EA60",
|
||||
DownloadModeHint = "TTL(COM2) 연결. SW1 누른 상태에서 SW2 눌렀다 떼고 SW1 떼면 다운로드 모드 진입.",
|
||||
Notes = "esp32-s3. 부트로더 offset 0x0000(중요). 스텁 921600 · 한 번에 기록. secure 보드는 부트로더(<0x8000) 거부 → --force 또는 앱만.",
|
||||
},
|
||||
new FlashProfile
|
||||
{
|
||||
Name = "DB400S (ESP32)", Chip = "esp32", Baud = 921600,
|
||||
Regions = { Boot("0x1000"), Part(), Ota(), AppAt() },
|
||||
ConsolePortHint = "10C4:EA60",
|
||||
DownloadModeHint = "TTL(COM2) 연결. SW1 누른 상태에서 SW2 눌렀다 떼고 SW1 떼면 다운로드 모드 진입.",
|
||||
Notes = "esp32 클래식. 부트로더 0x1000. 스텁 921600 · 한 번에. secure 보드는 부트로더(<0x8000) 거부 → --force 또는 앱만.",
|
||||
},
|
||||
new FlashProfile
|
||||
{
|
||||
Name = "DB400Q (ESP32)", Chip = "esp32", Baud = 921600,
|
||||
Regions = { Boot("0x1000"), Part(), Ota(), AppAt() },
|
||||
ConsolePortHint = "10C4:EA60",
|
||||
DownloadModeHint = "TTL(COM2) 연결. SW1 누른 상태에서 SW2 눌렀다 떼고 SW1 떼면 다운로드 모드 진입.",
|
||||
Notes = "esp32 클래식. DB400S와 동일 방식.",
|
||||
},
|
||||
new FlashProfile
|
||||
{
|
||||
Name = "DB300eM (ESP32)", Chip = "esp32", Baud = 921600,
|
||||
Regions = { Boot("0x1000"), Part(), Ota(), AppAt() },
|
||||
ConsolePortHint = "10C4:EA60",
|
||||
DownloadModeHint = "TTL(COM2) 연결. JP1 점퍼핀 단락 후 전원 재인가하면 다운로드 모드 진입.",
|
||||
Notes = "esp32 클래식. JP1 점퍼로 다운로드 진입. web OTA(IP 입력)도 가능.",
|
||||
},
|
||||
};
|
||||
|
||||
/// <summary>폴더의 flash.json 을 읽는다(없으면 null).</summary>
|
||||
public static FlashProfile? LoadFromFolder(string folder)
|
||||
{
|
||||
try
|
||||
{
|
||||
var p = Path.Combine(folder, "flash.json");
|
||||
if (!File.Exists(p)) return null;
|
||||
var prof = JsonSerializer.Deserialize<FlashProfile>(File.ReadAllText(p), JsonOpts);
|
||||
if (prof is not null) prof.FromFile = true;
|
||||
return prof;
|
||||
}
|
||||
catch { return null; }
|
||||
}
|
||||
|
||||
/// <summary>앱 bin 파일명(DIBD720…, DIBD402S… 등)으로 빌트인 프로파일을 추정.</summary>
|
||||
public static FlashProfile? MatchByApp(IEnumerable<string> appFileNames, List<FlashProfile> profiles)
|
||||
{
|
||||
// 더 구체적인 토큰을 먼저 (402S 가 400 보다, 400S 가 400 보다 우선)
|
||||
(string token, string profileTag)[] map =
|
||||
{
|
||||
("402S", "DB402S"), ("400S", "DB400S"), ("400Q", "DB400Q"),
|
||||
("300", "DB300"), ("720", "DB720"),
|
||||
};
|
||||
foreach (var name in appFileNames)
|
||||
{
|
||||
var up = name.ToUpperInvariant();
|
||||
foreach (var (token, tag) in map)
|
||||
if (up.Contains(token))
|
||||
{
|
||||
var hit = profiles.FirstOrDefault(p => p.Name.ToUpperInvariant().Contains(tag));
|
||||
if (hit is not null) return hit;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user