• OTA Update๋Š” ๊ธฐ๊ธฐ์˜ ํŽŒ์›จ์–ด/์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์œ ์„  ์—ฐ๊ฒฐ ์—†์ด Wi-Fiยท์…€๋ฃฐ๋Ÿฌ ๋“ฑ ๋ฌด์„  ๋„คํŠธ์›Œํฌ๋กœ ๊ฐฑ์‹ ํ•˜๋Š” ๋ฐฉ์‹
  • ์ž„๋ฒ ๋””๋“œยทIoT ๊ธฐ๊ธฐ ํ•œ์ •์œผ๋กœ๋Š” **FOTA(Firmware Over-The-Air)**๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๋ฐฐํฌ ๊ธฐ๋ฒ•
  • ์‚ฌ์šฉ์ž๊ฐ€ USB ์ผ€์ด๋ธ”ยท์ „์šฉ ํˆด ์—†์ด ์›๊ฒฉ์—์„œ ๋Œ€๊ทœ๋ชจ๋กœ ๋ฐฐํฌ ๊ฐ€๋Šฅํ•œ ์—…๋ฐ์ดํŠธ ์ฑ„๋„
  • ๋‹ค์šด๋กœ๋“œ โ†’ ๊ฒ€์ฆ โ†’ ์žฌ๋ถ€ํŒ… โ†’ ์ž๊ฐ€์ง„๋‹จ โ†’ ํ™•์ •/๋กค๋ฐฑ์œผ๋กœ ์ด์–ด์ง€๋Š” ๋ฌด์ค‘๋‹จยท๋ณต๊ตฌ๊ฐ€๋Šฅ(power-safe) ๊ฐฑ์‹  ์ ˆ์ฐจ

ํ•ด๋‹น ๊ฐœ๋…์ด ํ•„์š”ํ•œ ์ด์œ 

  • ํ˜„์žฅ์— ์ด๋ฏธ ๋ฐฐํฌ๋œ ์ˆ˜์‹ญ~์ˆ˜๋งŒ ๋Œ€์˜ ๊ธฐ๊ธฐ๋ฅผ ์ผ์ผ์ด ํšŒ์ˆ˜ํ•˜๊ฑฐ๋‚˜ USB๋กœ ๋ฌผ๋ฆฌ ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ  ๋ฒ„๊ทธ ์ˆ˜์ •ยท๊ธฐ๋Šฅ ์ถ”๊ฐ€๋ฅผ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด
  • ์‚ฌ์šฉ์ž์—๊ฒŒ โ€œ์ƒˆ ๋ฒ„์ „์ด ๋‚˜์™”์œผ๋‹ˆ ์ปดํ“จํ„ฐ์— ์—ฐ๊ฒฐํ•ด์„œ ์‚ฌ์ดํŠธ์—์„œ ํŽŒ์›จ์–ด๋ฅผ ๋ฐ›์•„ ๊ตฌ์šฐ์„ธ์š”โ€๋ผ๊ณ  ์š”๊ตฌํ•˜์ง€ ์•Š๊ณ , ๊ธฐ๊ธฐ๊ฐ€ ์Šค์Šค๋กœ ๋ฐ›์•„ ์ ์šฉํ•˜๋Š” ๊ฒฝํ—˜์„ ์ฃผ๊ธฐ ์œ„ํ•ด
  • ์—…๋ฐ์ดํŠธ ๋„์ค‘ ์ •์ „/๋„คํŠธ์›Œํฌ ๋Š๊น€์ด ๋ฐœ์ƒํ•ด๋„ ๊ธฐ๊ธฐ๊ฐ€ ๋ฒฝ๋Œ(brick)์ด ๋˜์ง€ ์•Š๋„๋ก ์ด์ค‘ ์Šฌ๋กฏ + ๋กค๋ฐฑ์œผ๋กœ ์•ˆ์ „ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด

AS-IS โ€” USB๋กœ ์ง์ ‘ ๊ตฝ๋Š” ๋ฐฉ์‹ (์‚ฌ์šฉ์ž๊ฐ€ ์ง€์–‘ํ•˜๋Š” ํ๋ฆ„)

sequenceDiagram
    autonumber
    actor U as ์‚ฌ์šฉ์ž
    participant PC as ์ปดํ“จํ„ฐ(ํ”Œ๋ž˜์…” ํˆด)
    participant D as ESP32 ๊ธฐ๊ธฐ
    U->>PC: ๋ฆด๋ฆฌ์Šค ์‚ฌ์ดํŠธ์—์„œ .bin ํŽŒ์›จ์–ด ๋‹ค์šด๋กœ๋“œ
    U->>D: USB ์ผ€์ด๋ธ” ๋ฌผ๋ฆฌ ์—ฐ๊ฒฐ
    PC->>D: esptool๋กœ flash ์ „์ฒด ๊ตฝ๊ธฐ
    D-->>U: ์žฌ๋ถ€ํŒ… ํ›„ ์ƒˆ ํŽŒ์›จ์–ด ์‹คํ–‰
    Note over U,D: ๊ธฐ๊ธฐ๋งˆ๋‹ค ์ผ€์ด๋ธ” ์—ฐ๊ฒฐยท์ˆ˜๋™ ์ž‘์—… ํ•„์š” โ†’ ํ™•์žฅ ๋ถˆ๊ฐ€

TO-BE โ€” OTA (๊ธฐ๋Œ€ํ•˜๋Š” ํ๋ฆ„: ์•Œ๋ฆผ โ†’ ๋ฒ„ํŠผ โ†’ ๋ฌด์„  ๊ฐฑ์‹ )

sequenceDiagram
    autonumber
    participant S as ํŽŒ์›จ์–ด ์„œ๋ฒ„/ํด๋ผ์šฐ๋“œ
    participant D as ESP32 ๊ธฐ๊ธฐ
    actor U as ์‚ฌ์šฉ์ž(์•ฑ)
    S-->>D: "์ƒˆ ๋ฒ„์ „ v1.2.0 ์žˆ์Œ" ์•Œ๋ฆผ(push/manifest)
    D-->>U: ์•ฑ์— ์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅ ํ‘œ์‹œ
    U->>D: [์—…๋ฐ์ดํŠธ] ๋ฒ„ํŠผ ํด๋ฆญ
    D->>S: ์ƒˆ ํŽŒ์›จ์–ด ์ด๋ฏธ์ง€ ์š”์ฒญ(HTTPS)
    S-->>D: ์ด๋ฏธ์ง€ ์ŠคํŠธ๋ฆฌ๋ฐ ์ „์†ก
    D->>D: ๋น„ํ™œ์„ฑ ์Šฌ๋กฏ์— ๊ธฐ๋ก + ์„œ๋ช…/๋ฌด๊ฒฐ์„ฑ ๊ฒ€์ฆ
    D->>D: ๋ถ€ํŒ… ํŒŒํ‹ฐ์…˜ ์ „ํ™˜ ํ›„ ์žฌ๋ถ€ํŒ…
    D->>D: ์ž๊ฐ€์ง„๋‹จ ์„ฑ๊ณต โ†’ ํ™•์ • (์‹คํŒจ ์‹œ ์ž๋™ ๋กค๋ฐฑ)
    D-->>U: ์—…๋ฐ์ดํŠธ ์™„๋ฃŒ ๋ณด๊ณ 

OTA๊ฐ€ ์‹ค์ œ๋กœ ๋™์ž‘ํ•˜๋Š” ๋ฐฉ์‹ (ESP32/ESP-IDF ๊ธฐ์ค€)

ESP32๋Š” ํ”Œ๋ž˜์‹œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํŒŒํ‹ฐ์…˜(partition) ์ด๋ผ๋Š” ์šฉ๋„๋ณ„ ๊ตฌํš์œผ๋กœ ๋‚˜๋ˆ  ์“ด๋‹ค. OTA์˜ ํ•ต์‹ฌ์€ **์•ฑ ์Šฌ๋กฏ์ด 2๊ฐœ(์ด์ค‘ ์Šฌ๋กฏ, A/B)**๋ผ๋Š” ์ ์ด๋‹ค.

ํŒŒํ‹ฐ์…˜ ๋ ˆ์ด์•„์›ƒ

ํŒŒํ‹ฐ์…˜ ๊ตฌ์„ฑ์€ CSV๋กœ ์ •์˜ํ•˜๋ฉฐ, ๊ธฐ๋ณธ ์œ„์น˜๋Š” ์˜คํ”„์…‹ 0x8000(4KB ํ•œ ์„นํ„ฐ)์ด๋‹ค.

# Name,   Type, SubType,  Offset,   Size
nvs,      data, nvs,      0x9000,   0x6000
otadata,  data, ota,      0xf000,   0x2000
factory,  app,  factory,  0x10000,  1M
ota_0,    app,  ota_0,    ,         1M
ota_1,    app,  ota_1,    ,         1M
ํŒŒํ‹ฐ์…˜์ข…๋ฅ˜์—ญํ• 
factoryapp๊ณต์žฅ ์ถœํ•˜ ์ดˆ๊ธฐ ํŽŒ์›จ์–ด (์„ ํƒ์ )
ota_0 / ota_1app์„œ๋กœ ๊ต๋Œ€๋กœ ์“ฐ์ด๋Š” ๋‘ ๊ฐœ์˜ ์•ฑ ์Šฌ๋กฏ
otadatadata๋‹ค์Œ์— ์–ด๋А ์Šฌ๋กฏ์„ ๋ถ€ํŒ…ํ• ์ง€ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ + ๋กค๋ฐฑ ์ƒํƒœ (๋‘ ์„นํ„ฐ๋ผ ์ •์ „์—๋„ ํ•˜๋‚˜๋Š” ์ƒ์กด)
nvsdataWi-Fi ์ž๊ฒฉ์ฆ๋ช…ยท์„ค์ • ๋“ฑ ๋น„ํœ˜๋ฐœ์„ฑ ์ €์žฅ. ์•ฑ์„ ๊ฐˆ์•„๋ผ์›Œ๋„ ๊ฐ’ ๋ณด์กด โ†’ ์‚ฌ์šฉ์ž ์„ค์ • ์œ ์ง€

์•ฑ ํŒŒํ‹ฐ์…˜์€ 64KB ์ •๋ ฌ์ด ํ•„์š”ํ•˜๊ณ , Name์€ ์ตœ๋Œ€ 16๋ฐ”์ดํŠธ๋‹ค. ์˜คํ”„์…‹์„ ๋น„์›Œ๋‘๋ฉด ์ž๋™ ๊ณ„์‚ฐ๋œ๋‹ค.

์—…๋ฐ์ดํŠธ ์ ˆ์ฐจ โ€” โ€œ๋น„ํ™œ์„ฑ ์Šฌ๋กฏ์— ์“ฐ๊ณ  ํฌ์ธํ„ฐ๋งŒ ๋ฐ”๊ฟ” ์žฌ๋ถ€ํŒ…โ€

sequenceDiagram
    autonumber
    participant App as ํ˜„์žฌ ์•ฑ(ota_0์—์„œ ์‹คํ–‰ ์ค‘)
    participant Flash as ๋น„ํ™œ์„ฑ ์Šฌ๋กฏ(ota_1)
    participant OtaData as otadata ํŒŒํ‹ฐ์…˜
    participant Boot as ๋ถ€ํŠธ๋กœ๋”
    App->>Flash: esp_ota_begin() โ€” ๋Œ€์ƒ ์Šฌ๋กฏ ์ค€๋น„/erase
    loop ๋‹ค์šด๋กœ๋“œ๋˜๋Š” ์ฒญํฌ๋งˆ๋‹ค
        App->>Flash: esp_ota_write() โ€” ์กฐ๊ฐ ๊ธฐ๋ก
    end
    App->>Flash: esp_ota_end() โ€” ์ด๋ฏธ์ง€ ๋ฌด๊ฒฐ์„ฑ ๊ฒ€์ฆ
    App->>OtaData: esp_ota_set_boot_partition() โ€” ๋‹ค์Œ ๋ถ€ํŒ…=ota_1
    App->>Boot: ์žฌ๋ถ€ํŒ…
    Boot->>OtaData: ์–ด๋А ์Šฌ๋กฏ ๋ถ€ํŒ…ํ• ์ง€ ํ™•์ธ
    Boot->>Flash: ota_1์˜ ์ƒˆ ํŽŒ์›จ์–ด ๋กœ๋“œ/์‹คํ–‰

์ด ๊ตฌ์กฐ ๋•๋ถ„์— ๋‹ค์šด๋กœ๋“œ ๋„์ค‘ ์ „์›์ด ๊บผ์ ธ๋„ ์›๋ž˜ ์Šฌ๋กฏ(ota_0)์€ ๊ทธ๋Œ€๋กœ ๋ฉ€์ฉกํ•ด์„œ ๊ธฐ๊ธฐ๊ฐ€ ์ฃฝ์ง€ ์•Š๋Š”๋‹ค.

๋ถ€ํŠธ๋กœ๋”์˜ ๋ถ€ํŒ… ์„ ํƒ

**๋ถ€ํŠธ๋กœ๋”(bootloader)**๋Š” ์ „์›์ด ์ผœ์งˆ ๋•Œ ๊ฐ€์žฅ ๋จผ์ € ๋„๋Š” ์ฝ”๋“œ๋กœ, ํŒŒํ‹ฐ์…˜ ํ…Œ์ด๋ธ”๊ณผ otadata๋ฅผ ์ฝ์–ด ์–ด๋А ์•ฑ์„ ์‹คํ–‰ํ• ์ง€ ๊ฒฐ์ •ํ•œ๋‹ค.

sequenceDiagram
    autonumber
    participant BL as 2์ฐจ ๋ถ€ํŠธ๋กœ๋”
    participant PT as ํŒŒํ‹ฐ์…˜ ํ…Œ์ด๋ธ”(0x8000)
    participant OD as otadata
    participant App as ์„ ํƒ๋œ ์•ฑ ์Šฌ๋กฏ
    BL->>PT: ํŒŒํ‹ฐ์…˜ ๋ ˆ์ด์•„์›ƒ ์ฝ๊ธฐ
    BL->>OD: ์–ด๋А OTA ์Šฌ๋กฏ์ด ํ™œ์„ฑ์ธ์ง€ ํ™•์ธ
    alt otadata ๋น„์–ด์žˆ์Œ/์†์ƒ
        BL->>App: factory ์•ฑ์œผ๋กœ ํด๋ฐฑ
    else ์œ ํšจํ•œ OTA ์Šฌ๋กฏ ์ง€์ •
        BL->>App: ์ง€์ •๋œ ota_N ์•ฑ ๋กœ๋“œ/์‹คํ–‰
    end

์•ˆ์ „์žฅ์น˜: Rollback๊ณผ Anti-Rollback

  • Rollback(๋กค๋ฐฑ): ์ƒˆ ํŽŒ์›จ์–ด๊ฐ€ ์ฒซ ๋ถ€ํŒ… ์‹œ ์ž๊ฐ€์ง„๋‹จ์— ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ๋ถ€ํŒ… ์งํ›„ ๊ณ„์† ์ฃฝ์œผ๋ฉด, ๋ถ€ํŠธ๋กœ๋”๊ฐ€ ์ž๋™์œผ๋กœ ์ด์ „ ์ •์ƒ ์Šฌ๋กฏ์œผ๋กœ ๋˜๋Œ๋ฆฐ๋‹ค.
    • ์ƒˆ ์•ฑ์€ ์ฒซ ๋ถ€ํŒ…์—์„œ ์ •์ƒ ํ™•์ธ ํ›„ esp_ota_mark_app_valid_cancel_rollback()๋ฅผ ํ˜ธ์ถœํ•ด โ€œ๋‚˜ ์ •์ƒโ€์ด๋ผ๊ณ  ํ™•์ •ํ•ด์•ผ ํ•œ๋‹ค.
    • ํ™•์ • ์—†์ด ์ฃฝ์œผ๋ฉด ์ƒํƒœ๊ฐ€ PENDING_VERIFY โ†’ ABORTED๋กœ ๋„˜์–ด๊ฐ€๋ฉฐ ๋˜๋Œ์•„๊ฐ„๋‹ค.
  • Anti-Rollback(๋‹ค์šด๊ทธ๋ ˆ์ด๋“œ ๋ฐฉ์ง€): eFuse(1ํšŒ์„ฑ ํ•˜๋“œ์›จ์–ด ํ“จ์ฆˆ)์— ๋ณด์•ˆ ๋ฒ„์ „์„ ๊ธฐ๋กํ•ด, ์˜ˆ์ „ ์ทจ์•ฝ ๋ฒ„์ „์œผ๋กœ ๋˜๋Œ๋ฆฌ๋Š” ๊ณต๊ฒฉ์„ ์ฐจ๋‹จํ•œ๋‹ค. 32๋น„ํŠธ๋ผ ์ตœ๋Œ€ 32๋ฒˆ์˜ anti-rollback ๊ฐฑ์‹  ํ•œ๋„๊ฐ€ ์žˆ๋‹ค.

ํ•ต์‹ฌ: โ€œ์•Œ๋ฆผ โ†’ ์—…๋ฐ์ดํŠธ ๋ฒ„ํŠผโ€ UX๋Š” ์–ด๋–ป๊ฒŒ ๋งŒ๋“œ๋Š”๊ฐ€

์›ํ•˜๋Š” ๊ฒฝํ—˜์˜ ๊ด€๊ฑด์€ **โ€œ๊ธฐ๊ธฐ๊ฐ€ ์ƒˆ ๋ฒ„์ „์„ ์–ด๋–ป๊ฒŒ ์•Œ์•„์ฑ„๋А๋ƒโ€**์ด๊ณ , ํฌ๊ฒŒ ๋‘ ๋ฐฉ์‹์ด๋‹ค.

1) Pull ๋ฐฉ์‹ (ํด๋ง + ๋ฒ„์ „ ๋งค๋‹ˆํŽ˜์ŠคํŠธ)

๊ธฐ๊ธฐ๊ฐ€ ์ฃผ๊ธฐ์ ์œผ๋กœ ์„œ๋ฒ„์˜ ์ž‘์€ JSON(๋งค๋‹ˆํŽ˜์ŠคํŠธ)์„ ํ™•์ธํ•œ๋‹ค.

{ "version": "1.2.0", "url": "https://.../fw_1.2.0.bin", "sha256": "..." }

๊ธฐ๊ธฐ๊ฐ€ ์ž๊ธฐ ๋ฒ„์ „๊ณผ ๋น„๊ตํ•ด์„œ ๋” ๋†’์œผ๋ฉด โ€œ์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅโ€์œผ๋กœ ํ‘œ์‹œ โ†’ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๊ทธ๋•Œ url์„ ๋ฐ›์•„ OTA ์ ˆ์ฐจ ์‹คํ–‰. ์„œ๋ฒ„ ์ธํ”„๋ผ๊ฐ€ ๋‹จ์ˆœ(์ •์  ํŒŒ์ผ ํ˜ธ์ŠคํŒ…์ด๋ฉด ์ถฉ๋ถ„)ํ•˜์ง€๋งŒ, ํ™•์ธ ์ฃผ๊ธฐ๋งŒํผ ์•Œ๋ฆผ์ด ๋Šฆ๊ณ  ๋ถˆํ•„์š”ํ•œ ํŠธ๋ž˜ํ”ฝ์ด ์žˆ๋‹ค.

2) Push ๋ฐฉ์‹ (MQTT ์ƒ์‹œ ์—ฐ๊ฒฐ)

**MQTT(Message Queuing Telemetry Transport)**๋Š” ์ €์ „๋ ฅยท์ €๋Œ€์—ญํญ ๊ธฐ๊ธฐ์— ์ตœ์ ํ™”๋œ ๋ฐœํ–‰/๊ตฌ๋…(pub/sub) ๊ฒฝ๋Ÿ‰ ๋ฉ”์‹œ์ง• ํ”„๋กœํ† ์ฝœ์ด๋‹ค. ๊ธฐ๊ธฐ๊ฐ€ ๋ธŒ๋กœ์ปค์— ์ƒ์‹œ ์—ฐ๊ฒฐํ•ด OTA ํ† ํ”ฝ์„ ๊ตฌ๋…ํ•˜๋ฉด, ์„œ๋ฒ„๊ฐ€ ์ƒˆ ๋ฒ„์ „์„ publishํ•˜๋Š” ์ˆœ๊ฐ„ ์ฆ‰์‹œ ๊ธฐ๊ธฐ์— ๋„๋‹ฌํ•œ๋‹ค.

sequenceDiagram
    autonumber
    participant D as ๊ธฐ๊ธฐ(๊ตฌ๋…์ž)
    participant B as ๋ธŒ๋กœ์ปค
    participant S as ์„œ๋ฒ„(๋ฐœํ–‰์ž)
    D->>B: topic "device/123/ota" ๊ตฌ๋… + ์ƒ์‹œ ์—ฐ๊ฒฐ
    Note over D,B: ํ‰์†Œ์—” ์œ ํœด, ์—ฐ๊ฒฐ๋งŒ ์œ ์ง€
    S->>B: publish "v1.2.0 ์žˆ์Œ" to "device/123/ota"
    B-->>D: ์ฆ‰์‹œ ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ (์•Œ๋ฆผ!)

MQTT์—์„œ ๊ผญ ์•Œ์•„์•ผ ํ•  4๊ฐ€์ง€:

  • Broker(๋ธŒ๋กœ์ปค): ๋ชจ๋“  ๋ฉ”์‹œ์ง€๊ฐ€ ๊ฑฐ์ณ ๊ฐ€๋Š” ์ค‘์•™ ํ—ˆ๋ธŒ. ๊ตฌ๋… ๊ด€๋ฆฌยท๋ผ์šฐํŒ… ๋‹ด๋‹น (์˜ˆ: Mosquitto, HiveMQ, AWS IoT Core).
  • Topic(ํ† ํ”ฝ): device/123/ota ๊ฐ™์€ ๊ณ„์ธตํ˜• ์ฃผ์†Œ. ๊ตฌ๋…์ž๋Š” ๊ด€์‹ฌ ํ† ํ”ฝ๋งŒ ๋ฐ›๋Š”๋‹ค.
  • QoS(์ „๋‹ฌ ๋ณด์ฆ): 0 ์ตœ๋Œ€ 1ํšŒ(fire-and-forget), 1 ์ตœ์†Œ 1ํšŒ(์ค‘๋ณต ๊ฐ€๋Šฅ), 2 ์ •ํ™•ํžˆ 1ํšŒ. OTA ์•Œ๋ฆผ์—” ๋ณดํ†ต QoS 1 ์ด์ƒ.
  • Retained / Last Will: ํ† ํ”ฝ์˜ ๋งˆ์ง€๋ง‰ ๋ฉ”์‹œ์ง€๋ฅผ ์ƒˆ ๊ตฌ๋…์ž์—๊ฒŒ ์ž๋™ ์ „๋‹ฌ(retained), ๊ธฐ๊ธฐ๊ฐ€ ๊ฐ‘์ž๊ธฐ ๋Š๊ธฐ๋ฉด ๋Œ€์‹  ๋ณด๋‚ด๋Š” ์œ ์–ธ ๋ฉ”์‹œ์ง€(LWT)๋กœ ์˜จ๋ผ์ธ ์—ฌ๋ถ€ ๊ฐ์ง€.

๋ชฉํ‘œ(์•Œ๋ฆผ + ๋ฒ„ํŠผ, USB ์ง€์–‘)์—๋Š” Push(MQTT) ๋˜๋Š” ๊ด€๋ฆฌํ˜• ํ”Œ๋žซํผ์ด ๊ฐ€์žฅ ์ž˜ ๋งž๋Š”๋‹ค. ์•Œ๋ฆผ๋งŒ ๋จผ์ € ์ฃผ๊ณ  ์‹ค์ œ ๋‹ค์šด๋กœ๋“œ/์ ์šฉ์€ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅธ ์ด๋ฒคํŠธ์—์„œ ํŠธ๋ฆฌ๊ฑฐํ•˜๋ฉด, โ€œ์•Œ๋ฆผ โ†’ ๋ฒ„ํŠผ โ†’ ๊ฐฑ์‹ โ€ ํ๋ฆ„์ด ๊ทธ๋Œ€๋กœ ๊ตฌํ˜„๋œ๋‹ค. ์ง„ํ–‰๋ฅ ยท์„ฑ๊ณต/์‹คํŒจ๋„ ๊ฐ™์€ MQTT ์ฑ„๋„๋กœ ๋˜๋ณด๊ณ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ESP32์—์„œ OTA๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์„ ํƒ์ง€

๋ฐฉ๋ฒ•ํŠน์ง•์•Œ๋ฆผ/๋ฒ„ํŠผ UX
esp_https_ota (ESP-IDF)HTTPS๋กœ ์ด๋ฏธ์ง€ ๋ฐ›์•„ ๊ตฝ๋Š” ํ‘œ์ค€ ์ปดํฌ๋„ŒํŠธ. ์„œ๋ฒ„ยท๋งค๋‹ˆํŽ˜์ŠคํŠธ ์ง์ ‘ ๊ตฌ์„ฑ์ง์ ‘ ๊ตฌํ˜„
ESP RainMakerEspressif ๊ด€๋ฆฌํ˜• ํด๋ผ์šฐ๋“œ. esp_rmaker_ota_enable() ํ•œ ์ค„๋กœ OTA + ํฐ ์•ฑ + ์•Œ๋ฆผ + ์ง„ํ–‰๋ฅ  ๋˜๋ณด๊ณ  (AWS S3 ๊ธฐ๋ฐ˜, MQTT Force Push)๊ฑฐ์˜ ์™„์„ฑํ˜• ์ œ๊ณต
Arduino ArduinoOTA/Update๊ฐœ๋ฐœ ๋‹จ๊ณ„ ๋กœ์ปฌ ๋„คํŠธ์›Œํฌ ์—…๋กœ๋“œ์— ํŽธ๋ฆฌ๋ฐฐํฌ์šฉ์œผ๋ก  ๋ถ€์ ํ•ฉ
esp32FOTA ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌJSON ๋งค๋‹ˆํŽ˜์ŠคํŠธ ๊ธฐ๋ฐ˜ ํด๋ง OTA๋ฅผ ๊ฐ„๋‹จํžˆ ๊ตฌํ˜„๋งค๋‹ˆํŽ˜์ŠคํŠธ๋กœ ๊ตฌํ˜„
AWS IoT / Azure Device Update๋Œ€๊ทœ๋ชจ fleet ์บ ํŽ˜์ธยท๋กค์•„์›ƒ ๊ด€๋ฆฌํ”Œ๋žซํผ ์ œ๊ณต

์‹ค์ „ ํŒŒ์ดํ”„๋ผ์ธ: ๋‚ด๊ฐ€ ๊ฐœ๋ฐœ โ†’ ๋ฐฐํฌ โ†’ ๋ณด๋“œ๊ฐ€ ์Šค์Šค๋กœ ์„ค์น˜

๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ „์ œ โ€” โ€œOTA ํด๋ผ์ด์–ธํŠธ๋Š” ์ด๋ฏธ ํŒ ํŽŒ์›จ์–ด ์•ˆ์— ์žˆ๋‹คโ€

OTA๊ฐ€ ์„ฑ๋ฆฝํ•˜๋ ค๋ฉด, ์ฒ˜์Œ ํŒ๋งคํ•œ v1.0.0 ํŽŒ์›จ์–ด ์•ˆ์— โ€œ์—…๋ฐ์ดํŠธ๋ฅผ ํ™•์ธยท๋‹ค์šด๋กœ๋“œยท์„ค์น˜ํ•˜๋Š” ์ฝ”๋“œ(OTA ํด๋ผ์ด์–ธํŠธ)โ€œ๊ฐ€ ์ด๋ฏธ ๋“ค์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๋‚˜์ค‘์— ์„œ๋ฒ„์— ๋ญ˜ ์˜ฌ๋ ค์„œ ๊ธฐ๊ธฐ๋ฅผ โ€œ์‹คํ–‰โ€์‹œํ‚ค๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ, ๊ธฐ๊ธฐ ์•ˆ์˜ ๊ทธ ์ฝ”๋“œ๊ฐ€ ์Šค์Šค๋กœ ์„œ๋ฒ„๋ฅผ ํ™•์ธํ•˜๊ณ  ์ž๊ธฐ ์ž์‹ ์„ ๊ฐˆ์•„๋ผ์šด๋‹ค. ๊ฐœ๋ฐœ์ž๊ฐ€ ์›๊ฒฉ์—์„œ ์†๋Œ€๋Š” ๊ฑด ์˜ค์ง โ€œ์„œ๋ฒ„์— ์ƒˆ bin๊ณผ ๋ฒ„์ „ ์ •๋ณด๋ฅผ ์˜ฌ๋ฆฌ๋Š” ๊ฒƒโ€๋ฟ์ด๋‹ค.

๋งŒ์•ฝ v1.0.0์— OTA ํด๋ผ์ด์–ธํŠธ๋ฅผ ์•ˆ ๋„ฃ๊ณ  ํŒ”์•˜๋‹ค๋ฉด, ๊ทธ ๋ณด๋“œ๋“ค์€ ์˜์˜ USB๋กœ๋งŒ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ์ฒซ ์ถœํ•˜ ๋•Œ OTA ํด๋ผ์ด์–ธํŠธ๋ฅผ ๊ผญ ํฌํ•จ์‹œํ‚ค๋Š” ๊ฒŒ ํ•ต์‹ฌ์ด๋‹ค.

์ „์ฒด ๊ทธ๋ฆผ

sequenceDiagram
    autonumber
    actor Dev as ๋‚˜(๊ฐœ๋ฐœ์ž)
    participant PIO as PlatformIO
    participant Host as ํŽŒ์›จ์–ด ํ˜ธ์ŠคํŒ…<br/>(S3/GitHub Release/์„œ๋ฒ„)
    participant Broker as MQTT ๋ธŒ๋กœ์ปค
    participant Board as ESP32(v1.0.0 ์‹คํ–‰ ์ค‘)
    actor User as ์ตœ์ข… ์‚ฌ์šฉ์ž(์•ฑ)

    Dev->>PIO: ๋ฒ„์ „ 1.1.0์œผ๋กœ ๋นŒ๋“œ
    PIO-->>Dev: firmware.bin ์ƒ์„ฑ
    Dev->>Host: firmware.bin + manifest.json ์—…๋กœ๋“œ
    Dev->>Broker: "v1.1.0 ๋‚˜์™”์Œ" publish (์„ ํƒ)
    Broker-->>Board: OTA ํ† ํ”ฝ์œผ๋กœ ์•Œ๋ฆผ ์ „๋‹ฌ
    Board-->>User: ์•ฑ์— "์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅ" ํ‘œ์‹œ
    User->>Board: [์—…๋ฐ์ดํŠธ] ๋ฒ„ํŠผ ํด๋ฆญ
    Board->>Host: manifest.json ์ฝ๊ณ  firmware.bin ์š”์ฒญ(HTTPS)
    Host-->>Board: bin ์ŠคํŠธ๋ฆฌ๋ฐ
    Board->>Board: ๋น„ํ™œ์„ฑ ์Šฌ๋กฏ(ota_1)์— ๊ธฐ๋ก+๊ฒ€์ฆ
    Board->>Board: ๋ถ€ํŒ… ์Šฌ๋กฏ ์ „ํ™˜ ํ›„ ์žฌ๋ถ€ํŒ…
    Board-->>User: v1.1.0๋กœ ์—…๋ฐ์ดํŠธ ์™„๋ฃŒ ๋ณด๊ณ 

Step 1 โ€” PlatformIO๋กœ ๋นŒ๋“œํ•˜๊ณ  ๋ฒ„์ „์„ ์‹ฌ๋Š”๋‹ค

๋ฒ„์ „์„ ์ฝ”๋“œ์— ๋ฐ•์•„๋‘ฌ์•ผ ๊ธฐ๊ธฐ๊ฐ€ โ€œ๋‚ด ๋ฒ„์ „ vs ์„œ๋ฒ„ ๋ฒ„์ „โ€์„ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋‹ค. platformio.ini์—์„œ ๋นŒ๋“œ ํ”Œ๋ž˜๊ทธ๋กœ ์ฃผ์ž…ํ•œ๋‹ค.

; platformio.ini
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
build_flags = -DFW_VERSION="1.1.0"      ; ์ฝ”๋“œ์—์„œ ์ด ๊ฐ’์œผ๋กœ ์ž๊ธฐ ๋ฒ„์ „ ์ธ์‹
lib_deps = chrisjoyce911/esp32FOTA      ; OTA ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

๋นŒ๋“œํ•˜๋ฉด ์‚ฐ์ถœ๋ฌผ์€ ์—ฌ๊ธฐ์— ์ƒ๊ธด๋‹ค:

.pio/build/esp32dev/firmware.bin        โ† ์ด ํŒŒ์ผ์„ ๋ฐฐํฌํ•œ๋‹ค

Step 2 โ€” bin์„ โ€œ์–ด๋”˜๊ฐ€โ€์— ์˜ฌ๋ฆฌ๊ณ , ๋ฒ„์ „ ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ํ•จ๊ป˜ ๋‘”๋‹ค

firmware.bin์„ ๊ธฐ๊ธฐ๊ฐ€ HTTPS๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๊ณณ์— ์˜ฌ๋ฆฐ๋‹ค. ํ›„๋ณด:

ํ˜ธ์ŠคํŒ…์„ฑ๊ฒฉ
AWS S3 / ํด๋ผ์šฐ๋“œ ์Šคํ† ๋ฆฌ์ง€์ •์  ํŒŒ์ผ, ํ™•์žฅ์„ฑ ์ข‹์Œ. RainMaker๋„ ๋‚ด๋ถ€์ ์œผ๋กœ S3 ์‚ฌ์šฉ
GitHub Releases๋ฌด๋ฃŒยท๊ฐ„๋‹จ. ๋ฆด๋ฆฌ์Šค์— bin ์ฒจ๋ถ€ํ•˜๋ฉด ๊ณ ์ • URL ์ œ๊ณต
์ง์ ‘ ์šด์˜ํ•˜๋Š” nginx/์„œ๋ฒ„์™„์ „ํ•œ ํ†ต์ œ, ์ ‘๊ทผ์ œ์–ด ์ž์œ 

๊ทธ๋ฆฌ๊ณ  **๋ฒ„์ „ ์ •๋ณด๋ฅผ ๋‹ด์€ ์ž‘์€ JSON(๋งค๋‹ˆํŽ˜์ŠคํŠธ)**์„ ๊ฐ™์ด ์˜ฌ๋ฆฐ๋‹ค. ๊ธฐ๊ธฐ๋Š” bin์ด ์•„๋‹ˆ๋ผ ์ด JSON์„ ๋จผ์ € ๋ณธ๋‹ค.

// manifest.json  (esp32FOTA ํ˜•์‹ ์˜ˆ์‹œ)
{
  "type": "my-board",
  "version": "1.1.0",
  "host": "https://fw.example.com",
  "port": 443,
  "bin": "/firmware/my-board_1.1.0.bin"
}

Step 3 โ€” ๊ธฐ๊ธฐ์— โ€œ์ƒˆ ๋ฒ„์ „ ๋‚˜์™”๋‹คโ€๊ณ  ์•Œ๋ฆฐ๋‹ค (๋‘ ๋ฐฉ๋ฒ•)

  • Push (MQTT): ์„œ๋ฒ„๊ฐ€ device/+/ota ํ† ํ”ฝ์— ์ƒˆ ๋ฒ„์ „์„ publish โ†’ ์˜จ๋ผ์ธ ๊ธฐ๊ธฐ๊ฐ€ ์ฆ‰์‹œ ๋ฐ›์•„ ์•ฑ์— ๋ฐฐ์ง€ ํ‘œ์‹œ. ์‹ค์‹œ๊ฐ„์„ฑ์ด ํ•„์š”ํ•˜๋ฉด ์ด ๋ฐฉ์‹.
  • Pull (ํด๋ง): ๊ธฐ๊ธฐ๊ฐ€ ๋ถ€ํŒ… ์‹œ + N์‹œ๊ฐ„๋งˆ๋‹ค manifest.json์„ GETํ•ด์„œ ์ž๊ธฐ ๋ฒ„์ „๋ณด๋‹ค ๋†’์œผ๋ฉด ํ‘œ์‹œ. ์„œ๋ฒ„๊ฐ€ ๋‹จ์ˆœ(์ •์  ํŒŒ์ผ๋งŒ)ํ•ด์„œ ์‹œ์ž‘ํ•˜๊ธฐ ์‰ฝ๋‹ค.

๋‘˜ ๋‹ค โ€œ์•Œ๋ฆผ๋งŒโ€ ํ•˜๋Š” ๋‹จ๊ณ„๋‹ค. ์‹ค์ œ ๋‹ค์šด๋กœ๋“œ๋Š” ์•„์ง ์‹œ์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค โ€” ์‚ฌ์šฉ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋Š” ์ด๋ฒคํŠธ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.

Step 4 โ€” ๋ฒ„ํŠผ ํด๋ฆญ โ†’ ๊ธฐ๊ธฐ๊ฐ€ ์Šค์Šค๋กœ ๋‹ค์šดยท๊ฒ€์ฆยท์„ค์น˜ยท์žฌ๋ถ€ํŒ…

์‚ฌ์šฉ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด(์•ฑ์ด MQTT/BLE/HTTP๋กœ ๊ธฐ๊ธฐ์— โ€œ์—…๋ฐ์ดํŠธ ์‹œ์ž‘โ€ ์‹ ํ˜ธ๋ฅผ ๋ณด๋ƒ„), ๊ธฐ๊ธฐ ์•ˆ์˜ OTA ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๊ฐ€ ๋‚˜๋จธ์ง€๋ฅผ ์ „๋ถ€ ์ž๋™์œผ๋กœ ํ•œ๋‹ค.

#include <esp32FOTA.hpp>
 
// ๋‚ด ๋ณด๋“œ ํƒ€์ž…, ํ˜„์žฌ ๋ฒ„์ „์„ ์•Œ๋ ค์ฃผ๋ฉฐ OTA ํด๋ผ์ด์–ธํŠธ ์ƒ์„ฑ
esp32FOTA fota("my-board", FW_VERSION);   // FW_VERSION = "1.1.0"
 
void setup() {
  fota.setManifestURL("https://fw.example.com/manifest.json");
  // (๊ถŒ์žฅ) ์„œ๋ช…/์ธ์ฆ์„œ ๊ฒ€์ฆ ์„ค์ • โ€” ์œ„์กฐ ํŽŒ์›จ์–ด ์ฐจ๋‹จ
}
 
// ์‚ฌ์šฉ์ž๊ฐ€ "์—…๋ฐ์ดํŠธ" ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜
void onUpdateButtonPressed() {
  if (fota.execHTTPcheck()) {     // ๋งค๋‹ˆํŽ˜์ŠคํŠธ ๋ฒ„์ „ > ๋‚ด ๋ฒ„์ „ ?
    fota.execOTA();               // ์—ฌ๊ธฐ์„œ ์ „๋ถ€ ์ž๋™ ์ˆ˜ํ–‰ โ†“
    // 1) firmware.bin ์ŠคํŠธ๋ฆฌ๋ฐ ๋‹ค์šด๋กœ๋“œ
    // 2) ๋น„ํ™œ์„ฑ ์Šฌ๋กฏ(ota_1)์— esp_ota_write๋กœ ๊ธฐ๋ก
    // 3) ์ด๋ฏธ์ง€ ๋ฌด๊ฒฐ์„ฑ/์„œ๋ช… ๊ฒ€์ฆ
    // 4) otadata ํฌ์ธํ„ฐ๋ฅผ ์ƒˆ ์Šฌ๋กฏ์œผ๋กœ ๋ณ€๊ฒฝ
    // 5) esp_restart() โ€” ์žฌ๋ถ€ํŒ…
    // ์žฌ๋ถ€ํŒ… ํ›„ ๋ถ€ํŠธ๋กœ๋”๊ฐ€ ota_1์„ ์„ ํƒ โ†’ v1.1.0 ์‹คํ–‰
  }
}

โ€๋‚ด๊ฐ€ ์‹คํ–‰ ์•ˆ ์‹œ์ผœ๋„ ์ž๋™์œผ๋กœ ์„ค์น˜๋˜๋Š”โ€ ์ด์œ 

ํ•ต์‹ฌ์€ ๋‹ค์šด๋กœ๋“œ๋œ bin์„ ์‚ฌ๋žŒ์ด ์–ด๋””์— ๋ณต์‚ฌํ•˜๊ฑฐ๋‚˜ ์‹คํ–‰ํ•˜๋Š” ๊ฐœ๋…์ด ์•„๋‹ˆ๋ผ๋Š” ์ ์ด๋‹ค. execOTA()๊ฐ€ ๋ฐ›์€ ๋ฐ”์ดํŠธ๋ฅผ ๊ณง๋ฐ”๋กœ ๋น„ํ™œ์„ฑ ํŒŒํ‹ฐ์…˜(ota_1)์— ๊ตฝ๊ณ , otadata์˜ ๋ถ€ํŒ… ํฌ์ธํ„ฐ๋งŒ ๋ฐ”๊พผ ๋’ค ์žฌ๋ถ€ํŒ…ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ถ€ํŠธ๋กœ๋”๊ฐ€ ๋‹ค์Œ ๋ถ€ํŒ…์—์„œ ์ƒˆ ์Šฌ๋กฏ์„ ์ž๋™์œผ๋กœ ๊ณจ๋ผ ์‹คํ–‰ํ•œ๋‹ค. ์ฆ‰:

  • ๋‹ค์šด๋กœ๋“œ == ์„ค์น˜๋‹ค. ๋ฐ›์€ ์ฆ‰์‹œ ํ”Œ๋ž˜์‹œ์— ๊ธฐ๋ก๋˜๋ฏ€๋กœ ๋ณ„๋„ โ€œ์„ค์น˜ ์‹คํ–‰โ€ ๋‹จ๊ณ„๊ฐ€ ์—†๋‹ค.
  • ์„ฑ๊ณต ํ™•์ธ ์ „๊นŒ์ง€ ์›๋ž˜ ์Šฌ๋กฏ(ota_0)์€ ์‚ด์•„ ์žˆ์–ด, ์ƒˆ ํŽŒ์›จ์–ด๊ฐ€ ๋ถ€ํŒ…์— ์‹คํŒจํ•˜๋ฉด ์ž๋™ ๋กค๋ฐฑ๋œ๋‹ค.
  • ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•˜๋Š” ์ผ์€ ์˜ค์ง **Step 1~3(๋นŒ๋“œยท์—…๋กœ๋“œยท์•Œ๋ฆผ)**๋ฟ. Step 4์˜ ๋ฌผ๋ฆฌ์  ์„ค์น˜๋Š” ์ „๋ถ€ ๊ธฐ๊ธฐ๊ฐ€ ํ•œ๋‹ค.

๋ณด์•ˆ: ์ด๋ฏธ์ง€ ์„œ๋ช…๊ณผ Secure Boot

OTA๋Š” โ€œ์›๊ฒฉ์—์„œ ์ฝ”๋“œ๋ฅผ ๋ฐ›์•„ ์‹คํ–‰โ€ํ•˜๋Š” ํ†ต๋กœ๋ผ, ๊ฒ€์ฆ์ด ์—†์œผ๋ฉด ๊ณต๊ฒฉ์ž๊ฐ€ ์•…์„ฑ ํŽŒ์›จ์–ด๋ฅผ ๋ฐ€์–ด๋„ฃ๋Š” ๋ฐฑ๋„์–ด๊ฐ€ ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ๋‘ ๊ฒน์˜ ๋ฐฉ์–ด๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

  • ์ „์†ก ๊ตฌ๊ฐ„ ์•”ํ˜ธํ™”: HTTPS/TLS๋กœ ๋ฐ›์•„ ์ค‘๊ฐ„์žยทDNS ์Šคํ‘ธํ•‘ ๋ฐฉ์ง€ (RainMaker๋Š” ์„œ๋ฒ„ ์ธ์ฆ์„œ ๊ฒ€์ฆ ํฌํ•จ).
  • ์ด๋ฏธ์ง€ ์„œ๋ช… ๊ฒ€์ฆ (Secure Boot): ์„œ๋ช…๋œ ์ด๋ฏธ์ง€๋งŒ ๋ถ€ํŒ…์„ ํ—ˆ์šฉํ•œ๋‹ค. ESP32 Secure Boot v2๋Š” RSA-3072(PSS) ๊ณต๊ฐœํ‚ค ์•”ํ˜ธ๋กœ ๋ถ€ํŠธ๋กœ๋”ยท์•ฑ์„ ๊ฒ€์ฆํ•˜๊ณ , ๊ณต๊ฐœํ‚ค์˜ ์ง€๋ฌธ์„ eFuse์— ๊ฐ์ธํ•ด ์œ„ยท๋ณ€์กฐ๋ฅผ ๋ง‰๋Š”๋‹ค.
sequenceDiagram
    autonumber
    participant ROM as ROM ๋ถ€ํŠธ๋กœ๋”(๋ณ€๊ฒฝ๋ถˆ๊ฐ€)
    participant BL as 2์ฐจ ๋ถ€ํŠธ๋กœ๋”
    participant App as ์•ฑ ์ด๋ฏธ์ง€
    participant eF as eFuse(๊ณต๊ฐœํ‚ค ์ง€๋ฌธ)
    ROM->>eF: ๊ณต๊ฐœํ‚ค ์ง€๋ฌธ ์ฝ๊ธฐ
    ROM->>BL: 2์ฐจ ๋ถ€ํŠธ๋กœ๋” ์„œ๋ช… ๊ฒ€์ฆ
    Note over ROM,BL: ์‹คํŒจ ์‹œ ๋ถ€ํŒ… ์ค‘๋‹จ
    BL->>App: ์•ฑ ์ด๋ฏธ์ง€ ์„œ๋ช… ๊ฒ€์ฆ (๋ถ€ํŒ… ์‹œ + OTA ์‹œ)
    App-->>App: ๊ฒ€์ฆ ํ†ต๊ณผ โ†’ ์‹คํ–‰

ํ•ต์‹ฌ์€ OTA๋กœ ๋ฐ›์€ ์ƒˆ ์ด๋ฏธ์ง€๋„ ๋ถ€ํŒ… ์‹œ์ ๊ณผ OTA ์ ์šฉ ์‹œ์  ๋ชจ๋‘ ๊ฐ™์€ eFuse ๊ณต๊ฐœํ‚ค ์ง€๋ฌธ์œผ๋กœ ์„œ๋ช… ๊ฒ€์ฆ์„ ํ†ต๊ณผํ•ด์•ผ ์ฑ„ํƒ๋œ๋‹ค๋Š” ์ ์ด๋‹ค. ์ฆ‰ esp_ota_end()์˜ ๋ฌด๊ฒฐ์„ฑ ๊ฒ€์ฆ ์œ„์—, Secure Boot๋Š” โ€œ์ •ํ’ˆ ์„œ๋ช…โ€๊นŒ์ง€ ์š”๊ตฌํ•˜๋Š” ์ƒ์œ„ ๋ฐฉ์–ด์„ ์ด๋‹ค.

  • Secure Boot vs Flash Encryption: Secure Boot๋Š” ์œ„์กฐ ์ฝ”๋“œ ์‹คํ–‰์„ ๋ง‰๊ณ (๋ฌด๊ฒฐ์„ฑ), Flash Encryption์€ ํ”Œ๋ž˜์‹œ ๋‚ด์šฉ ์ฝ๊ธฐ๋ฅผ ๋ง‰๋Š”๋‹ค(๊ธฐ๋ฐ€์„ฑ). ๋ชฉ์ ์ด ๋‹ฌ๋ผ ํ•จ๊ป˜ ์“ฐ๊ธฐ๋ฅผ ๊ถŒ์žฅํ•œ๋‹ค.
  • Anti-Rollback: ์ทจ์•ฝํ•œ ๊ตฌ๋ฒ„์ „์œผ๋กœ์˜ ๊ฐ•์ œ ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œ๋ฅผ ์ฐจ๋‹จ(์œ„ ์•ˆ์ „์žฅ์น˜ ์ ˆ ์ฐธ๊ณ ).
  • ์ผ๋ฐ˜์  ์œ„ํ˜‘: spoofing, tampering, replay, DoS, ๊ถŒํ•œ ์ƒ์Šน โ†’ ๊ฒ€์ฆ ์—†๋Š” OTA๋Š” ๊ณง ๋ฐฑ๋„์–ด๋ผ๋Š” ๊ด€์ ์ด ํ•„์š”ํ•˜๋‹ค.

์ฐธ๊ณ  ๋ฌธ์„œ