Controlling STM32 & WIZnet Ethernet with Rust + Embassy(Nucleo-F446RE Example)
Rust 언어와 Embassy 프레임워크를 사용해 STM32 보드(Nucleo-F446RE)에서 WIZnet 이더넷 칩을 제어하는 방법을 소개
Rust + Embassy로 STM32와 WIZnet Ethernet 제어하기
STM32 Nucleo-F446RE + WIZnet W5500 기반 임베디드 Rust 네트워크 스타터 프로젝트
프로젝트 개요 (Project Overview)
이 프로젝트는 Rust + Embassy 프레임워크를 사용하여
STM32 Nucleo-F446RE 보드와 WIZnet Ethernet 칩(W5500 등)을 제어하는 기본 네트워크 예제입니다.
- 주요 키워드: WIZnet, W5500, W6100, W55RP20, STM32, Nucleo-F446RE, Rust, Embassy, Embedded, Ethernet, TCP/IP, Async
목표
- C/C++ 대신 Rust로 안전한 임베디드 네트워크 코드를 작성해 보기
- Embassy 비동기 런타임과 WIZnet 하드웨어 TCP/IP를 결합해 LED 깜빡이기 + Ethernet 초기화까지 구현
- 향후 Web Server, MQTT, IoT Gateway 등으로 확장 가능한 기반 만들기
이 예제는 “Lチカ(LED Blink)” 수준에서 시작하지만,
프로젝트 구조 자체는 WIZnet Ethernet을 포함한 Rust 네트워킹 프로젝트 템플릿으로 확장 가능하도록 설계되어 있습니다.
**Rust는 2006년, 미국에 있던 Mozilla(모질라) 연구소 소프트웨어 엔지니어 Graydon Hoare가 개인 프로젝트로 시작했고, 2009년부터 Mozilla가 공식 후원하면서 성장한 언어입니다. 이후 미국에 설립된 비영리 단체 Rust Foundation이 관리하며, Amazon Web Services, Google, Microsoft, Mozilla 등 글로벌 기업들이 함께 후원하고 있습니다.
***Embassy란?
Embassy는 임베디드용 Rust 비동기 프레임워크로, 오픈소스 커뮤니티(embassy-rs 조직)를 중심으로 개발되고 있습니다. 특정 한 회사 제품이라기보다, 여러 개발자들이 STM32, nRF 등 다양한 MCU 보드를 위해 함께 만들어 가는 프로젝트입니다. RTOS 없이도 async/await으로 여러 작업을 동시에 처리할 수 있게 해 주고, 태스크와 메모리를 정적으로 관리해서 저전력·소용량 MCU에 잘 맞습니다. Rust를 임베디드 세계로 확장시키는 핵심 축 역할을 하면서, 앞으로 IoT·산업용 장비에서 “RTOS 대신 Rust + Embassy”를 쓰는 흐름을 만드는 데 영향을 주고 있습니다.
프로젝트 설명 (Description)
1. 왜 Rust + Embassy + WIZnet인가?
기존의 임베디드 개발은 대부분 C/C++ + RTOS 조합에 의존합니다.
하지만 다음과 같은 한계가 있습니다.
- 포인터/메모리 버그로 인한 디버깅 난이도
- 같은 핀을 중복 설정하거나, 잘못된 타이머/채널을 연결해도 컴파일 시점에 에러를 못 잡는 경우
- RTOS에서 태스크·큐·락을 직접 관리해야 하는 복잡한 동기화 코드
Rust + Embassy 조합은 이런 문제를 다음과 같이 줄여 줍니다.
- 소유권(Ownership)과 타입 시스템으로
- 한 번 사용한 핀을 다시 다른 역할로 생성하면 컴파일 에러
- 하드웨어 제약(특정 타이머-핀 조합 등)을 타입으로 표현하여 잘못된 설정을 사전에 차단
- 비동기(Async) 기반 타이머/IO를 제공하여,
Timer::after()처럼 CPU를 블로킹하지 않는 딜레이 구현- 여러 네트워크 작업을 동시에 처리하는 구조 확장에 유리
여기에 WIZnet Ethernet 칩(W5500 / W6100 / W55RP20 등) 을 더하면:
- MCU에서 복잡한 TCP/IP 스택을 직접 구현할 필요 없이,
- WIZnet 하드웨어 TCP/IP 엔진이 대부분의 네트워크 처리를 담당
- Rust는 주로 애플리케이션 로직과 프로토콜 처리에 집중할 수 있어
- 코드가 단순해지고
- MCU 자원(CPU/메모리)도 효율적으로 사용 가능합니다.
하드웨어 구성 (Hardware Setup)
사용 보드 및 부품
- MCU 보드
- ST Nucleo-F446RE (STM32F446RE 기반)
- 다른 STM32 Nucleo 보드로도 확장 가능 (Embassy 지원 여부에 따라)
- WIZnet Ethernet 보드/모듈 (예시 중 택 1)
- WIZnet W5500 이더넷 모듈 또는 이와 동일 칩 기반 이더넷 보드
- 또는 W6100, W5100S, W55RP20-EVB-Pico / ioNIC 기반 보드 등으로 확장 가능
- 기타
- USB 케이블 (보드 전원 및 디버깅용)
- 점퍼 케이블 (STM32 보드와 WIZnet 모듈 간 SPI/INT/RESET 연결용)
기본 연결 예 (STM32 Nucleo-F446RE + W5500)
아래는 대표적인 SPI 연결 예시입니다. 실제 핀은 보드 레이아웃에 따라 조정 가능합니다.
- SPI SCK → STM32
PA5 - SPI MISO → STM32
PA6 - SPI MOSI → STM32
PA7 - CS(SS) → STM32
PB6(예시) - RESET → STM32
PB7(선택 사항) - INT → STM32
PB8(선택 사항, 인터럽트 기반 이벤트 처리 시)
Nucleo 보드에서 기본 LED는 보통 PA5에 연결되어 있어,
LED 깜빡이 예제는 이 핀을 출력으로 사용합니다.
소프트웨어 구성 (Software Setup)
개발 환경
- OS: Ubuntu 22.04 / 24.04 (또는 Windows + WSL2)
- IDE: Visual Studio Code
- 개발 환경 방식: VSCode Dev Containers + Docker
- 디버깅/플래시:
probe-rs사용
1. Dev Container 구성
프로젝트 루트에 .devcontainer 폴더를 만들고, 다음을 준비합니다.
Dockerfileubuntu:24.04베이스rustup으로 Rust 설치probe-rs설치cargo와thumbv7em-none-eabihf타깃 설정
docker-compose.yml/dev를 컨테이너에 마운트해서 **USB 디버거(ST-LINK 등)**에 접근 가능하도록 설정- 워크스페이스 및 SSH 키 볼륨 마운트
devcontainer.json- 컨테이너에서 열 워크스페이스 폴더 지정 (예:
/workspace) rust-lang.rust-analyzer확장 필수 설치
- 컨테이너에서 열 워크스페이스 폴더 지정 (예:
VSCode에서 “Dev Containers: Reopen in Container”를 실행하면
Rust + Embassy + probe-rs 개발 환경이 자동으로 올라옵니다.
2. Rust 프로젝트 및 의존성
cargo init 명령으로 새 프로젝트를 생성한 뒤, Cargo.toml에 Embassy 및 WIZnet 관련 의존성을 추가합니다.
버전은 예시이며, 실제 사용 시 최신 버전을 확인해 맞게 조정하면 됩니다.
추가로:
.cargo/config.toml에 타깃(thumbv7em-none-eabihf) 및probe-rsrunner 설정rust-toolchain.toml로 팀 전체 Rust 버전 고정 (예:1.90등)build.rs에서 Embassy 링커 스크립트 적용
3. 메인 예제 코드 개요
기본 예제는 다음 두 가지를 수행합니다.
- LED 깜빡이기 (Lチカ) – MCU 및 Embassy 환경이 정상 동작하는지 검증
- WIZnet Ethernet 초기화 – MAC 설정 후 DHCP로 IP 획득 (또는 Static IP 설정)
코드 구조는 대략 아래와 같습니다.
이 구조를 기반으로:
- TCP 서버/클라이언트
- HTTP Web Server
- MQTT 클라이언트
등을 Embassy +embassy-net레이어 위에서 구현할 수 있습니다.
WIZnet 제품이 어떻게 사용되었는지 (How WIZnet Products Are Used)
1. 하드웨어 TCP/IP 오프로드
이 프로젝트에서 WIZnet 칩(W5500/W6100/W5100S/W55RP20 등)은:
- 하드웨어 TCP/IP 엔진으로 동작하며
- MCU는 단순히 소켓 오픈 / 데이터 송수신 / 상태 확인 위주의 제어만 수행합니다.
이로써:
- MCU에서 소프트웨어 TCP/IP 스택을 구현할 때 발생하는
- 복잡한 상태 머신
- 방대한 코드량 및 메모리 사용
- 네트워크 타이밍 이슈
를 크게 줄일 수 있습니다.
2. Embassy 네트워크 계층과의 연결
embassy-net-wiznet 크레이트는 WIZnet 칩을 위한 드라이버 + 어댑터 레이어입니다.
- SPI 기반 WIZnet Device(W5500 등)를
WiznetSpiDevice형태로 래핑하고 - Embassy의 네트워크 스택(
embassy-net)에 붙여DHCP,ARP,UDP,TCP등 프로토콜을 Rust 코드에서 안전하게 제어할 수 있게 합니다.
3. WIZnet + Rust 조합의 의미
이 프로젝트는 다음과 같은 의미를 가집니다.
1. 기존 WIZnet C예제에서 한 단계 진화
- C 기반 예제 위주였던 WIZnet 생태계에
- Rust/Embassy 기반의 현대적인 임베디드 예제를 추가하여
- 새로운 언어/패러다임에 익숙한 개발자도 쉽게 접근 가능
2. 안전한 IoT/IIoT 시스템 기반 마련
- 산업용/보안 중요 서비스에서 메모리 안전성은 필수 요소
- WIZnet 칩이 네트워크를 담당하고, Rust가 애플리케이션 로직을 담당함으로써
- 안전성과 신뢰성을 동시에 확보
3. WIZnet 제품 확장성 강조
- 동일 코드 구조로
- W5500 → W6100(IPv4/IPv6)
- W5100S / ioNIC(W55RP20) 기반 보드
등으로 확장 가능
- WIZnet 제품 포트폴리오 간 코드 재사용성과 호환성이 높다는 것을 보여주는 데에도 좋은 데모
이 프로젝트의 의미와 확장 아이디어 (Significance & Future Work)
교육/학습 관점
- Embedded Rust 입문용 예제로 활용 가능
- WIZnet Ethernet + MCU + Rust 조합을 한 번에 경험할 수 있는 구성
- C/C++ 개발자에게 “Rust로도 이렇게 쉽게 네트워크 MCU 개발이 가능하다”는 메시지를 전달
실전 응용 아이디어
- 🌐 초간단 Web Server
- 온도/습도 센서 값을 WIZnet 기반 Web 페이지로 실시간 제공
- 📡 MQTT IoT Gateway
- 센서 데이터 → WIZnet Ethernet → MQTT Broker(Cloud) 전송
- 🧠 AIoT Edge Node (특히 W55RP20 연동)
- RP2350 기반 W55RP20-EVB-Pico와 Embassy를 결합하여
- 로컬 연산 + Ethernet 통신을 수행하는 AIoT 엣지 노드 구현
- 🧩 산업용 장비 모니터링 게이트웨이
- RS-485/Modbus 장비 상태를 수집 후
- WIZnet Ethernet으로 상위 서버에 보고
마무리
이 프로젝트는 “Rust + Embassy + WIZnet Ethernet” 조합이 실제로 얼마나 강력한지 보여주는 최소 예제입니다.
- 기존 C 기반 TCP/IP보다 더 안전하고 유지보수하기 쉬운 코드
- WIZnet 하드웨어 TCP/IP가 제공하는 안정적이고 검증된 네트워크 구현
- Embassy의 비동기 런타임으로 고성능·저지연 네트워크 앱으로 확장 가능한 구조
을 동시에 얻을 수 있습니다.
앞으로 maker.wiznet.io에서
- W5500 / W6100 / W55RP20을 대상으로 한 Rust/Embassy 예제 시리즈
- Web Server, MQTT Client, HTTP REST API 등
을 연재 형식으로 확장해 나가도 좋습니다.
Getting Started with Rust + Embassy on STM32 and WIZnet Ethernet
1. Hardware TCP/IP Offload
In this project, the WIZnet chip (e.g., W5500 / W6100 / W5100S / W55RP20) acts as a:
- Hardware TCP/IP offload engine, and
- Offloads low-level protocol handling from the MCU.
The Rust firmware:
- Opens sockets
- Sends / receives data
- Monitors connection status
while the WIZnet silicon handles ARP, IP, TCP, UDP, and timing in hardware.
This:
- Reduces firmware complexity
- Decreases MCU flash / RAM usage
- Improves reliability for industrial Ethernet, IoT, and IIoT scenarios
2. Integration with Embassy Network Stack
The embassy-net-wiznet crate provides:
- A WIZnet driver layer (e.g.
WiznetSpiDevice) - An adapter to plug the WIZnet device into Embassy’s network stack (
embassy-net)
This makes Rust code able to use:
- DHCP
- IPv4 (and IPv6 with appropriate WIZnet chip)
- UDP and TCP sockets
in a type-safe and async manner.
3. Why This Combination Matters
This project highlights:
1. A modern path for WIZnet users
- Traditional C-based examples are still valuable,
- But this Rust/Embassy example shows a modern, safe alternative for new-generation developers.
2. Safety for production IoT / IIoT systems
- Memory safety issues are a major concern in connected devices.
- With Rust handling application logic and WIZnet offloading Ethernet/TCP/IP,
you can build reliable and maintainable networked devices.
3. Scalability across WIZnet product families
- The same architectural pattern can be reused with:
- W5500 for classic IPv4 Ethernet
- W6100 for IPv4/IPv6
- W55RP20 (ioNIC) for tightly integrated MCU + TCP/IP
- This demonstrates cross-device code reuse throughout the WIZnet ecosystem.
Significance and Future Directions
Educational & Learning Value
- A great Embedded Rust introduction for C/C++ developers
- A real-world example combining:
- Rust,
- Embassy async runtime, and
- WIZnet Ethernet hardware
This shows that:
“You can build serious networked MCUs in Rust on WIZnet hardware.”
Practical Extension Ideas
- 🌐 Simple Web server showing sensor values over W5500/W6100
- 📡 MQTT IoT gateway pushing telemetry to a cloud broker
- 🧠 AIoT edge node combining:
- Local compute (e.g., W55RP20 / RP-based boards)
- Deterministic Ethernet communication
- 🧩 Industrial monitoring gateway that bridges legacy field devices (e.g. RS-485, Modbus) with Ethernet
Adapting This Project to W55RP20-EVB-Pico (ioNIC)
The W55RP20-EVB-Pico is WIZnet’s ioNIC-based evaluation board, combining:
- A Raspberry Pi RP2350-class MCU (dual-core ARM Cortex-M33)
- WIZnet hardwired TCP/IP engine in a single chip (W55RP20)
- A Pico-style form factor, compatible with many Raspberry Pi Pico accessories
Hardware Differences
Compared to “STM32 Nucleo + external W5500 module”:
- You only need one board:
W55RP20-EVB-Pico - The Ethernet MAC + PHY and TCP/IP engine are integrated in the W55RP20 chip
- On-board LED, buttons, and headers are already wired, so:
- No external SPI wiring to a separate Ethernet module
- Simpler hardware setup for quick prototypes
Software Adaptation (Conceptual)
The overall software architecture remains the same:
- Use an appropriate HAL / Embassy port for the RP2350 class MCU
- Initialize clocks, GPIO, and ioNIC-specific peripherals
- Use a WIZnet driver compatible with W55RP20 (similar to how
embassy-net-wiznetworks for W5500) - Configure MAC, start DHCP, then start async tasks as usual
Pseudo-style structure (for illustration):
Note: The module and type names above (
embassy_rp55,wiznet_ionic, etc.) are illustrative.
Actual crate names and APIs may differ depending on the HAL and Embassy support status for W55RP20/RP2350.
Meaning of the W55RP20 Variant
Using W55RP20-EVB-Pico with Rust + Embassy is particularly interesting because:
1. Single-chip integration
- MCU + TCP/IP in one chip simplifies board design and BOM.
- Ideal for compact IoT and AIoT products.
2. Pico ecosystem compatibility
- The Pico-style form factor works with many existing add-ons and carrier boards.
3. Best of both worlds
- WIZnet’s proven hardware TCP/IP engine,
- Combined with Rust’s memory safety and Embassy’s async model,
- Creates a future-proof architecture for connected devices.

