wiznet-rs: no_std Rust Driver for WIZnet W6100 TCP/IP Ethernet Controller
A platform-independent Rust driver for WIZnet W6100, using SPI DMA, interrupt-driven service, and lock-free socket data paths.
Project Overview
wiznet-rs is a Rust-based embedded network driver project for WIZnet hard-wired TCP/IP + Ethernet controllers. The current implemented target is WIZnet W6100, connected to an STM32F103C8 Blue Pill through SPI1. The repository provides a no_std driver crate and a bare-metal echo firmware example that runs TCP echo on port 5555 and UDP echo on port 5556.
The project is structured as a Cargo workspace with two main members:
| Path | Role |
|---|---|
wiznet-rs/ | Platform-independent no_std driver crate |
examples/echo/ | STM32F103 bare-metal firmware using W6100 over SPI1 |
examples/spi_dma_loopback.rs | Standalone SPI + DMA loopback self-test |
examples/echo/tools/echo_test.py | Host-side TCP/UDP echo validation tool |
The driver crate depends on embedded-hal, embedded-dma, bitflags, and nb, while the example firmware adds stm32f1xx-hal, cortex-m, cortex-m-rt, panic-halt, and static_cell.
Project Type
| Item | Assessment |
|---|---|
| Project type | Embedded Rust Ethernet driver |
| Runtime style | no_std, bare-metal |
| Target MCU example | STM32F103C8 / Blue Pill |
| Ethernet controller | WIZnet W6100 |
| Main interface | SPI1 with DMA |
| Network protocol examples | TCP echo, UDP echo |
| Driver abstraction | Platform-independent driver + board-specific BSP layer |
| Current maturity | Hardware-exercised prototype/reference implementation |
WIZnet Product Usage and System Role
| Item | Assessment |
|---|---|
| WIZnet product used | W6100 Ethernet Controller |
| Product role | SPI-based hard-wired TCP/IP + Ethernet controller |
| MCU role | STM32F103 runs application logic, interrupt handlers, and SPI/DMA transport |
| Driver role | Controls W6100 common registers, socket registers, socket state machines, and data transfer |
| Confirmed chips | W6100 checked as implemented |
| Listed but not implemented | W6300, W5500, W5300, W5100S, W5100 |
The README marks W6100 as the supported chip and leaves W6300, W5500, W5300, W5100S, and W5100 unchecked. Therefore, the repository should be interpreted as a W6100-focused implementation, not a complete multi-chip WIZnet driver.
TOE Usage
TOE Usage: Yes, through direct WIZnet W6100 socket/register control.
The project uses the W6100 as a hard-wired TCP/IP Ethernet controller. TCP and UDP processing are handled through the WIZnet chip’s socket engine, while the Rust driver manages socket state, register access, buffer movement, and command sequencing over SPI. This is not an Arduino Ethernet library path, not ESP-IDF esp_eth / esp_netif, and not an lwIP socket stack path.
The code defines W6100 register addresses such as CIDR, VER, SHAR, GAR, SUBR, SIPR, SIR, SIMR, and PHYSR, and uses socket operations including TCP listen/connect and UDP bind. The socket layer also defines protocol modes such as TCP4, UDP4, IPRAW4, MACRAW, TCP6, and UDP6, but the example uses TCP4 and UDP4 echo behavior.
Hybrid Network 여부
Hybrid Network: No
The repository shows a wired Ethernet path through W6100 over SPI. No Wi-Fi, BLE, cellular, or other wireless network path is confirmed in the reviewed README, driver crate, or STM32 example. The presence of TCP and UDP examples does not constitute hybrid networking because both operate over the same W6100 Ethernet interface.
System Architecture
Host PC
├─ TCP client: 192.168.10.10:5555
└─ UDP client: 192.168.10.10:5556
│
▼
Ethernet Network
│
▼
WIZnet W6100
├─ Hard-wired TCP/IP engine
├─ 8 hardware sockets
├─ Common registers
├─ Socket registers
└─ RX/TX socket buffers
│ SPI1 + DMA
▼
STM32F103C8
├─ examples/echo application
├─ interrupt handlers
│ ├─ TIM2 periodic service
│ ├─ EXTI15_10 W6100 INT line
│ └─ DMA1_CHANNEL2 DMA completion
├─ HalSpi transport
└─ wiznet-rs driver crate
│
▼
Application socket handles
├─ TcpSocket read/write
└─ UdpSocket recv_from/send_toThe driver separates the platform-independent crate from the board-specific layer. wiznet-rs/src/ contains the driver logic without STM32 HAL dependencies, while examples/echo/src/hal_spi.rs and main.rs contain GPIO, DMA, SPI, timer, EXTI, and interrupt wiring for STM32F103.
Operation Flow
1. STM32 initializes clocks, GPIO, SPI1, DMA1, W6100 reset, and interrupt lines.
2. W6100 is initialized through SPI register access.
3. Driver checks PHY link status.
4. When link is up, runtime IPv4 configuration is staged:
- IP: 192.168.10.10
- Gateway: 192.168.10.1
- Subnet: 255.255.255.0
5. TCP listener opens on port 5555.
6. UDP socket opens on port 5556.
7. W6100 events, timer ticks, and DMA completion interrupts call service routines.
8. TCP received bytes are echoed back through socket ring buffers.
9. UDP datagrams are echoed back to their sender.
10. On link loss or socket closure, the driver re-arms the socket path.The example code configures IP address 192.168.10.10, TCP port 5555, and UDP port 5556. It uses chip.service() from interrupt context and keeps the main application loop focused on socket handle operations and wfi() sleep.
Technical Characteristics
| Area | Description |
|---|---|
| Driver model | no_std, platform-independent Rust crate |
| Hardware access | SPI command header + register/socket buffer access |
| Bulk transfer | Full-duplex DMA |
| Completion model | Polling for small transfers, interrupt completion for bulk transfers |
| Socket ownership | W6100 owns 8 socket slots; user code receives lightweight handles |
| Data path | Lock-free SPSC RX/TX rings |
| Application behavior | Main loop uses socket handles and sleeps with wfi() |
| Unsafe policy | Driver crate denies unsafe code; hardware-specific unsafe blocks remain local to app layer |
The SPI transport exposes SpiDmaDevice, SpiDmaTransaction, DmaBuffers, and Completion::{Poll, Interrupt}. Bulk asynchronous transfers are started by the driver and completed from the DMA interrupt path.
Strengths
| Strength | Details |
|---|---|
| Clear driver/BSP separation | The driver crate is kept independent from STM32 HAL code. |
| Rust embedded design | Uses no_std, embedded-hal, embedded-dma, and non-blocking nb style. |
| Efficient data movement | Bulk RX/TX payloads move through DMA instead of CPU byte loops. |
| Interrupt-driven architecture | Timer, W6100 INT, and DMA completion events drive service execution. |
| Lock-free socket data path | RX/TX rings reduce contention between ISR and application code. |
| TCP and UDP examples | The repository includes both stream and datagram echo validation paths. |
| Concrete hardware target | The STM32F103 + W6100 path is implemented and documented. |
Limitations
| Limitation | Details |
|---|---|
| Chip support scope | W6100 is the only checked implemented chip in README. |
| W5500 support | 저장소 내 명시 없음 as implemented support; it is listed but unchecked. |
| DHCP | Runtime network configuration exists, but DHCP integration is described as future-oriented rather than completed. |
| Hardware portability | The driver is portable in design, but the included working firmware targets STM32F103. |
| Release status | No release package is published in the GitHub repository view. |
| External adoption | Stars and forks are low in the repository view, so external adoption is not yet demonstrated. |
The README explicitly lists runtime network configuration as built to later be driven by DHCP, and the GitHub repository view shows no published releases.
Application Value
This project has high reference value for embedded Rust developers building deterministic Ethernet firmware around WIZnet TOE chips. Its strongest value is not a generic TCP/UDP echo example, but the architecture around SPI DMA, interrupt-driven chip service, socket-level ownership, and lock-free application-facing socket handles.
Potential application areas include:
| Area | Value |
|---|---|
| Embedded Rust Ethernet firmware | Reference for no_std WIZnet driver architecture |
| MCU + TOE networking | Demonstrates how TCP/UDP can be delegated to W6100 |
| Low-CPU Ethernet I/O | DMA-based transfer reduces CPU involvement in payload movement |
| Industrial controller firmware | Useful pattern for deterministic wired communication |
| Driver portability design | Shows separation between platform-independent driver and concrete HAL/BSP |
Final Summary
wiznet-rs is a technically meaningful embedded Rust project centered on WIZnet W6100. It implements a no_std driver model with direct W6100 register/socket control, SPI DMA bulk transfer, interrupt-based service execution, and lock-free socket data paths. The included STM32F103 example validates TCP and UDP echo behavior over wired Ethernet.
Its main limitation is scope: despite listing multiple WIZnet chip families, the repository currently confirms W6100 as the implemented target. It is best classified as a W6100-focused Rust driver reference rather than a finished general-purpose WIZnet W-series driver.
Author Information
| Item | Information |
|---|---|
| Repository owner | max619 |
| Repository name | wiznet-rs |
| Repository description | Wiznet W series network chips driver written in Rust |
| License | MIT |
| Public activity indicators | 0 stars, 0 forks in the repository view at review time |
The repository is hosted under the GitHub owner max619, is public, and is described as a Rust driver for WIZnet W-series network chips.
wiznet-rs: WIZnet W6100용 no_std Rust TCP/IP Ethernet 드라이버
프로젝트 개요
wiznet-rs는 WIZnet hard-wired TCP/IP + Ethernet 컨트롤러를 Rust 환경에서 제어하기 위한 임베디드 네트워크 드라이버 프로젝트이다. 현재 저장소에서 구현 대상으로 확인되는 칩은 WIZnet W6100이며, 예제 펌웨어는 STM32F103C8 Blue Pill에서 SPI1을 통해 W6100을 연결하고 TCP echo 서버 5555번 포트, UDP echo 서버 5556번 포트를 구동한다.
저장소는 Cargo workspace 구조이며, 드라이버와 보드별 예제를 분리한다.
| 경로 | 역할 |
|---|---|
wiznet-rs/ | 플랫폼 독립형 no_std Rust 드라이버 crate |
examples/echo/ | STM32F103 + W6100 기반 bare-metal echo 펌웨어 |
examples/spi_dma_loopback.rs | SPI + DMA loopback 자체 테스트 |
examples/echo/tools/echo_test.py | TCP/UDP echo 검증용 호스트 테스트 도구 |
드라이버 crate는 embedded-hal, embedded-dma, bitflags, nb를 사용하며, STM32 예제는 stm32f1xx-hal, cortex-m, cortex-m-rt, panic-halt, static_cell 등을 사용한다.
프로젝트 유형
| 항목 | 내용 |
|---|---|
| 프로젝트 유형 | 임베디드 Rust Ethernet 드라이버 |
| 실행 환경 | no_std, bare-metal |
| 예제 MCU | STM32F103C8 / Blue Pill |
| Ethernet 컨트롤러 | WIZnet W6100 |
| 주요 인터페이스 | SPI1 + DMA |
| 네트워크 예제 | TCP echo, UDP echo |
| 드라이버 구조 | 플랫폼 독립 드라이버 + 보드별 BSP 계층 |
| 성격 | 하드웨어 검증 기반 prototype/reference implementation |
WIZnet 제품 사용 여부와 시스템 내 역할
| 항목 | 판단 |
|---|---|
| 사용 WIZnet 제품 | W6100 Ethernet Controller |
| 제품 역할 | SPI 기반 hard-wired TCP/IP + Ethernet 컨트롤러 |
| MCU 역할 | STM32F103이 애플리케이션, 인터럽트 처리, SPI/DMA 전송 계층 담당 |
| 드라이버 역할 | W6100 공통 레지스터, 소켓 레지스터, 소켓 상태 머신, 데이터 전송 제어 |
| 구현 확인 칩 | W6100 |
| 목록에는 있으나 구현 미확인 | W6300, W5500, W5300, W5100S, W5100 |
README의 supported chips 항목에서 W6100만 체크되어 있고 W6300, W5500, W5300, W5100S, W5100은 체크되어 있지 않다. 따라서 이 저장소는 현재 기준으로 W6100 중심 구현으로 판단하는 것이 정확하다.
TOE 사용 여부
TOE 사용 여부: 사용함
이 프로젝트는 W6100의 hard-wired TCP/IP 엔진을 사용한다. TCP/UDP 프로토콜 처리는 W6100의 하드웨어 소켓 엔진에 위임하고, Rust 드라이버는 SPI를 통해 레지스터 접근, 소켓 명령, 버퍼 포인터, RX/TX 데이터 이동, 상태 전이를 제어한다. Arduino Ethernet library 경유, ESP-IDF esp_eth / esp_netif 경유, lwIP socket 계층 경유 구조는 아니다.
코드에는 CIDR, VER, SHAR, GAR, SUBR, SIPR, SIR, SIMR, PHYSR 등 W6100 레지스터 주소가 정의되어 있고, TCP listen/connect 및 UDP bind 흐름이 구현되어 있다. 소켓 계층에는 TCP4, UDP4, IPRAW4, MACRAW, TCP6, UDP6 등의 모드 정의가 있으나, 예제 동작은 TCP4/UDP4 echo 중심이다.
Hybrid Network 여부
Hybrid Network: 아님
확인된 네트워크 경로는 W6100을 통한 유선 Ethernet이다. README, 드라이버 crate, STM32 예제 코드에서 Wi-Fi, BLE, cellular 등 별도 무선 네트워크 경로는 확인되지 않는다. TCP 예제와 UDP 예제가 함께 존재하지만, 둘 다 동일한 W6100 Ethernet 인터페이스 위에서 동작하므로 Hybrid Network로 판단하지 않는다.
시스템 구조
Host PC
├─ TCP client: 192.168.10.10:5555
└─ UDP client: 192.168.10.10:5556
│
▼
Ethernet Network
│
▼
WIZnet W6100
├─ Hard-wired TCP/IP engine
├─ 8개 hardware socket
├─ Common register
├─ Socket register
└─ RX/TX socket buffer
│ SPI1 + DMA
▼
STM32F103C8
├─ examples/echo application
├─ interrupt handlers
│ ├─ TIM2 periodic service
│ ├─ EXTI15_10 W6100 INT line
│ └─ DMA1_CHANNEL2 DMA completion
├─ HalSpi transport
└─ wiznet-rs driver crate
│
▼
Application socket handles
├─ TcpSocket read/write
└─ UdpSocket recv_from/send_to구조의 핵심은 드라이버와 BSP의 경계 분리이다. wiznet-rs/src/는 STM32 HAL에 의존하지 않는 플랫폼 독립 드라이버이며, examples/echo/src/hal_spi.rs와 main.rs가 STM32F103의 GPIO, DMA, SPI, timer, EXTI, interrupt wiring을 담당한다.
동작 흐름
1. STM32가 clock, GPIO, SPI1, DMA1, W6100 reset, interrupt line을 초기화한다.
2. W6100을 SPI 레지스터 접근으로 초기화한다.
3. 드라이버가 PHY link 상태를 확인한다.
4. link up 상태가 되면 IPv4 설정을 적용한다.
- IP: 192.168.10.10
- Gateway: 192.168.10.1
- Subnet: 255.255.255.0
5. TCP listener를 5555번 포트에 연다.
6. UDP socket을 5556번 포트에 연다.
7. W6100 INT, timer tick, DMA completion interrupt가 service 흐름을 구동한다.
8. TCP로 수신된 byte stream은 socket ring buffer를 통해 다시 송신된다.
9. UDP datagram은 송신자 주소를 유지한 채 다시 전송된다.
10. link loss 또는 socket close 발생 시 socket을 re-arm한다.예제 코드는 192.168.10.10 주소, TCP 5555, UDP 5556 포트를 사용한다. chip.service()는 인터럽트 컨텍스트에서 호출되며, main loop는 socket handle 접근과 wfi() sleep 중심으로 구성된다.
기술적 특징
| 영역 | 내용 |
|---|---|
| 드라이버 모델 | no_std 기반 플랫폼 독립 Rust crate |
| 하드웨어 접근 | SPI command header 기반 레지스터 및 socket buffer 접근 |
| 대용량 전송 | Full-duplex DMA |
| 완료 모델 | 소형 전송은 Poll, bulk 전송은 Interrupt completion |
| Socket 소유 구조 | W6100 객체가 8개 socket slot을 소유 |
| 데이터 경로 | Lock-free SPSC RX/TX ring |
| 애플리케이션 동작 | main loop는 socket handle만 다루고 wfi()로 대기 |
| unsafe 정책 | 드라이버 crate는 unsafe code deny, 보드 종속 app layer에 제한적 unsafe 허용 |
SPI/DMA 추상화는 SpiDmaDevice, SpiDmaTransaction, DmaBuffers, Completion::{Poll, Interrupt}로 구성된다. Bulk transfer는 드라이버에서 시작되고 DMA 완료 인터럽트에서 마무리된다.
장점
| 장점 | 설명 |
|---|---|
| 드라이버/BSP 분리 | STM32 HAL 의존성을 예제 계층에 격리한다. |
| Rust 임베디드 구조 | no_std, embedded-hal, embedded-dma, nb 기반으로 구성된다. |
| DMA 기반 payload 이동 | TCP/UDP payload 이동 시 CPU byte loop 부담을 줄인다. |
| 인터럽트 기반 서비스 | Timer, W6100 INT, DMA completion interrupt가 chip service를 구동한다. |
| Lock-free 데이터 경로 | ISR과 application thread 사이의 RX/TX ring contention을 줄인다. |
| TCP/UDP 동시 예제 | Stream과 datagram 사용 흐름을 모두 확인할 수 있다. |
| 실제 하드웨어 대상 | STM32F103 + W6100 조합으로 구체화되어 있다. |
한계
| 한계 | 설명 |
|---|---|
| 칩 지원 범위 | README 기준 구현 확인 칩은 W6100뿐이다. |
| W5500 지원 | 구현 완료 여부는 저장소 내 명시 없음. 목록에는 있으나 unchecked 상태이다. |
| DHCP | Runtime network configuration은 있으나 DHCP client 연동은 향후 확장 지점으로 설명된다. |
| 하드웨어 범용성 | 드라이버는 이식성을 목표로 하지만, 포함된 동작 예제는 STM32F103에 고정되어 있다. |
| 릴리스 상태 | GitHub 저장소 view 기준 published release는 확인되지 않는다. |
| 외부 채택 지표 | repository view 기준 star/fork가 낮아 외부 사용 사례는 아직 제한적으로 보인다. |
README는 set_network_config가 향후 DHCP에 의해 구동될 수 있도록 설계되었다고 설명하며, GitHub repository view에서는 published release가 확인되지 않는다.
적용 가치
wiznet-rs의 가치는 단순한 echo 예제보다 WIZnet TOE 칩을 Rust 임베디드 환경에서 어떻게 구조화할 수 있는지에 있다. SPI DMA, interrupt-driven service, socket ownership, lock-free socket handle 설계가 핵심이다.
| 적용 영역 | 가치 |
|---|---|
| Embedded Rust Ethernet firmware | no_std 기반 WIZnet 드라이버 설계 참고 |
| MCU + TOE 네트워킹 | TCP/UDP 처리를 W6100에 위임하는 구조 확인 |
| 저부하 Ethernet I/O | DMA 기반 payload 이동으로 CPU 개입 감소 |
| 산업용 제어 펌웨어 | 결정적 유선 통신 구조의 참고 사례 |
| 드라이버 이식성 설계 | 플랫폼 독립 드라이버와 HAL/BSP 분리 구조 확인 |
최종 요약
wiznet-rs는 WIZnet W6100을 중심으로 한 Rust 임베디드 Ethernet 드라이버 프로젝트이다. no_std 드라이버, 직접 W6100 register/socket 제어, SPI DMA bulk transfer, interrupt 기반 service, lock-free socket data path를 결합한다. STM32F103 예제는 TCP/UDP echo를 통해 W6100 Ethernet 통신 흐름을 검증한다.
다만 저장소에서 구현 대상으로 명확히 확인되는 칩은 W6100이다. 여러 WIZnet 칩을 나열하지만, W5500 등은 현재 구현 완료로 단정할 수 없다. 따라서 이 프로젝트는 범용 WIZnet W-series 완성 드라이버라기보다 W6100 중심의 Rust driver reference로 분류하는 것이 적절하다.
저자 정보
| 항목 | 내용 |
|---|---|
| Repository owner | max619 |
| Repository name | wiznet-rs |
| Repository description | Wiznet W series network chips driver written in Rust |
| License | MIT |
| 공개 지표 | repository view 기준 0 stars, 0 forks |
이 저장소는 GitHub 사용자 max619가 공개한 프로젝트이며, 설명은 Rust로 작성된 WIZnet W-series network chip driver로 등록되어 있다.
