MCM_GitHub_OTA Library
MCM_GitHub_OTA Library
요약
MCM_GitHub_OTA는 ESP32 펌웨어를 GitHub Releases에서 자동으로 내려받아 플래시하는 Arduino 라이브러리입니다. WiFi뿐 아니라 W5500 이더넷 모듈을 통한 유선 OTA를 공식 지원하며, SSL 인증서 만료로 인한 현장 기기 벽돌화를 방지하는 Late Fallback 메커니즘을 내장하고 있습니다. WiFi를 사용할 수 없는 산업·현장 환경에서도 GitHub CI/CD 파이프라인과 연동해 원격 펌웨어 배포를 자동화할 수 있다는 점에서 주목할 만한 프로젝트입니다.
개요: 현장 기기를 어떻게 업데이트할 것인가
배포된 임베디드 기기 수가 늘수록 펌웨어 유지보수는 점점 무거운 문제가 됩니다. 버그 패치 하나를 적용하기 위해 수십, 수백 대의 현장 기기에 물리적으로 접근하는 것은 현실적으로 불가능합니다. OTA(Over-The-Air) 업데이트가 그 해답이지만, 산업 현장에서는 WiFi 자체를 쓸 수 없는 경우가 많습니다. EMI(전자기 간섭)가 심한 공장, 유선 전용 보안망, PoE 인프라 위에서 동작하는 설비가 대표적입니다.
MCM_GitHub_OTA 라이브러리는 이 간극을 메웁니다. W5500 이더넷 모듈을 네트워크 인터페이스로 활용해 GitHub Releases를 소스로 하는 유선 OTA 파이프라인을 구성할 수 있습니다. 개발자는 GitHub에 새 릴리스를 올리는 것만으로 현장의 모든 기기를 자동 업데이트할 수 있습니다.
시스템 아키텍처: GitHub → W5500 → ESP32
전체 업데이트 흐름은 세 단계로 구성됩니다. ① GitHub API로 최신 버전 태그를 조회하고, ② CDN에서 .bin 바이너리를 다운로드한 뒤, ③ ESP32 내부 OTA 파티션에 플래시하고 재부팅합니다.
네트워크 인터페이스 선택은 생성자에서 결정됩니다. enableEthernet과 enableWiFi 플래그를 각각 독립적으로 설정할 수 있으며, 라이브러리가 활성 인터페이스를 자동으로 감지해 사용합니다.
// W5500 이더넷 전용 모드
MCM_GitHub_OTA ota(true, false);
// WiFi 전용 모드
MCM_GitHub_OTA ota(false, true);
// 듀얼 모드 (활성 인터페이스 자동 선택)
MCM_GitHub_OTA ota(true, true);
MCM_GitHub_OTA 라이브러리 핵심 기능
단순히 파일을 내려받아 플래시하는 것에 그치지 않고, 보안·복원력·유연성을 함께 설계한 것이 이 라이브러리의 핵심입니다.
- 듀얼 네트워크 지원: WiFi와 W5500 이더넷을 동시에 지원. 생성자 플래그 하나로 전환 가능
- GitHub Releases 연동: GitHub API를 직접 파싱해 최신 릴리스 태그 및
.bin에셋을 자동으로 탐색 - 보안 연결: SSLClient(BearSSL 기반)와 Trust Anchor(Root CA)를 사용해 펌웨어 위변조를 방지
- Late Fallback 메커니즘: CDN 인증서 불일치 시 Insecure 모드로 자동 전환해 업데이트를 완료
- Private 리포지토리 지원: GitHub Personal Access Token(PAT)으로 비공개 저장소 연동 가능
- 메모리 효율: 공유 글로벌 버퍼 사용으로 대용량 바이너리 다운로드 시 힙 단편화 최소화
주요 API는 간결합니다.
// 리포지토리 설정 및 초기화
ota.begin("owner", "repo-name", "v1.0.0"); // 퍼블릭
ota.begin("owner", "repo-name", "v1.0.0", "ghp_xxxxxxxxxxxx"); // 프라이빗
// 업데이트 확인 및 실행 (블로킹)
ota.checkForUpdate();
// 최신 버전 여부 확인
bool latest = ota.isUpdated();
W5500이 OTA 안정성에 기여하는 이유
OTA는 일반적인 센서 데이터 송신과 다릅니다. 수백 KB에서 수 MB에 달하는 바이너리를 중단 없이, 순서대로, 정확하게 수신해야 합니다. 패킷 하나가 손실되거나 연결이 끊기면 플래시 실패 또는 기기 벽돌화로 이어질 수 있습니다.
W5500은 이 요구사항에 잘 맞는 선택입니다.
- 하드웨어 TCP/IP 오프로딩: TCP 소켓 관리·재전송·흐름 제어를 W5500이 독립적으로 처리. MCU는 데이터 수신에만 집중
- 유선 연결의 물리적 안정성: WiFi 대비 패킷 손실·간섭·연결 끊김 위험이 현저히 낮음
- SPI 인터페이스: ESP32와 간단한 4선 연결로 구성 가능, 추가 회로 최소화
- 8개 독립 소켓: GitHub API용 소켓과 CDN 다운로드용 소켓을 독립적으로 관리 가능
또한 PoE(Power over Ethernet) 환경과 결합하면 이더넷 케이블 한 가닥으로 전원 공급과 OTA 업데이트 채널을 동시에 확보할 수 있습니다. 케이블 배선이 이미 완료된 산업 현장에서는 추가 인프라 없이 OTA를 도입할 수 있는 실질적인 경로입니다. [추정]
인증서 관리와 보안 Fallback
임베디드 OTA의 숨은 위협은 SSL 인증서 만료입니다. GitHub와 그 CDN(Amazon S3, Azure 등)은 주기적으로 Root CA를 교체합니다. 디바이스에 내장된 Trust Anchor가 오래된 경우, 보안 연결이 실패하고 OTA가 중단됩니다. 이 상태가 지속되면 현장 기기는 스스로를 업데이트할 방법을 잃습니다.
MCM_GitHub_OTA는 이 문제를 Late Fallback 방식으로 실용적으로 해결합니다.
| 단계 | 동작 | 설명 |
|---|---|---|
| 1차 시도 | Secure 모드 | BearSSL + Trust Anchor로 API 및 CDN 연결 시도 |
| 문제 감지 | API 성공 / CDN 실패 | CDN의 Root CA가 Trust Anchor와 불일치 |
| 2차 시도 | Insecure Fallback | 인증서 검증을 생략하고 해당 세션만 다운로드 재시도 |
| 결과 | 업데이트 완료 | 이후 새 인증서가 포함된 펌웨어로 Trust Anchor 갱신 가능 |
이 구조의 핵심은 API 인증은 항상 보안 연결로 유지하고, 바이너리 다운로드 실패 시에만 예외적으로 Insecure 모드를 적용한다는 점입니다. 완벽한 보안은 아니지만, "인증서 만료로 영구 벽돌화"되는 최악의 상황을 현실적으로 방지합니다.
인증서를 직접 갱신하려면 BearSSL Certificate Utility를 통해 MCM_CertStore.h를 재생성할 수 있습니다. 포함해야 할 도메인은 다음과 같습니다.
api.github.com, github.com, objects.githubusercontent.com,
release-assets.githubusercontent.com, raw.githubusercontent.com, s3.amazonaws.com
실제 적용 시나리오
이 구조가 진가를 발휘하는 환경은 명확합니다.
- 산업 자동화 설비: EMI가 심한 공장 내부에서는 WiFi 신뢰성이 낮습니다. 유선 이더넷 기반 OTA는 설비를 멈추지 않고 펌웨어를 갱신할 수 있는 현실적인 방법입니다.
- 스마트 빌딩 / 에너지 미터: 장기간 현장에 설치된 전력 모니터링 기기는 IEC 규격 변경이나 보안 패치가 필요할 때 물리적 접근이 어렵습니다. GitHub Releases 기반 배포는 버전 이력 관리와 롤백 추적을 함께 제공합니다.
- 농업·환경 모니터링: 오지에 설치된 센서 노드는 방문 비용이 큽니다. PoE 인프라가 갖춰진 경우 단일 케이블로 전원과 OTA를 동시에 해결할 수 있습니다.
- GitHub Actions CI/CD 연동: Actions 워크플로우에서 빌드가 완료되면 자동으로 GitHub Release가 생성되고, 현장 기기가 다음
checkForUpdate()호출 시 즉시 배포를 수신합니다. 개발자가 코드를 머지하는 것만으로 현장 배포까지 자동화됩니다.
한계 및 개선 방향
MCM_GitHub_OTA는 실용적인 설계로 많은 문제를 해결하지만, 운영 환경에 따라 고려해야 할 제약이 있습니다.
현재 한계
- SSL 처리 부하: W5500이 TCP/IP를 오프로딩하더라도 BearSSL 핸드셰이크 연산은 ESP32가 전담합니다. 처리 능력이 낮은 MCU나 고빈도 체크 구조에서는 부담이 될 수 있습니다.
- 블로킹 동작:
checkForUpdate()실행 중 MCU가 점유됩니다. PID 제어, 모터 드라이브 등 실시간 루프가 있는 시스템에서는 별도 FreeRTOS 태스크로 분리해 처리해야 합니다. - ESP32 단일 플랫폼: 현재 STM32, RP2040 등 다른 MCU를 공식 지원하지 않습니다.
- GitHub 의존성: GitHub API Rate Limit 또는 서비스 장애 시 업데이트가 불가합니다.
개선 방향
이 라이브러리가 W5500 기반 산업용 플랫폼으로 확장된다면, 다음 개선이 의미 있습니다. HTTPS 요청을 W5500의 하드웨어 소켓 단에서 더 효율적으로 분산 처리하는 구조, OTA 전용 소켓 격리, 그리고 FreeRTOS 비동기 태스크와의 공식 통합이 자연스러운 다음 단계입니다. 또한 checkForUpdate()에 타임아웃 파라미터를 추가하면 실시간 시스템과의 공존 가능성이 높아집니다.
FAQ
Q1. W5100도 지원되나요, W5500만 지원하나요? Arduino Ethernet Library를 의존성으로 사용하기 때문에 W5100도 동작합니다. 다만 라이브러리 README에서는 W5500을 기준으로 명시하고 있으며, W5500이 8개 소켓과 더 넓은 버퍼를 제공하므로 OTA 용도에는 W5500을 권장합니다.
Q2. Private 리포지토리는 어떻게 연동하나요? begin() 함수의 네 번째 파라미터에 GitHub Personal Access Token(PAT)을 전달하면 됩니다. 토큰에는 repo 읽기 권한만 부여하면 충분하며, 소스 코드에 직접 하드코딩하기보다 ESP32의 NVS(Non-Volatile Storage)에 저장해 관리하는 것을 권장합니다.
Q3. OTA 중 전원이 차단되면 어떻게 되나요? ESP32의 OTA 메커니즘은 듀얼 파티션 구조로 동작합니다. 새 펌웨어는 기존 파티션과 분리된 영역에 기록되며, 플래시가 완전히 완료된 후에만 부트로더가 새 파티션으로 전환합니다. 중간에 전원이 끊기면 기존 펌웨어로 재부팅됩니다.
Q4. 인증서를 업데이트하지 않으면 언제 문제가 발생하나요? GitHub CDN이 사용하는 Root CA가 교체될 때 발생합니다. Late Fallback 덕분에 즉시 벽돌화되지는 않지만, Insecure 모드 다운로드가 반복되는 상태는 권장되지 않습니다. BearSSL Certificate Utility로 새 인증서를 생성해 펌웨어에 포함하고, OTA로 배포해 갱신하는 것이 올바른 순환 구조입니다.
Q5. WiFi와 이더넷을 동시에 활성화할 수 있나요? 생성자에서 두 플래그를 모두 true로 설정하면 듀얼 모드로 동작합니다. 라이브러리가 활성 인터페이스를 자동 감지해 사용합니다. 유선이 연결된 경우 이더넷을 우선 사용하도록 인프라를 설계하면 WiFi를 백업 경로로 활용하는 이중화 구성이 가능합니다. [추정]
Summary
MCM_GitHub_OTA is an Arduino library that automatically fetches and flashes ESP32 firmware from GitHub Releases. It officially supports wired OTA via the W5500 Ethernet module alongside WiFi, and includes a built-in Late Fallback mechanism to prevent remote devices from being permanently bricked due to SSL certificate expiration. It is a noteworthy project for environments where WiFi is unavailable, enabling automated remote firmware deployment integrated with GitHub CI/CD pipelines.
Overview: How Do You Update Devices in the Field?
As the number of deployed embedded devices grows, firmware maintenance becomes an increasingly serious challenge. Physically accessing dozens or hundreds of field devices to apply a single bug fix is simply not feasible. OTA (Over-The-Air) updates are the answer — but in industrial environments, WiFi is often not an option. Factories with heavy EMI (electromagnetic interference), wired-only secure networks, and equipment running on PoE infrastructure are common examples.
MCM_GitHub_OTA bridges this gap. By using the W5500 Ethernet module as the network interface, it enables a wired OTA pipeline sourced directly from GitHub Releases. Developers can automatically update every device in the field simply by publishing a new release on GitHub.
System Architecture: GitHub → W5500 → ESP32
The full update flow consists of three stages: ① query the latest version tag via the GitHub API, ② download the .bin binary from the CDN, and ③ flash it to the ESP32's OTA partition and reboot.
The network interface is selected at construction time. The enableEthernet and enableWiFi flags can be set independently, and the library automatically detects and uses the active interface.
// W5500 Ethernet only
MCM_GitHub_OTA ota(true, false);
// WiFi only
MCM_GitHub_OTA ota(false, true);
// Dual mode (auto-selects active interface)
MCM_GitHub_OTA ota(true, true);
Key Features of the MCM_GitHub_OTA Library
What sets this library apart is its design philosophy: not just flashing a file, but combining security, resilience, and flexibility in a single package.
- Dual Network Support: Supports both WiFi and W5500 Ethernet. Switch between them with a single constructor flag
- GitHub Releases Integration: Directly parses the GitHub API to locate the latest release tag and corresponding
.binasset automatically - Secure by Default: Uses SSLClient (BearSSL-based) with Trust Anchors (Root CAs) to prevent firmware tampering
- Late Fallback Mechanism: Automatically switches to Insecure mode on CDN certificate mismatch to complete the update
- Private Repository Support: Connect to private repositories using a GitHub Personal Access Token (PAT)
- Memory Efficient: Uses a shared global buffer to minimize heap fragmentation during large binary downloads
The core API is straightforward:
// Configure repository and initialize
ota.begin("owner", "repo-name", "v1.0.0"); // Public repo
ota.begin("owner", "repo-name", "v1.0.0", "ghp_xxxx"); // Private repo
// Trigger update check and execution (blocking)
ota.checkForUpdate();
// Check if running the latest version
bool latest = ota.isUpdated();
Why W5500 Improves OTA Reliability
OTA is fundamentally different from routine sensor data transmission. A binary ranging from hundreds of kilobytes to several megabytes must be received without interruption, in sequence, and with full integrity. A single lost packet or dropped connection can result in a failed flash or a bricked device.
W5500 is well-suited for this requirement:
- Hardware TCP/IP Offloading: W5500 independently handles TCP socket management, retransmission, and flow control — freeing the MCU to focus solely on receiving data
- Physical Stability of Wired Connection: Significantly lower risk of packet loss, interference, and disconnection compared to WiFi
- SPI Interface: Simple 4-wire connection to the ESP32 with minimal additional circuitry
- 8 Independent Sockets: GitHub API and CDN download connections can be managed on separate, isolated sockets
When combined with a PoE (Power over Ethernet) infrastructure, a single Ethernet cable delivers both power and the OTA update channel simultaneously. In industrial environments where cable runs are already in place, this provides a practical path to OTA deployment with no additional infrastructure. [Estimated]
Certificate Management and the Security Fallback
The hidden threat to embedded OTA is SSL certificate expiration. GitHub and its CDNs (Amazon S3, Azure, etc.) periodically rotate their Root CAs. If the Trust Anchors embedded in the device are outdated, secure connections fail and OTA updates stop. If this persists, field devices lose the ability to update themselves entirely.
MCM_GitHub_OTA addresses this pragmatically with its Late Fallback approach:
| Step | Action | Description |
|---|---|---|
| Attempt 1 | Secure mode | Connect to API and CDN using BearSSL + Trust Anchors |
| Detection | API success / CDN failure | CDN Root CA does not match the stored Trust Anchor |
| Attempt 2 | Insecure Fallback | Skip certificate validation and retry the download only |
| Result | Update completes | Next firmware can include updated Trust Anchors |
The key design principle is that API authentication always uses a secure connection — only the binary download falls back to Insecure mode when it fails. It is not a perfect security solution, but it effectively prevents the worst-case scenario of permanent bricking due to certificate expiration.
To manually refresh certificates, regenerate MCM_CertStore.h using the BearSSL Certificate Utility. Include the following domains:
api.github.com, github.com, objects.githubusercontent.com,
release-assets.githubusercontent.com, raw.githubusercontent.com, s3.amazonaws.com
Real-World Application Scenarios
The environments where this architecture delivers the most value are clear:
- Industrial Automation Equipment: WiFi reliability is low inside factories with heavy EMI. Wired Ethernet-based OTA is a practical way to update firmware without halting operations.
- Smart Buildings / Energy Meters: Power monitoring devices installed long-term in the field require security patches or regulatory updates without physical access. GitHub Releases-based deployment also provides built-in version history and rollback tracking.
- Agricultural and Environmental Monitoring: Sensor nodes in remote locations are costly to visit. Where PoE infrastructure is in place, a single cable resolves both power and OTA.
- GitHub Actions CI/CD Integration: When a build completes in an Actions workflow, a GitHub Release is automatically created. On the next
checkForUpdate()call, field devices receive the deployment immediately — merging code becomes the only manual step in the entire pipeline.
Limitations and Improvement Directions
MCM_GitHub_OTA solves many problems with a pragmatic design, but there are constraints worth understanding depending on the operating environment.
Current Limitations
- SSL Processing Load: Even though W5500 offloads TCP/IP, BearSSL handshake computation runs entirely on the ESP32. This can become a burden in low-power MCU configurations or high-frequency check intervals.
- Blocking Operation:
checkForUpdate()occupies the MCU during execution. Systems with real-time control loops — PID controllers, motor drives — must isolate this call in a separate FreeRTOS task. - ESP32-Only Platform: STM32, RP2040, and other MCUs are not officially supported at this time.
- GitHub Dependency: API rate limits or GitHub service outages will prevent updates from completing.
Improvement Directions
As this library evolves toward industrial-grade W5500-based platforms, the most meaningful improvements would be more efficient distribution of HTTPS requests across W5500 hardware sockets, dedicated OTA socket isolation, and official integration with FreeRTOS async tasks. Adding a timeout parameter to checkForUpdate() would also significantly improve coexistence with real-time systems.
FAQ
Q1. Is W5100 supported, or only W5500? Because the library depends on the Arduino Ethernet Library, W5100 is compatible. However, the README explicitly references W5500 as the target, and W5500 is recommended for OTA use given its 8 sockets and larger internal buffer.
Q2. How do I connect a private repository? Pass a GitHub Personal Access Token (PAT) as the fourth parameter to begin(). Read-only repo scope is sufficient. Rather than hardcoding the token in source code, storing it in the ESP32's NVS (Non-Volatile Storage) is the recommended approach for production deployments.
Q3. What happens if power is lost during an OTA update? The ESP32 OTA mechanism uses a dual-partition layout. The new firmware is written to a partition separate from the currently running one, and the bootloader only switches to the new partition after the flash completes successfully. A power loss mid-transfer results in a reboot into the existing firmware.
Q4. When does the certificate issue actually occur? It occurs when GitHub or its CDN rotates the Root CA used for its servers. The Late Fallback prevents immediate bricking, but repeated Insecure mode downloads are not a recommended long-term state. The correct cycle is to generate new certificates via the BearSSL Certificate Utility, bundle them into the next firmware build, and deploy the update via OTA.
Q5. Can WiFi and Ethernet be active at the same time? Setting both flags to true in the constructor enables dual mode, with the library auto-detecting the active interface. Designing the infrastructure so that Ethernet takes priority when a wired connection is present allows WiFi to serve as a fallback path — enabling a redundant OTA architecture. [Estimated]

