---
title: "W5500 Ethernet Driver with PlatformIO and lwIP"
url: "https://maker.wiznet.io/sophia/projects/w5500-ethernet-driver-with-platformio-and-lwip/"
markdown_url: "https://maker.wiznet.io/sophia/projects/w5500-ethernet-driver-with-platformio-and-lwip/md"
type: "UCC: User Created Content"
author: "Arnoldas Bagdonas"
author_url: "https://github.com/ArnoldasBagdonas/PlatformIO-W5500-Ethernet-Driver-lwIP"
editor: "WIZnet"
editor_url: "https://maker.wiznet.io/"
original_author: "Arnoldas Bagdonas"
original_url: "https://github.com/ArnoldasBagdonas/PlatformIO-W5500-Ethernet-Driver-lwIP"
published: "2026-03-12"
language: "en"
hardware: ["WIZnet W5500"]
likes: 0
views: 450
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# W5500 Ethernet Driver with PlatformIO and lwIP

> PlatformIO와 lwIP로 구현한 W5500 Ethernet Driver

Original author: Arnoldas Bagdonas (source: https://github.com/ArnoldasBagdonas/PlatformIO-W5500-Ethernet-Driver-lwIP)

## Components

- **WIZnet W5500** x 1 ([docs](https://docs.wiznet.io/Product/Chip/Ethernet/W5500))

WIZnet parts: W5500 ([Datasheet](https://docs.wiznet.io/Product/Chip/Ethernet/W5500/datasheet?utm_source=maker&utm_medium=project&utm_campaign=w5500), [product hub](https://maker.wiznet.io/products/w5500/))

## Article

## PlatformIO W5500 Ethernet Driver with lwIP

### PlatformIO와 Arduino 환경에서 구현한 경량 유선 네트워크 스택

## 프로젝트 소개

임베디드 개발에서 Ethernet이 필요할 때는 보통 완성된 라이브러리를 사용하는 경우가 많습니다. 그 방식은 빠르고 편리하지만, 실제로 **하드웨어 Ethernet 컨트롤러와 TCP/IP 스택이 어떻게 연결되는지**까지 깊이 이해하기는 쉽지 않습니다.

이 프로젝트는 그 구조를 직접 보여줍니다.
`PlatformIO-W5500-Ethernet-Driver-lwIP`는 **W5500 Ethernet 컨트롤러를 SPI로 제어하는 저수준 드라이버**를 만들고, 이를 **lwIP TCP/IP 스택**과 연결해 PlatformIO 기반 Arduino 프로젝트에서 동작하도록 구성한 예제입니다. 이 프로젝트는 **Ethernet abstraction layer**, **DHCP/Static IP 지원**, 그리고 **raw TCP API 기반의 미니 HTTP 서버**까지 포함하고 있어, 단순한 Ethernet 사용 예제를 넘어 보다 깊이 있는 학습 자료로 활용할 수 있습니다.

즉, 이 프로젝트는 단순히 Ethernet 연결을 구현하는 수준이 아니라, **임베디드 Ethernet의 내부 구조를 직접 이해하고 확장할 수 있게 해주는 실전형 레퍼런스**라고 볼 수 있습니다.

## 시스템 구조

이 프로젝트의 데이터 흐름은 비교적 명확합니다.
MCU는 SPI를 통해 W5500과 통신하고, W5500은 Ethernet 프레임을 송수신합니다. 상위에서는 lwIP가 네트워크 인터페이스를 관리하고, 애플리케이션 레벨에서는 포트 80에서 동작하는 간단한 HTTP 서버가 요청을 처리합니다.

이 서버는 루트 경로에 접속한 횟수를 표시하는 예제로 구성되어 있어, 패킷 수신, TCP 처리, 응답 생성까지 최소한의 웹 서버 동작을 한 번에 살펴볼 수 있습니다.

## 프로젝트 구조

이 프로젝트에서 특히 눈에 띄는 부분은 **upstream lwIP를 직접 수정하지 않는 구조**입니다. lwIP 원본 코드는 `thirdparty/lwip/` 아래 Git submodule로 포함되고, 실제 PlatformIO 포팅과 설정은 `lib/lwip_wrapper/`에서 담당합니다. 이 wrapper 구조 덕분에 서드파티 소스를 건드리지 않으면서도 유지보수성과 업데이트 편의성을 확보할 수 있습니다.

주요 구성은 다음과 같습니다.

- `w5500.c`: W5500용 SPI 드라이버

- `ethif.c`: 하드웨어 독립적인 Ethernet 인터페이스 계층

- `sys_arch.cpp`: bare-metal 환경용 최소 시스템 추상화

- `lwipopts.h`: no-OS 환경용 lwIP 설정 파일

이런 구조는 단순 예제를 넘어서, **다른 MCU 보드나 응용 프로젝트로 확장하기 좋은 설계 방식**이라는 점에서도 의미가 있습니다.

## 하드웨어 구성

예제 하드웨어는 **Seeeduino XIAO SAMD21**과 **W5500 Ethernet 모듈**을 사용합니다. 필요한 구성품으로는 USB 케이블, RJ45가 연결된 라우터 또는 스위치, 브레드보드와 점퍼선이 포함됩니다.

배선도도 비교적 단순합니다.

- Pin 7 → W5500 SCS

- Pin 8 → W5500 CLK

- Pin 9 → W5500 MISO

- Pin 10 → W5500 MOSI

- GND → W5500 GND

- 5V → W5500 5V

또한 W5500의 RST, INT, 3.3V 핀은 연결하지 않아도 되므로, 핵심 통신 라인만으로 구성이 가능합니다.

## 핵심 기능

이 프로젝트의 핵심 기능은 비교적 분명합니다.

첫째, **DHCP와 Static IP를 모두 지원**합니다. 컴파일 타임 플래그인 `USE_STATIC_IP`를 통해 설정 방식을 바꿀 수 있어, 테스트 환경과 고정 배포 환경 모두에 대응할 수 있습니다.
둘째, **raw lwIP TCP API 기반의 최소 HTTP 서버**가 포함되어 있습니다. 이 서버는 작은 규모이지만, 임베디드 환경에서 TCP 세션과 웹 응답을 어떻게 구성하는지 살펴보기에 충분합니다.

그리고 가장 중요한 점은, 이 모든 기능이 **외부 고수준 Ethernet 라이브러리에 크게 의존하지 않는 구조** 위에 올라가 있다는 점입니다. 즉, 학습용으로도 좋고, 필요하다면 기능을 직접 수정하거나 다른 형태의 네트워크 애플리케이션으로 발전시키기에도 좋습니다.

## W5500의 강점

이 프로젝트에서 W5500을 선택한 이유는 분명합니다.
W5500은 SPI 기반으로 MCU와 쉽게 연결할 수 있고, 유선 Ethernet 인터페이스를 안정적으로 제공할 수 있습니다. 이 저장소는 W5500을 **저수준 RAW MAC 드라이버** 형태로 사용해 lwIP와 직접 연결하는 방식을 택하고 있어, 단순 사용을 넘어 **네트워크 계층을 제어 가능한 형태로 다룬다**는 점이 핵심입니다.

실제로 이런 구조는 다음과 같은 응용으로 확장하기 좋습니다.

- 센서 상태를 웹 페이지로 보여주는 모니터링 장치

- 로컬 네트워크 기반의 설정 페이지

- 유선 Ethernet 기반 산업용 상태 표시 장치

- bare-metal 네트워크 학습용 레퍼런스

## 빌드와 적용

이 프로젝트는 **PlatformIO 기반 Arduino 프로젝트**로 구성되어 있으며, lwIP 원본은 Git submodule로 포함되어 있습니다. 따라서 저장소를 그대로 가져온 뒤 PlatformIO 환경에서 빌드해 예제를 실행하는 흐름을 따릅니다.

라이선스 측면에서는 프로젝트 본체에 MIT 라이선스가 적용되어 있고, lwIP는 원래의 라이선스를 유지합니다.

## 마무리

`PlatformIO-W5500-Ethernet-Driver-lwIP`는 단순한 Ethernet 데모가 아닙니다.
이 프로젝트는 **W5500 드라이버 계층**, **lwIP 통합 구조**, **DHCP/Static IP 지원**, **minimal HTTP server**를 한 번에 보여주며, 임베디드 유선 네트워크를 보다 깊이 이해하고 싶은 개발자에게 좋은 출발점이 됩니다.

PlatformIO의 익숙한 개발 환경 안에서 Ethernet 스택의 내부 구조까지 보고 싶다면, 꽤 흥미로운 참고 사례가 될 것입니다.

### FAQ

**Q1. 이 프로젝트는 어떤 보드를 기준으로 작성되었나요?**
예제 보드는 Seeeduino XIAO SAMD21입니다.

**Q2. DHCP만 지원하나요?**
아니요. DHCP와 Static IP를 모두 지원하며, `USE_STATIC_IP` 플래그로 전환할 수 있습니다.

**Q3. 어떤 예제가 포함되어 있나요?**
포트 80에서 동작하는 minimal HTTP server 예제가 포함되어 있으며, 루트 경로 방문 횟수를 표시합니다.

**Q4. 서드파티 lwIP 소스를 수정하나요?**
아니요. 원본 lwIP는 read-only Git submodule로 두고, 별도의 wrapper 계층으로 통합합니다.

## PlatformIO W5500 Ethernet Driver with lwIP

### A Lightweight Wired Networking Stack for PlatformIO and Arduino

## Project Introduction

In embedded development, Ethernet is often added by simply using a ready-made library. That approach is convenient, but it does not always show how the Ethernet hardware and the TCP/IP stack are actually connected under the hood.

This project makes that structure visible.
`PlatformIO-W5500-Ethernet-Driver-lwIP` builds a **low-level SPI driver for the W5500 Ethernet controller** and connects it to the **lwIP TCP/IP stack** inside a PlatformIO-based Arduino project. It includes an **Ethernet abstraction layer**, **DHCP/static IP support**, and even a **minimal HTTP server based on lwIP’s raw TCP API**, making it far more than a simple Ethernet connectivity example.

In other words, this is not just a demo. It is a **practical reference that helps developers understand and extend embedded Ethernet from the hardware layer upward**.

## System Architecture

The data flow is straightforward.
The MCU communicates with the W5500 over SPI, the W5500 handles Ethernet frame transfer, lwIP manages the network interface, and a lightweight application-level HTTP server listens on port 80.

The included server example counts visits to the root endpoint, making it a compact but effective demonstration of packet handling, TCP processing, and response generation in an embedded environment.

## Project Structure

One of the most interesting parts of this project is that it **does not modify the upstream lwIP source directly**. The original lwIP source is kept in `thirdparty/lwip/` as a Git submodule, while the actual PlatformIO-specific porting logic lives inside `lib/lwip_wrapper/`. This wrapper-based structure improves maintainability and makes future updates easier.

The main components include:

- `w5500.c`: SPI driver for the W5500

- `ethif.c`: hardware-independent Ethernet interface layer

- `sys_arch.cpp`: minimal system abstraction for bare-metal operation

- `lwipopts.h`: lwIP configuration for a no-OS environment

This design makes the project useful not only as a demo, but also as a foundation for adapting the stack to other MCU boards and custom applications.

## Hardware Setup

The example setup uses a **Seeeduino XIAO SAMD21** together with a **W5500 Ethernet module**. The required hardware includes a USB cable, an RJ45 connection through a router or switch, and standard breadboard wiring.

The pin mapping is simple:

- Pin 7 → W5500 SCS

- Pin 8 → W5500 CLK

- Pin 9 → W5500 MISO

- Pin 10 → W5500 MOSI

- GND → W5500 GND

- 5V → W5500 5V

The W5500’s RST, INT, and 3.3V pins are left open, which keeps the wiring minimal.

## Key Features

The main features are clearly defined.

First, the project supports **both DHCP and static IP configuration**. A compile-time flag, `USE_STATIC_IP`, allows switching between the two modes so it can fit both test environments and fixed deployments.
Second, it includes a **minimal embedded HTTP server** built on lwIP’s raw TCP API. Even though the server is lightweight, it clearly demonstrates how a TCP session and web response can be implemented in an embedded application.

Most importantly, these features are implemented in a structure that does **not heavily rely on external high-level Ethernet libraries**. That makes the project valuable both as a learning resource and as a starting point for custom wired networking applications.

## Strength of W5500

The choice of W5500 is a strong fit for this project.
It provides a practical SPI-based wired Ethernet interface that can be integrated cleanly with a microcontroller project. In this repository, the W5500 is used through a **low-level RAW MAC driver**, allowing it to be connected directly to lwIP rather than hidden behind a high-level abstraction.

This makes the structure especially suitable for future extensions such as:

- sensor monitoring devices with a browser-based interface

- local network configuration pages

- industrial status display systems over wired Ethernet

- bare-metal networking study projects

## Build and Usage

The project is organized as a **PlatformIO-based Arduino project**, with the upstream lwIP source included as a Git submodule. The general workflow is to clone the repository and build the example directly in a PlatformIO environment.

The main project uses the MIT License, while lwIP keeps its original license.

## Conclusion

`PlatformIO-W5500-Ethernet-Driver-lwIP` is more than a simple Ethernet demo.
It brings together the **W5500 driver layer**, **lwIP integration structure**, **DHCP/static IP support**, and a **minimal HTTP server** in a single example. For developers who want to go beyond plug-and-play Ethernet and better understand embedded wired networking from the inside, this is a strong reference project.

It is a particularly interesting example for anyone who wants the accessibility of PlatformIO and Arduino-style development together with the technical depth of network stack integration.

### FAQ

**Q1. Which board is used in the example?**
The example board is the Seeeduino XIAO SAMD21.

**Q2. Does it only support DHCP?**
No. It supports both DHCP and static IP configuration through the `USE_STATIC_IP` flag.

**Q3. What example application is included?**
A minimal HTTP server running on port 80 is included, and it counts visits to the root endpoint.

**Q4. Does it modify upstream lwIP directly?**
No. The original lwIP source is kept as a read-only Git submodule, and integration is handled through a wrapper layer.

---

Source: https://maker.wiznet.io/sophia/projects/w5500-ethernet-driver-with-platformio-and-lwip/
