10.1 Zenoh-Pico 개요
전 세계에 배포된 사물인터넷(IoT) 센서 및 액추에이터 디바이스의 대다수는 운영체제(OS)를 구동할 수 없는 초소형 마이크로컨트롤러(MCU)를 기반으로 작동한다.
Zenoh 프로토콜 생태계를 이러한 자원 제약 환경(Resource-Constrained Environment)까지 확장하기 위해 설계된 구현체가 바로 zenoh-pico이다. 본 절에서는 zenoh-pico의 탄생 배경과 하드웨어 제약 조건을 극복하기 위한 공학적 설계 철학, 그리고 표준 C 구현체인 zenoh-c와의 구조적 차이점을 학술적 관점에서 규명한다.
1. 마이크로컨트롤러와 제한된 리소스 환경의 이해
고성능 마이크로프로세서(MPU) 환경에 익숙한 시스템 엔지니어는 MCU 환경으로 이주할 때 소프트웨어 아키텍처 구상을 원점에서 재검토해야 한다.
1. 메모리의 극단적 빈곤 (Memory Constraints)
일반적인 리눅스 런타임 환경 시스템이 기가바이트(GB) 단위의 RAM을 확보하는 것과 달리, 범용 MCU(예: 특정 STM32 계열 등)는 불과 수십 킬로바이트(KB) 이하의 정적 램(SRAM)만을 탑재한다. 이러한 환경에서 동적 메모리 할당을 수행하거나 무거운 직렬화 포맷(예: JSON 파서)을 도입하는 것은 시스템 멈춤을 초래한다.
2. 메모리 단편화 (Memory Fragmentation)의 위험성
MCU 환경에서는 가비지 컬렉터(Garbage Collector) 런타임이 부재하며, malloc 및 free 명령을 통한 동적 메모리 생성/해제가 반복될 경우 힙(Heap) 공간에 단편화가 발생한다. 이는 종국에 메모리 할당 실패(Allocation Failure) 및 하드 폴트(Hard Fault)를 유발하여 임베디드 장비의 가동 중단을 초래한다.
3. 운영체제의 부재 (Bare-metal 및 RTOS 한계)
리눅스 시스템 콜과 멀티 스레딩(Multi-threading) 인터페이스가 존재하지 않는다. 비동기 소켓 제어, TCP 커넥션 풀링과 같은 복잡한 네트워크 조작을 단일 메인 루프(while(1)) 내에서 비블로킹(Non-blocking) 방식으로 처리하지 못하면 시스템 전체 루프가 정지된다.
2. Zenoh-Pico의 설계 철학과 경량화 전략
기존 IoT 프로토콜(MQTT, CoAP)이 성능이나 분산 라우팅 기능을 타협한 것과 달리, Zenoh-Pico는 핵심 프로토콜 규격을 유지하면서도 C 언어 수준에서의 고강도 런타임 경량화 전술을 도입하였다.
graph TD
classDef zClass fill:#e6f7ff,stroke:#333,stroke-width:1px;
classDef sysClass fill:#fff2e8,stroke:#333,stroke-width:1px;
subgraph "Zenoh-Pico Lightweight Architecture"
ClientPico[zenoh-pico<br>Dumb Client Mode]
MemPool[Static Memory Pool<br>Pre-allocated at Compile Time]
PortLayer[BYON Porting Layer<br>Platform Independent I/O]
end
subgraph "Zenoh Infrastructure"
ZRouter((Zenoh Router<br>Smart Routing & Topology))
end
subgraph "Hardware Layer"
MCU_MAC[Network MAC / UART / BLE]
end
ClientPico -->|0 Allocation, Forward Only| ZRouter
ClientPico -->|Buffer Mapping| MemPool
ClientPico -->|Read/Write Bytes| PortLayer
PortLayer --> MCU_MAC
class ClientPico,MemPool,PortLayer zClass;
class ZRouter,MCU_MAC sysClass;
1. 동적 메모리 할당의 원천 배제 (Zero Dynamic Allocation)
zenoh-pico 프로그램이 부팅된 후에는 malloc 호츌이 전혀 발생하지 않는다. 개발자가 컴파일 타임에 선언해둔 전역 물리 버퍼(Static Array) 메모리만 대여하여 통신을 수행하며, 메모리 단편화 문제의 발생 근원을 소거(Elimination)하였다.
2. 라우터 의존형 토폴로지 전술 (Dumb Client Topology)
MCU 내부에서 네트워크 위상 토폴로지(Topology)를 계산하거나 큐스토리지 정책(Queueing)을 수행하는 복잡성을 제거하였다. zenoh-pico 노드는 오직 클라이언트(Client) 모드로 작동하며, 상위에 연결된 강력한 데스크톱 노드나 클라우드 상의 Zenoh 라우터에게 패킷 전달 책임을 전면 위임한다.
3. 포팅 자율성 극대화 (Bring Your Own Network, BYON)
코어 구현체 내에 특정 물리 계층(TCP, UDP, UART 등)의 의존 코드를 포함하지 않는다. zenoh-pico 엔진은 순수한 바이트 조작 스택으로 동작하며, 개발자가 시스템의 통신 모듈(Ethernet, BLE, RS-485 등)과 연결되는 간단한 읽기/쓰기 포팅 계층(Porting Layer) 함수 포인터 두 개를 마련해 주면 그 위에서 구동되도록 설계되었다.
3. 범용 Zenoh (zenoh-c)와 Zenoh-Pico의 구조적 차이
많은 개발자들이 Rust 코어를 완전히 내포하고 있는 zenoh-c 패키지와 순수 C 구현체인 zenoh-pico 간의 환경 조건을 혼동한다. 시스템의 물리 스펙과 가용 자원에 따라 아키텍처 구상을 다음과 같이 타결해야 한다.
| 기능 비교 | zenoh-c (표준 바인딩) | zenoh-pico (마이크로 구현체) |
|---|---|---|
| 코어 엔진 | Rust 네이티브 백그라운드 구동 (zenoh-rs) | 100% C 구조체 기반의 상태 머신 (Pure C) |
| 선행 요구사항 | 멀티 스레드 지원 OS (Linux/Windows 등) | 제약 없음 (Bare-metal, RTOS 등 단일 루프 상호 대응) |
| 메모리(RAM) 풋프린트 | 최소 10 ~ 20 MB | 단 2 ~ 5 KB |
| 지원 네트워크 토폴로지 | Router, Peer, Client 토폴로지 모두 지원 | 오직 Client 모드로 한정 |
| 네트워크 자율성 | 자동 스카우팅(Scouting) 및 동적 멀티캐스트 탐색 주도 | 라우터 연결 단절 시 맹목적 대기. (중계 불가) |
MCU의 시스템 제어기를 구현하는 팀에서는 zenoh-pico를 사용하고, 해당 제어기들의 패킷을 수합하는 중간 에지(Edge) 컴퓨터(예: 라즈베리 파이 급 MPU 보드)에는 zenoh-c 혹은 zenoh-rs를 적재하여 토폴로지를 격리(Isolation)하는 계층적 분배 방식이 요구된다.
4. 지원 하드웨어 플랫폼 및 한계 제원 (Specification)
하드웨어 설계 및 칩셋 발주(Sourcing) 이전에, zenoh-pico 가 대상 칩 시스템(System on Chip, SoC)에 이식될 수 있는지 한계 제원을 확인해야 한다.
1. 절대적 물리 메모리 한도
- 비휘발성 플래시(Flash) 메모리: 코드 섹션 적재를 위해 최소 30KB ~ 50KB 용량 필요.
- SRAM (실행 힙/스택): 버퍼 배열 저장을 위해 최소 2KB ~ 5KB. 데이터 페이로드(Payload) 크기에 비례하여 증가.
2. I/O 인프라 요구량
칩 내부에 WiFi 기능이 포함된 ESP32와 같은 SoC부터 인터넷 기능이 없고 직렬(Serial) 통신만 지원하는 초저전력 칩들까지 모두 지원한다. 단, 개발팀에서 해당 칩의 I/O를 비동기 혹은 폴링(Polling) 방식으로 제어할 수 있는 저수준 하드웨어 추상 계층(HAL) 코드를 소유하고 있어야 포팅이 성립된다.
결론적으로, C99 표준 컴파일러(GCC 호환)가 구동되며 외부로 바이트 전송이 가능한 어떠한 형태의 마이크로컨트롤러 환경에서도 zenoh-pico는 독립적으로 이식되어 분산 라우팅망의 종단 노드(End-node)로 합류할 수 있는 궁극적 유연성을 파급한다.