Wiznet makers

chen

Published March 29, 2026 ©

95 UCC

1 WCC

27 VAR

0 Contests

0 Followers

0 Following

Original Link

How to Develop a W5500 Hardware TCP/IP Driver and Socket Flow on STM32?

This article is a driver-oriented technical walkthrough of the W5500 rather than a full repository-backed product,

COMPONENTS
PROJECT DESCRIPTION

How to Develop a W5500 Hardware TCP/IP Driver and Socket Flow on STM32?

Summary

This article is a driver-oriented technical walkthrough of the W5500 rather than a full repository-backed product, but it is useful for both education and commercial embedded work because it explains the actual control flow between an MCU and a hardware TCP/IP Ethernet controller. The platform is an STM32-class MCU over SPI, the goal is wired Ethernet communication, and the W5500’s role is to offload TCP/IP transport, socket state transitions, and packet buffering so the MCU only manages register access, command sequencing, and payload movement.

What the Project Does

The source explains how to build a usable W5500 driver stack from the bottom up. It starts by describing the chip architecture, then moves into register space, SPI access rules, socket registers, and finally a concrete socket lifecycle API for a TCP server. That means the article is not just introducing W5500 features. It is showing how firmware should actually be structured if the MCU is expected to bring the chip up, configure networking, and drive socket-based communication.

From a network-stack perspective, the main lesson is the hardware/software split. The W5500 implements the Ethernet controller, MAC, PHY, and hardware TCP/IP engine, while the MCU controls it through SPI and register writes. The article explicitly says the chip handles functions such as TCP handshake, retransmission, checksum calculation, and sliding-window behavior in hardware, while the MCU only triggers state-machine transitions through register access. For education, this is valuable because it shows exactly how hardware-offloaded networking differs from a pure software stack.

The source also frames the device as relevant to industrial control, smart instrumentation, and remote I/O, where deterministic behavior and low MCU burden matter. That makes the architecture relevant to commercial systems, not just classroom exercises: the same driver structure that helps a student understand socket flow is also the one a product team would use to build a maintainable embedded Ethernet interface.

Where WIZnet Fits

The exact WIZnet product here is the W5500. The article describes it as a hardware TCP/IP Ethernet controller with integrated MAC and PHY, 32 KB embedded RAM for socket buffering, eight independent hardware sockets, and SPI as the host interface. It also states that the chip supports TCP, UDP, ICMP, DHCP, and related networking functions in hardware.

In this architecture, WIZnet is providing the network engine itself, not just a PHY or low-level link block. The MCU does not construct Ethernet, IP, and TCP behavior in software for every exchange. Instead, it configures network identity, writes socket mode and port information, triggers commands such as open or listen, and checks state and interrupt registers to know what happened next. That is the defining W5500 firmware model, and it is exactly what the article teaches.

This is why the W5500 fits both educational and commercial use. For learners, it exposes network control as a register-driven hardware state machine. For commercial systems, it reduces software stack complexity and gives a repeatable integration boundary between product firmware and Ethernet transport behavior.

Implementation Notes

This project does use WIZnet products, and the article includes real code snippets, but it does not expose a public source tree with file paths and line-numbered repository files. The implementation details below are therefore limited to what is directly visible in the article.

One short verified example shows the low-level SPI access layer:

 
static void w5500_spi_write(uint8_t cmd, uint16_t addr, uint8_t data) {
    uint8_t tx_buf[4] = {cmd, (uint8_t)(addr >> 8), (uint8_t)addr, data};
    HAL_SPI_Transmit(&hspi1, tx_buf, 4, HAL_MAX_DELAY);
}

static uint8_t w5500_spi_read(uint8_t cmd, uint16_t addr) {
    uint8_t tx_buf[4] = {cmd, (uint8_t)(addr >> 8), (uint8_t)addr, 0xFF};
    uint8_t rx_buf[4];
    HAL_SPI_TransmitReceive(&hspi1, tx_buf, rx_buf, 4, HAL_MAX_DELAY);
    return rx_buf[3];
}
 

Why it matters: this is the real hardware boundary of the stack. It shows that the MCU is not calling an abstract network API first. It is constructing SPI command frames, sending them through the STM32 HAL, and using that mechanism to read and write W5500 registers. The article also emphasizes that CS handling must be correct and that SPI communication must follow the device’s full-duplex timing rules.

A second verified example shows how register access is wrapped into a clearer driver layer:

 
#define W5500_REG_GAR       0x0009
#define W5500_REG_SUBR      0x000F
#define W5500_REG_SHAR      0x0020

static inline void w5500_write_16bit(uint16_t addr, uint16_t value) {
    w5500_spi_write(0x04, addr, (uint8_t)(value >> 8));
    w5500_spi_write(0x04, addr + 1, (uint8_t)value);
}
 

Why it matters: this is where the firmware becomes maintainable. The article is not just showing raw transactions. It is demonstrating the expected driver pattern: define register addresses, encapsulate common access patterns, and build a cleaner socket-control layer on top. That structure is what makes the design suitable for commercial firmware as well as education.

A third verified example shows the socket lifecycle for a TCP server:

 
uint8_t w5500_socket_tcp_server(uint8_t sn, uint16_t port) {
    w5500_write_8bit(W5500_Sn_CR(sn), 0x10); // CLOSE
    HAL_Delay(1);
    w5500_write_8bit(W5500_Sn_MR(sn), 0x02);
    w5500_write_16bit(W5500_Sn_PORT(sn), port);
    w5500_write_8bit(W5500_Sn_CR(sn), 0x02);

    for(uint16_t i = 0; i < 10000; i++) {
        if(w5500_read_8bit(W5500_Sn_SR(sn)) == 0x14)
            return 0;
        HAL_Delay(1);
    }
    return 1;
}
 

Why it matters: this is the clearest demonstration of the W5500 firmware flow. The host closes the socket, sets the mode, sets the port, triggers the command register, then polls the status register until the hardware socket engine reaches the expected state. That is the core programming model of the chip: command, wait, inspect state, continue.

Practical Tips / Pitfalls

  • Keep SPI access disciplined. The article stresses that even single-byte operations must follow the expected command-frame format, and any timing mistake can break register access. 
  • Separate the driver into layers. The source is strongest when read as three tiers: SPI hardware abstraction, register access wrappers, and socket lifecycle APIs. 
  • Treat Sn_CR as a trigger and Sn_SR as the truth source for state. The article’s TCP server flow depends on that exact relationship. 
  • Use timeout protection around socket-state polling. The example server code does this, which is especially important in commercial products. 
  • Handle CS explicitly and correctly when using STM32 HAL SPI. The article calls this out as necessary for reliable communication. 
  • Do not assume hardware offload means no firmware structure is needed. The chip handles transport behavior, but the host still owns initialization order, mode selection, state checks, and recovery paths. 

FAQ

Why use the W5500 instead of implementing the whole stack in MCU firmware?
Because the W5500 moves much of the Ethernet and TCP/IP transport burden into dedicated hardware. The article explicitly describes handshake handling, retransmission, checksum work, and socket state transitions as hardware-managed, which reduces MCU-side stack complexity.

How does the W5500 connect to the platform?
Through SPI. The article shows an STM32 HAL-based SPI layer using four-byte command frames, manual chip-select handling, and register-mapped read/write access.

What role does the W5500 play in this source specifically?
It is both the subject of the lesson and the hardware network engine being controlled. The page is essentially a technical guide to writing a W5500 driver and socket flow on an MCU.

Can beginners follow this article?
Yes, but it is best for beginner-to-intermediate embedded developers who already understand basic SPI and MCU firmware structure. The article is technical and register-heavy, so it works better as a guided learning reference than as a first-ever networking tutorial.

How does this compare with LwIP or another software stack?
The architecture is fundamentally different. A software stack keeps protocol behavior in MCU code, while the W5500 exposes a command-and-register control model for hardware-managed transport. That usually lowers MCU burden and improves determinism, but it also means working within the chip’s socket-engine model.

Source

Original article: CSDN post, “W5500硬件TCP/IP协议栈驱动开发与实战,” published March 22, 2026, under CC 4.0 BY-SA. The visible content includes W5500 architecture, SPI command framing, register mapping, and a socket TCP server control example.

Tags

W5500, WIZnet, Embedded Ethernet, Hardware TCP/IP, SPI, Socket Engine, Register Access, Firmware Flow, STM32, Education, Commercial, Driver Architecture

STM32에서 W5500 하드웨어 TCP/IP 드라이버와 소켓 흐름을 어떻게 개발할 수 있을까?

Summary

이 글은 완전한 저장소 기반 제품 예제라기보다 W5500 자체를 중심으로 한 드라이버 지향 기술 해설에 가깝다. 하지만 교육용과 상용 임베디드 개발 양쪽 모두에 유용하다. MCU와 하드웨어 TCP/IP 이더넷 컨트롤러 사이의 실제 제어 흐름을 설명하기 때문이다. 플랫폼은 SPI로 연결되는 STM32 계열 MCU이고, 목표는 유선 이더넷 통신이며, W5500의 역할은 TCP/IP 전송, 소켓 상태 전이, 패킷 버퍼링을 하드웨어로 오프로딩해 MCU가 레지스터 접근, 명령 순서 제어, 페이로드 이동만 처리하도록 만드는 것이다.

What the Project Does

이 소스는 W5500 드라이버 스택을 아래에서 위로 어떻게 구성할 수 있는지 설명한다. 먼저 칩 아키텍처를 설명하고, 이어서 레지스터 공간, SPI 접근 규칙, 소켓 레지스터, 마지막으로 TCP 서버용 구체적인 소켓 라이프사이클 API로 넘어간다. 즉, 단순히 W5500의 기능을 소개하는 것이 아니라, MCU가 칩을 구동하고, 네트워크를 설정하고, 소켓 기반 통신을 제어하려면 펌웨어가 어떤 구조를 가져야 하는지를 보여준다.

네트워크 스택 관점에서 핵심 교훈은 하드웨어와 소프트웨어의 역할 분리다. W5500은 이더넷 컨트롤러, MAC, PHY, 하드웨어 TCP/IP 엔진을 구현하고, MCU는 SPI와 레지스터 쓰기를 통해 이를 제어한다. 글은 TCP 핸드셰이크, 재전송, 체크섬 계산, 슬라이딩 윈도 동작 같은 기능을 칩이 하드웨어에서 처리하고, MCU는 레지스터 접근으로 상태 기계 전이만 트리거한다고 분명히 설명한다. 교육용으로 특히 유용한 이유가 여기에 있다. 하드웨어 오프로딩 네트워킹이 순수 소프트웨어 스택과 어떻게 다른지 정확히 보여주기 때문이다.

이 글은 또 산업 제어, 스마트 계측기, 원격 I/O 같은 분야에서도 W5500 구조가 적합하다고 설명한다. 결정성이 중요하고 MCU 부담을 줄여야 하는 상용 시스템에서 이 구조가 바로 쓰일 수 있기 때문이다. 즉, 학생이 배우는 소켓 흐름 구조와 제품 팀이 실제로 유지보수 가능한 임베디드 이더넷 인터페이스를 만들 때 쓰는 구조가 사실상 동일하다는 점이 중요하다.

Where WIZnet Fits

여기서 사용되는 정확한 WIZnet 제품은 W5500이다. 글은 W5500을 통합 MAC 및 PHY, 32 KB 내장 RAM 기반 소켓 버퍼, 8개의 독립 하드웨어 소켓, SPI 호스트 인터페이스를 가진 하드웨어 TCP/IP 이더넷 컨트롤러로 설명한다. 또한 TCP, UDP, ICMP, DHCP 같은 네트워크 기능을 하드웨어에서 지원한다고 말한다.

이 아키텍처에서 WIZnet은 단순한 PHY나 링크 계층 보조 블록을 제공하는 것이 아니다. W5500이 네트워크 엔진 자체를 제공한다. MCU는 매 통신마다 Ethernet, IP, TCP 동작을 소프트웨어로 직접 구성하지 않는다. 대신 네트워크 정체성을 설정하고, 소켓 모드와 포트 정보를 쓰고, open이나 listen 같은 명령을 내리고, 상태 및 인터럽트 레지스터를 확인해 다음 동작을 결정한다. 바로 이것이 W5500 펌웨어 모델의 핵심이며, 이 글도 그 점을 중심으로 설명한다.

이 구조가 교육용과 상용 용도 모두에 맞는 이유도 여기에 있다. 학습자에게는 레지스터 기반 하드웨어 상태 기계로서 네트워크 제어를 보여주고, 상용 시스템에는 제품 펌웨어와 이더넷 전송 계층 사이에 반복 가능하고 유지보수 쉬운 경계를 제공한다.

Implementation Notes

이 프로젝트는 실제로 WIZnet 제품을 사용하며, 글 안에는 실제 코드 조각도 포함되어 있다. 다만 공개 저장소 형태의 소스 트리와 파일 경로, 줄 번호는 제공되지 않는다. 따라서 아래 구현 설명은 글 안에서 직접 확인 가능한 코드만 기준으로 한다.

검증 가능한 예시 중 하나는 저수준 SPI 접근 계층이다.

 
static void w5500_spi_write(uint8_t cmd, uint16_t addr, uint8_t data) {
    uint8_t tx_buf[4] = {cmd, (uint8_t)(addr >> 8), (uint8_t)addr, data};
    HAL_SPI_Transmit(&hspi1, tx_buf, 4, HAL_MAX_DELAY);
}

static uint8_t w5500_spi_read(uint8_t cmd, uint16_t addr) {
    uint8_t tx_buf[4] = {cmd, (uint8_t)(addr >> 8), (uint8_t)addr, 0xFF};
    uint8_t rx_buf[4];
    HAL_SPI_TransmitReceive(&hspi1, tx_buf, rx_buf, 4, HAL_MAX_DELAY);
    return rx_buf[3];
}
 

이 코드가 중요한 이유는 이것이 전체 스택의 실제 하드웨어 경계이기 때문이다. MCU는 처음부터 추상적인 네트워크 API를 호출하는 것이 아니라, SPI 명령 프레임을 만들고, STM32 HAL을 통해 전송하며, 그 방식으로 W5500 레지스터를 읽고 쓴다. 글은 또 CS 제어가 반드시 정확해야 하고, SPI 통신은 디바이스의 full-duplex 타이밍 규칙을 따라야 한다고 강조한다.

두 번째 검증 가능한 예시는 레지스터 접근을 더 명확한 드라이버 계층으로 감싸는 부분이다.

 
#define W5500_REG_GAR       0x0009
#define W5500_REG_SUBR      0x000F
#define W5500_REG_SHAR      0x0020

static inline void w5500_write_16bit(uint16_t addr, uint16_t value) {
    w5500_spi_write(0x04, addr, (uint8_t)(value >> 8));
    w5500_spi_write(0x04, addr + 1, (uint8_t)value);
}
 

이 코드가 중요한 이유는 여기서부터 펌웨어가 유지보수 가능한 구조를 갖기 시작하기 때문이다. 단순한 원시 트랜잭션 나열이 아니라, 레지스터 주소를 정의하고, 공통 접근 패턴을 캡슐화하고, 그 위에 더 깔끔한 소켓 제어 계층을 올리는 방식이다. 이 구조 덕분에 이 설계는 교육용뿐 아니라 상용 펌웨어에도 적합해진다.

세 번째 검증 가능한 예시는 TCP 서버용 소켓 라이프사이클이다.

 
uint8_t w5500_socket_tcp_server(uint8_t sn, uint16_t port) {
    w5500_write_8bit(W5500_Sn_CR(sn), 0x10); // CLOSE
    HAL_Delay(1);
    w5500_write_8bit(W5500_Sn_MR(sn), 0x02);
    w5500_write_16bit(W5500_Sn_PORT(sn), port);
    w5500_write_8bit(W5500_Sn_CR(sn), 0x02);

    for(uint16_t i = 0; i < 10000; i++) {
        if(w5500_read_8bit(W5500_Sn_SR(sn)) == 0x14)
            return 0;
        HAL_Delay(1);
    }
    return 1;
}
 

이 코드가 중요한 이유는 W5500 펌웨어 흐름을 가장 분명하게 보여주기 때문이다. 호스트는 먼저 소켓을 닫고, 모드를 설정하고, 포트를 설정하고, 커맨드 레지스터를 트리거한 뒤, 상태 레지스터가 원하는 상태가 될 때까지 확인한다. 이것이 바로 W5500 프로그래밍 모델의 핵심이다. 명령을 내리고, 기다리고, 상태를 확인하고, 다음 단계로 진행하는 구조다.

Practical Tips / Pitfalls

  • SPI 접근은 엄격하게 다뤄야 한다. 글은 단일 바이트 연산도 예상된 명령 프레임 형식을 따라야 하며, 타이밍이 틀어지면 레지스터 접근 자체가 깨질 수 있다고 강조한다.
  • 드라이버는 계층으로 나누는 편이 좋다. 이 글은 SPI 하드웨어 추상화, 레지스터 접근 래퍼, 소켓 라이프사이클 API라는 세 단계로 읽을 때 가장 잘 이해된다.
  • Sn_CR은 트리거 레지스터로 보고, Sn_SR은 실제 상태의 기준으로 다뤄야 한다. 글의 TCP 서버 흐름은 정확히 이 관계에 의존한다.
  • 소켓 상태 폴링에는 반드시 타임아웃 보호를 두는 편이 좋다. 예제 서버 코드도 그렇게 구현되어 있으며, 상용 제품에서는 특히 중요하다.
  • STM32 HAL SPI를 쓸 때는 CS를 명시적으로 정확하게 처리해야 한다. 글도 이 점을 신뢰성 확보의 핵심으로 지적한다.
  • 하드웨어 오프로딩이 있다고 해서 펌웨어 구조가 필요 없는 것은 아니다. 칩이 전송 동작을 맡더라도, 호스트는 여전히 초기화 순서, 모드 선택, 상태 확인, 복구 경로를 책임져야 한다.

FAQ

왜 전체 스택을 MCU 펌웨어에 구현하지 않고 W5500을 사용하는가?
W5500은 이더넷과 TCP/IP 전송 부담의 상당 부분을 전용 하드웨어로 넘겨준다. 글은 핸드셰이크, 재전송, 체크섬 처리, 소켓 상태 전이를 하드웨어가 관리한다고 설명하며, 그 덕분에 MCU 쪽 스택 복잡도가 줄어든다고 본다.

W5500은 플랫폼과 어떻게 연결되는가?
SPI로 연결된다. 글은 STM32 HAL 기반 SPI 계층에서 4바이트 명령 프레임을 사용하고, 수동 칩 셀렉트 처리와 레지스터 매핑 기반 읽기/쓰기를 수행하는 구조를 보여준다.

이 소스에서 W5500의 구체적인 역할은 무엇인가?
학습 대상이자 실제 하드웨어 네트워크 엔진이다. 페이지 전체가 사실상 MCU에서 W5500 드라이버와 소켓 흐름을 어떻게 작성하는지에 대한 기술 가이드다.

초보자도 이 글을 따라갈 수 있는가?
가능하다. 다만 기본적인 SPI와 MCU 펌웨어 구조를 이미 이해하는 초급~중급 임베디드 개발자에게 더 적합하다. 내용이 기술적이고 레지스터 중심이기 때문에, 첫 네트워킹 입문서보다는 guided reference에 가깝다.

LwIP 같은 소프트웨어 스택과 비교하면 어떤 차이가 있는가?
구조 자체가 다르다. 소프트웨어 스택은 프로토콜 동작을 MCU 코드 안에 두지만, W5500은 하드웨어 관리형 전송에 대해 명령+레지스터 제어 모델을 제공한다. 이 방식은 MCU 부담을 낮추고 결정성을 높이는 대신, 칩의 소켓 엔진 모델 안에서 동작해야 한다는 특징이 있다.

 

Documents
Comments Write