Table of Contents
Zephyr RTOS – 설치 및 예제 빌드
리눅스 재단(Linux Foundation)이 호스팅하고 인텔, NXP, 노르딕(Nordic) 등 글로벌 반도체 대기업들이 주도하여 유지보수하는 차세대 오픈소스 RTOS입니다. 현재 임베디드 시장에서 가장 가파르게 성장하고 있습니다.
개발 환경 구축
라이브러리 추가
윈도우에서도 가능하다고 하지만, WSL2 우분투에서 진행하도록 하겠습니다.
# Power Shell
wsl --list --online
wsl --install --distribution Ubuntu-26.04
sudo apt update
sudo apt upgrade -y
# 필수 빌드 도구 및 패키지 설치
sudo apt install -y git cmake ninja-build gperf \
ccache dfu-util device-tree-compiler wget \
python3-dev python3-pip python3-setuptools python3-tk python3-venv \
xz-utils file make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1
# 최소 3.20.5 이상이어야 함
cmake --version
cmake version 4.2.3
CMake suite maintained and supported by Kitware (kitware.com/cmake).
# 최소 3.12 이상이어야 함
python3 --version
Python 3.14.4
# 최소 1.4.6 이상이어야 함
dtc --version
Version: DTC 1.7.2
Zephyr 설치 및 Python 의존성 설치
python3 -m venv ~/zephyrproject/.venv
source ~/zephyrproject/.venv/bin/activate
pip install west
west init -m https://github.com/zephyrproject-rtos/zephyr ~/zephyrproject
cd ~/zephyrproject
# 오만 잡다한 버전을 전부 설치한다. 오래 걸린다.
west update
# Zephyr 소스 코드 위치를 CMake에 등록
west zephyr-export
sudo apt update
sudo apt install -y pkg-config libusb-1.0-0-dev libudev-dev
# Python 의존성 설치
west packages pip --install
Zephyr SDK 설치
cd ~/zephyrproject/zephyr
# 오만 잡다한 버전을 전부 설치한다. 오래 걸린다.
west sdk install
# 필요한 툴체인을 골라서 설치할 수 있다고 한다.
west sdk install --help
샘플 애플리게이션 빌드 테스트 (Blinky)
호스트 PC 와 동일한 시뮬레이션 빌드
cd ~/zephyrproject/zephyr
# west build -p always -b <your-board-name> samples/basic/blinky
# 호스트 PC 와 동일한 시뮬레이션 빌드
west build -p always -b native_sim samples/basic/blinky
# 실행
west build -t run
-- west build: running target run
[2/3] cd /home/skyer9/zephyrproject/zephyr/build && /home/skyer9/zephyrproject/zephyr/build/zephyr/zephyr.exe
*** Booting Zephyr OS build v4.4.0-7935-gcde0a961d820 ***
LED state: OFF
LED state: ON
LED state: OFF
LED state: ON
LED state: OFF
LED state: ON
^C
Stopped at 5.320s
ninja: build stopped: interrupted by user.
실제 하드웨어에 빌드
# 보드 타겟 빌드 -b 뒷 부분을 변경해야 합니다.
west build -p always -b nucleo_f411re samples/basic/blinky
# 보드를 USB로 연결 후 플래싱 (보드 제조사에서 제공하는 플래싱 툴 설치 필요)
west flash
기능 추가
Zephyr 내장 네이티브 HTTP 라이브러리를 이용해 https://google.com/ 페이지의 html 을 다운로드
테스트 진행중입니다.
mkdir -p samples/my_projects/http_get_google
vi samples/my_projects/http_get_google/prj.conf
# 일반 네트워킹 활성화
CONFIG_NETWORKING=y
CONFIG_NET_IPV4=y
CONFIG_NET_TCP=y
# native_sim의 zeth(tap) 인터페이스에 고정 IP/게이트웨이 부여
# (호스트에서 net-tools의 net-setup.sh로 zeth=192.0.2.2/24 를 만들어 둔 상태를 전제로 함)
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_CONFIG_NEED_IPV4=y
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1"
CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2"
CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0"
# 소켓 API 및 HTTP 클라이언트 활성화
CONFIG_NET_SOCKETS=y
# CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_NET_SOCKETS_OFFLOAD=n
CONFIG_HTTP_CLIENT=y
# DNS 설정 (구글 도메인 해석용)
CONFIG_DNS_RESOLVER=y
CONFIG_DNS_RESOLVER_MAX_SERVERS=1
CONFIG_DNS_SERVER_IP_ADDRESSES=y
CONFIG_DNS_SERVER1="192.0.2.2"
# TLS (HTTPS) 설정
CONFIG_NET_SOCKETS_SOCKOPT_TLS=y
CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_BUILTIN=y
CONFIG_MBEDTLS_ENABLE_HEAP=y
CONFIG_MBEDTLS_HEAP_SIZE=60000
CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=2
CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=7168
CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=7168
CONFIG_MBEDTLS_HASH_ALL_ENABLED=y
CONFIG_PSA_WANT_ALG_SHA_1=y
CONFIG_MBEDTLS_CIPHERSUITE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256=y
# TLS 세션 복원 및 캐싱 활성화 (Zephyr 커널 에러 해결용)
CONFIG_MBEDTLS_SSL_SESSION_TICKETS=y
# 힙 메모리 설정 (HTTP 응답 버퍼링 및 TLS 작업용)
CONFIG_HEAP_MEM_POOL_SIZE=32768
CONFIG_MAIN_STACK_SIZE=4096
# 로깅 서브시스템 활성화
# (CONFIG_LOG=y 없이 printk()만 쓰면, 네트워크 스택에서 에러가 발생한 직후
# printk()가 콘솔 락을 잡은 채로 멈춰서 이후 출력이 전부 사라지는 문제가 있었음)
CONFIG_LOG=y
mkdir -p samples/my_projects/http_get_google/src
vi samples/my_projects/http_get_google/src/main.c
#include <zephyr/kernel.h>
#include <zephyr/net/net_ip.h>
#include <zephyr/net/socket.h> // Zephyr 표준 소켓 (zsock_ 계열 포함)
#include <zephyr/net/http/client.h>
#include <zephyr/net/tls_credentials.h>
#include "ca_certificate.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define HTTP_PORT 443
#define HTTP_HOST "google.com"
/* HTTP 응답을 나누어 받을 버퍼 */
static uint8_t response_buf[2048];
/* HTTP 클라이언트 콜백 함수: 최신 Zephyr 규격에 맞춰 int 타입 반환 */
static int http_response_cb(struct http_response *rsp,
enum http_final_call final_data,
void *user_data)
{
if (rsp->data_len > 0) {
/* 수신된 HTML 데이터 출력 */
for (int i = 0; i < rsp->data_len; i++) {
putchar(rsp->recv_buf[i]);
}
}
if (final_data == HTTP_DATA_FINAL) {
printk("\n\n[HTTP] 모든 데이터를 성공적으로 수신했습니다.\n");
}
return 0; // 정상 처리 완료 반환
}
int main(void)
{
int ret;
struct zsock_addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
};
struct zsock_addrinfo *res;
ret = tls_credential_add(CA_CERTIFICATE_TAG, TLS_CREDENTIAL_CA_CERTIFICATE,
ca_certificate, sizeof(ca_certificate));
if (ret < 0) {
printk("CA 인증서 등록 실패: %d\n", ret);
return 0;
}
printk("구글 서브 도메인(DNS) 주소 변환 중...\n");
/* 1. DNS Lookup (Zephyr 명시적 zsock_ API 사용) */
ret = zsock_getaddrinfo(HTTP_HOST, "443", &hints, &res);
if (ret != 0) {
printk("DNS 변환 실패: %d\n", ret);
return 0;
}
/* 2. TLS 소켓 생성 */
int sock = zsock_socket(res->ai_family, res->ai_socktype, IPPROTO_TLS_1_2);
if (sock < 0) {
printk("소켓 생성 실패: %d\n", errno);
zsock_freeaddrinfo(res);
return 0;
}
/* HTTPS 통신을 위한 TLS 프로토콜 설정 */
sec_tag_t sec_tag_list[] = { CA_CERTIFICATE_TAG };
ret = zsock_setsockopt(sock, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_list, sizeof(sec_tag_list));
// HTTPS 호스트네임 검증(SNI) 설정
ret = zsock_setsockopt(sock, SOL_TLS, TLS_HOSTNAME, HTTP_HOST, strlen(HTTP_HOST));
printk("구글 서버에 연결 중 (%s)...\n", HTTP_HOST);
/* 3. 서버 연결 */
ret = zsock_connect(sock, res->ai_addr, res->ai_addrlen);
if (ret < 0) {
printk("서버 연결 실패: %d\n", errno);
zsock_close(sock);
zsock_freeaddrinfo(res);
return 0;
}
zsock_freeaddrinfo(res);
/* 4. HTTP 요청 구조체 채우기 */
struct http_request req = {
.method = HTTP_GET,
.url = "/",
.host = HTTP_HOST,
.protocol = "HTTP/1.1",
.response = http_response_cb,
.recv_buf = response_buf,
.recv_buf_len = sizeof(response_buf)
};
printk("HTTP GET 요청 전송 중...\n\n");
/* 5. HTTP 요청 전송 및 대기 (Timeout 5초) */
ret = http_client_req(sock, &req, 5000, NULL);
if (ret < 0) {
printk("HTTP 요청 전송 실패: %d\n", ret);
}
/* 6. 자원 정리 */
zsock_close(sock);
printk("\n연결이 종료되었습니다.\n");
return 0;
}
vi samples/my_projects/http_get_google/CMakeLists.txt
# 최소 CMake 버전 요구사항 정의
cmake_minimum_required(VERSION 3.20.0)
# Zephyr 패키지 불러오기 (빌드 시스템 핵심)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
# 프로젝트 이름 정의
project(http_get_google)
# 컴파일할 소스 파일 지정 (main.c 지정을 위해 필수)
target_sources(app PRIVATE src/main.c)
# CA 인증서(DER)를 C 배열(.inc)로 변환하여 빌드에 포함
set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated/)
generate_inc_file_for_target(
app
src/globalsign_r1.der
${gen_dir}/globalsign_r1.der.inc
)
vi samples/my_projects/http_get_google/src/ca_certificate.h
#ifndef __CA_CERTIFICATE_H__
#define __CA_CERTIFICATE_H__
#define CA_CERTIFICATE_TAG 1
/* GlobalSign Root CA - R1, google.com 접속용 (GTS Root R1이 하위 호환을 위해
* 이 인증서로 cross-sign 되어 있어 실제로 동작함) */
static const unsigned char ca_certificate[] = {
#include "globalsign_r1.der.inc"
};
#endif /* __CA_CERTIFICATE_H__ */
cp ~/zephyrproject/zephyr/samples/net/sockets/http_get/src/globalsign_r1.der \
~/zephyrproject/zephyr/samples/my_projects/http_get_google/src/globalsign_r1.der
sudo apt-get install -y iptables dnsmasq-base tcpdump
cd ~/zephyrproject/tools/net-tools
sudo ./net-setup.sh
# zeth: 192.0.2.2/24, Zephyr 쪽엔 192.0.2.1 할당됨 (prj.conf의 CONFIG_NET_CONFIG_MY_IPV4_ADDR)
cat > /tmp/dnsmasq_zeth.conf <<EOF
port=53
listen-address=192.0.2.2
except-interface=lo
bind-interfaces
no-dhcp-interface=lo
domain=zephyr.test
dhcp-range=192.0.2.16,192.0.2.32,1h
EOF
sudo dnsmasq -C /tmp/dnsmasq_zeth.conf -d --log-queries &
# 192.0.2.0/24(zeth) 발신 트래픽을 eth0으로 나갈 때 NAT
sudo iptables -t nat -A POSTROUTING -s 192.0.2.0/24 -o eth0 -j MASQUERADE
# FORWARD 체인 기본 정책이 DROP이므로 명시적으로 허용 규칙 추가 (맨 앞에 삽입)
sudo iptables -I FORWARD 1 -i zeth -o eth0 -j ACCEPT
sudo iptables -I FORWARD 2 -i eth0 -o zeth -m state --state RELATED,ESTABLISHED -j ACCEPT
# 1. 우분투 호스트 쪽에 가상 네트워크 인터페이스 및 NAT 라우팅 설정 (최초 1회)
cd ~/zephyrproject/tools/net-tools
/* 이 스크립트는 zeth 인터페이스를 만들고 방화벽(iptables) 설정을 잡아줍니다. */
sudo ./net-setup.sh up
# 2. 프로젝트 빌드 및 실행
cd ~/zephyrproject/zephyr
west build -p always -b native_sim samples/my_projects/http_get_google
west build -t run
주의 (인증서 관련): 위 예제 코드는 단순 데모를 위해 TLS 연결 시 인증서 무결성 검증을 건너뛰도록 구조화되었습니다(sec_tag_t = {0}). 만약 보안이 철저한 실제 상용 제품군에 적용할 때는 구글의 CA 루트 인증서(Root Certificate)를 mbedtls 서브시템에 등록해 준 뒤 setsockopt로 바인딩해야 정상적인 핸드셰이크가 완료됩니다.