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 네트워킹 프로젝트 템플릿으로 확장 가능하도록 설계되어 있습니다.
프로젝트 설명 (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.

