Wiznet makers

mark

Published March 13, 2026 ©

90 UCC

8 WCC

42 VAR

0 Contests

0 Followers

0 Following

Original Link

How to Build a Maker TCP Server and Modbus/TCP Stack with W5500?

This project is a compact W5500 porting note focused on bringing up a basic network stack on an MCU by transplanting WIZnet’s official driver files, adding a ha

COMPONENTS
PROJECT DESCRIPTION

How to Build a Maker TCP Server and Modbus/TCP Stack with W5500?

Summary

This project is a compact W5500 porting note focused on bringing up a basic network stack on an MCU by transplanting WIZnet’s official driver files, adding a hardware abstraction layer, then building first a TCP server and later a FreeModbus/TCP service on top. In this setup, the W5500 acts as the hardwired Ethernet endpoint and socket engine, while the MCU-side firmware handles SPI access, reset, PHY setup, network parameter loading, and the application polling loop.

What the Project Does

The article outlines a simple maker-oriented Ethernet bring-up flow. It starts by importing the W5500 driver files w5500.c/.h, socket.c/.h, and wizchip_conf.c/.h, then creates a board-specific file called w5500_port_hal.c to supply the chip-select, SPI, burst transfer, critical-section, reset, chip initialization, PHY initialization, and network information routines. That structure is typical of a practical W5500 integration: keep the vendor socket stack intact and isolate MCU-specific code in a thin hardware layer.

On top of that hardware layer, the article builds a TCP server. Its network-stack flow is explicit: read the socket state, open the socket if it is closed, call listen() when the socket reaches INIT, close it on disconnect, and only exchange data once the connection has been established. The article also notes that client information can be read from registers and that send/receive handling is driven by state flags. This is not a generic Ethernet theory post; it is a practical socket-state machine for a single-server embedded endpoint.

The same article then extends the design into Modbus/TCP using FreeModbus. In main.c, it initializes the Modbus/TCP stack with eMBTCPInit(MB_TCP_PORT_USE_DEFAULT), enables it with eMBEnable(), and runs eMBPoll() in the main loop. It also patches portevent.c so the port layer can trigger TCP polling through xMBPortTCPPool(), and it says a porttcp.c file must be added. For a maker project, that is the important architectural jump: the W5500 does not stop at raw TCP echo or a custom server; it becomes the network transport under a standard industrial application protocol.

Where WIZnet Fits

The exact WIZnet part here is the W5500. Its role is the network controller and hardwired TCP/IP offload engine under the application stack. WIZnet’s documentation describes the W5500 as an Ethernet controller with embedded TCP/IP, integrated 10/100 MAC and PHY, 32 KB internal packet buffer memory, eight independent hardware sockets, and an SPI host interface that supports up to 80 MHz. Those features explain why the article’s design can stay small and maker-friendly: the MCU does not need to run a full software IP stack just to stand up a TCP server or Modbus/TCP endpoint.

In this architecture, the W5500 is the transport boundary. The MCU-side code manages reset, SPI, chip registration, PHY configuration, and local IP settings, but socket operation happens through WIZnet’s driver model. That makes the project a good fit for maker use because it keeps the learning surface narrow: wiring, initialization, socket states, and application polling. It is enough to build a functioning wired node without first integrating a larger software stack such as LwIP.

Implementation Notes

This project does use WIZnet products, and the article shows real function names and call flow, but it does not expose a public repository with line-addressable source files. The implementation details below are therefore limited to what is visible in the article itself.

The board-support layer is centered around a dedicated w5500_port_hal.c file. The article lists the required registration and I/O functions directly: w5500_cris_enter(), w5500_cris_exit(), w5500_cs_select(), w5500_cs_deselect(), w5500_spi_readbyte(), w5500_spi_writebyte(), w5500_spi_readburst(), w5500_spi_writeburst(), and w5500_hard_reset(). Why this matters is architectural: the W5500 driver is only portable if the target MCU provides this exact low-level control boundary for chip-select timing, SPI byte movement, burst transfers, and reset handling.

The initialization layer is also explicit. The article names w5500_chip_init(), w5500_phy_init(), w5500_network_info_init(), w5500_network_info_show(), and w5500_init(), and notes that w5500_init() should be called from main. It even points out that network setup is applied through calls such as wizphy_setphyconf(&conf) and wizchip_getnetinfo(&info). Why this matters is that the project is not just opening a socket; it is formalizing chip bring-up, PHY mode, and local network identity before application traffic begins.

The TCP server logic is a straight socket-state machine. The article shows the intended path: if the socket is closed, call socket(SN, Sn_MR_TCP, 55555, SF_TCP_NODELAY); if the state is INIT, call listen(SN); if disconnected, call close(SN); and if connected, extract client information from registers, check receive flags, and send data. Why this matters is that it makes the W5500’s role in the system concrete: it is a socket-oriented endpoint, not just a MAC/PHY block. The firmware talks to a socket API and builds the application around socket state.

Practical Tips / Pitfalls

Keep the vendor driver files close to upstream and move board differences into w5500_port_hal.c; that will save time when debugging SPI or reset issues.

Bring up static network settings first. The article starts with direct network information initialization before moving into the TCP server and Modbus/TCP layers.

Treat the socket state machine as the application backbone. On W5500, correct handling of CLOSED, INIT, ESTABLISHED, and disconnect cases matters more than building a complicated task structure too early.

Decide buffer allocation early if you expand beyond one or two channels. W5500 has eight sockets, but its 32 KB packet memory is shared across them.

Do not skip the PHY and network-info display steps during first bring-up. Reading back configuration is one of the fastest ways to separate SPI driver faults from link or application faults. This is an inference from the article’s explicit w5500_network_info_show() step and W5500’s configuration model.

When adding FreeModbus, keep the polling path simple and visible. The article’s use of eMBPoll() in the loop and xMBPortTCPPool() in the event layer is a good minimal pattern for maker firmware.

FAQ

Why use W5500 for this project?
Because the project’s goal is to get a working wired TCP server and then Modbus/TCP service on a small MCU with minimal stack burden. The W5500 handles TCP/IP in hardware, gives you eight independent sockets, and exposes a socket-style API over SPI, which is much simpler for a maker project than integrating a full software stack from scratch.

How does it connect to the platform?
Through a board-specific HAL that provides chip select, SPI single-byte transfers, SPI burst transfers, critical-section hooks, and hardware reset. The article makes this explicit by listing those functions as the first step of the port.

What role does it play in this project?
It is the actual network endpoint under the application. The MCU configures the W5500, sets local network information, then uses socket-state transitions to run a TCP server and later a Modbus/TCP service.

Can beginners follow this project?
Yes, if they already understand MCU GPIO, SPI, and the idea of a main polling loop. The article is compact and practical, which suits maker use, but it assumes the reader can already port low-level drivers and reason about socket states.

How does this compare with LwIP?
LwIP gives more flexibility and more direct control of the full stack, but it also requires more RAM, more integration work, and more debugging on the MCU side. The W5500 approach used here keeps the firmware smaller by moving TCP/IP handling into the Ethernet controller and leaving the MCU with initialization, socket control, and application logic.

Source

Original article: CSDN blog post “W5500.” The page states CC 4.0 BY-SA. The article references WIZnet’s official library files and also outlines a FreeModbus/TCP integration path. Product facts were checked against WIZnet’s official W5500 datasheet and application documentation.

Tags

W5500, WIZnet, TCP Server, Modbus TCP, FreeModbus, Embedded Ethernet, Socket Offload, SPI, Maker, Network Stack, MCU Firmware, Hardwired TCP/IP

 

W5500으로 메이커용 TCP 서버와 Modbus/TCP 스택을 어떻게 구축할 수 있을까?

Summary

이 프로젝트는 WIZnet 공식 드라이버 파일을 이식하고, 하드웨어 추상화 계층을 추가한 뒤, 먼저 TCP 서버를 만들고 그 위에 FreeModbus/TCP 서비스를 올리는 방식으로 MCU에서 기본 네트워크 스택을 구동하는 간단한 W5500 포팅 노트다. 이 구조에서 W5500은 하드와이어드 이더넷 종단이자 소켓 엔진 역할을 하고, MCU 측 펌웨어는 SPI 접근, 리셋, PHY 설정, 네트워크 파라미터 로딩, 애플리케이션 폴링 루프를 담당한다.

What the Project Does

이 글은 메이커 관점의 단순한 이더넷 구동 흐름을 설명한다. 먼저 w5500.c/.h, socket.c/.h, wizchip_conf.c/.h 드라이버 파일을 가져오고, 이어서 w5500_port_hal.c라는 보드 전용 파일을 만들어 칩 셀렉트, SPI, 버스트 전송, 크리티컬 섹션, 리셋, 칩 초기화, PHY 초기화, 네트워크 정보 설정 루틴을 넣는다. 이런 구조는 실전 W5500 통합 방식과 잘 맞는다. 즉, 벤더 소켓 스택은 최대한 그대로 두고, MCU 의존 코드는 얇은 하드웨어 계층으로 분리하는 방식이다.

이 하드웨어 계층 위에서 글은 TCP 서버를 구성한다. 네트워크 스택 흐름도 분명하다. 소켓 상태를 읽고, 닫혀 있으면 소켓을 열고, INIT 상태에 도달하면 listen()을 호출하며, 연결이 끊기면 소켓을 닫고, 연결이 성립된 뒤에만 데이터를 주고받는다. 글은 클라이언트 정보를 레지스터에서 읽을 수 있고, 송수신 처리는 상태 플래그 중심으로 돌아간다고도 설명한다. 즉, 이 글은 일반적인 이더넷 이론 설명이 아니라 단일 서버형 임베디드 종단을 위한 실전 소켓 상태 머신 설명이다.

같은 글은 이후 FreeModbus를 이용해 Modbus/TCP로 확장한다. main.c에서는 eMBTCPInit(MB_TCP_PORT_USE_DEFAULT)로 Modbus/TCP 스택을 초기화하고, eMBEnable()로 활성화한 뒤, 메인 루프에서 eMBPoll()을 실행한다. 또한 portevent.c를 수정해 포트 계층이 xMBPortTCPPool()을 통해 TCP 폴링을 트리거하도록 하고, porttcp.c 파일도 추가해야 한다고 설명한다. 메이커 프로젝트 관점에서 중요한 점은 여기다. W5500이 단순한 TCP 에코나 커스텀 서버에 머무는 것이 아니라, 표준 산업용 애플리케이션 프로토콜의 전송 계층 역할까지 확장된다는 점이다.

Where WIZnet Fits

여기서 사용된 정확한 WIZnet 부품은 W5500이다. 이 칩의 역할은 애플리케이션 스택 아래에서 동작하는 네트워크 컨트롤러이자 하드와이어드 TCP/IP 오프로딩 엔진이다. WIZnet 문서에 따르면 W5500은 내장 TCP/IP, 통합 10/100 MAC 및 PHY, 32 KB 내부 패킷 버퍼 메모리, 8개의 독립 하드웨어 소켓, 그리고 최대 80 MHz SPI 호스트 인터페이스를 제공한다. 이런 특성 덕분에 이 글의 설계는 작고 메이커 친화적으로 유지될 수 있다. MCU가 TCP 서버나 Modbus/TCP 엔드포인트를 구현하기 위해 전체 소프트웨어 IP 스택을 직접 돌릴 필요가 없기 때문이다.

이 아키텍처에서 W5500은 전송 경계 역할을 한다. MCU 측 코드는 리셋, SPI, 칩 등록, PHY 설정, 로컬 IP 설정을 담당하지만, 실제 소켓 동작은 WIZnet 드라이버 모델을 통해 이뤄진다. 이런 구조는 메이커 용도에 잘 맞는다. 배선, 초기화, 소켓 상태, 애플리케이션 폴링만 이해해도 동작하는 유선 노드를 만들 수 있고, LwIP 같은 더 큰 소프트웨어 스택을 먼저 통합하지 않아도 되기 때문이다.

Implementation Notes

이 프로젝트는 실제로 WIZnet 제품을 사용하며, 글에는 실제 함수 이름과 호출 흐름도 나온다. 다만 줄 번호를 확인할 수 있는 공개 저장소는 제공되지 않으므로, 아래 구현 설명은 글에서 확인 가능한 내용만 기준으로 한다.

보드 지원 계층의 중심은 전용 w5500_port_hal.c 파일이다. 글에는 필요한 등록 및 I/O 함수가 직접 나열되어 있다. w5500_cris_enter(), w5500_cris_exit(), w5500_cs_select(), w5500_cs_deselect(), w5500_spi_readbyte(), w5500_spi_writebyte(), w5500_spi_readburst(), w5500_spi_writeburst(), w5500_hard_reset()이 그것이다. 이 부분이 중요한 이유는 구조적 경계를 보여주기 때문이다. W5500 드라이버는 타깃 MCU가 칩 셀렉트 타이밍, SPI 바이트 전송, 버스트 전송, 리셋 처리를 위한 저수준 제어 경계를 제공해야만 이식 가능하다.

초기화 계층도 분명하다. 글은 w5500_chip_init(), w5500_phy_init(), w5500_network_info_init(), w5500_network_info_show(), w5500_init()를 언급하며, main에서 w5500_init()을 호출해야 한다고 적고 있다. 또한 wizphy_setphyconf(&conf)wizchip_getnetinfo(&info) 같은 호출로 네트워크 설정이 적용된다고 설명한다. 이것이 중요한 이유는 이 프로젝트가 단순히 소켓 하나를 여는 데 그치지 않고, 애플리케이션 트래픽이 시작되기 전에 칩 구동, PHY 모드, 로컬 네트워크 정체성을 먼저 정리하고 있다는 점이다.

TCP 서버 로직은 전형적인 소켓 상태 머신이다. 글은 다음과 같은 흐름을 보여준다. 소켓이 닫혀 있으면 socket(SN, Sn_MR_TCP, 55555, SF_TCP_NODELAY)를 호출하고, 상태가 INIT이면 listen(SN)을 호출하며, 연결이 끊기면 close(SN)을 호출하고, 연결이 성립된 뒤에는 레지스터에서 클라이언트 정보를 읽고, 수신 플래그를 확인한 뒤 데이터를 송신한다. 이것이 중요한 이유는 시스템 내 W5500의 역할을 매우 구체적으로 보여주기 때문이다. 이 칩은 단순한 MAC/PHY 블록이 아니라 소켓 중심 종단이며, 펌웨어는 소켓 API를 기준으로 애플리케이션을 구성한다.

Practical Tips / Pitfalls

벤더 드라이버 파일은 가능한 한 원본에 가깝게 유지하고, 보드 차이는 w5500_port_hal.c에 모아두는 편이 좋다. SPI나 리셋 문제를 디버깅할 때 훨씬 수월하다.

처음에는 고정 네트워크 설정부터 올리는 것이 좋다. 이 글도 직접 네트워크 정보를 초기화한 뒤 TCP 서버와 Modbus/TCP 계층으로 넘어간다.

소켓 상태 머신을 애플리케이션의 중심으로 다뤄야 한다. W5500에서는 CLOSED, INIT, ESTABLISHED, 연결 종료 상태를 정확히 처리하는 것이, 처음부터 복잡한 태스크 구조를 만드는 것보다 더 중요하다.

채널을 하나 둘 이상으로 늘릴 계획이라면 버퍼 할당을 초기에 정해야 한다. W5500은 8개 소켓을 제공하지만, 32 KB 패킷 메모리를 공유한다.

첫 구동 때는 PHY 상태와 네트워크 정보 출력 단계를 생략하지 않는 편이 좋다. 설정을 다시 읽어보는 것은 SPI 드라이버 문제와 링크 또는 애플리케이션 문제를 빠르게 분리하는 가장 쉬운 방법 중 하나다.

FreeModbus를 추가할 때는 폴링 경로를 단순하게 유지하는 것이 좋다. 글에서처럼 루프에서 eMBPoll()을 돌리고, 이벤트 계층에서 xMBPortTCPPool()을 연결하는 방식은 메이커 펌웨어에 적합한 최소 패턴이다.

FAQ

왜 이 프로젝트에 W5500을 써야 하나?
이 프로젝트의 목표는 작은 MCU에서 최소한의 스택 부담으로 동작하는 유선 TCP 서버와 이후 Modbus/TCP 서비스를 만드는 것이다. W5500은 TCP/IP를 하드웨어에서 처리하고, 8개의 독립 소켓을 제공하며, SPI 기반 소켓 스타일 API를 노출한다. 그래서 전체 소프트웨어 스택을 처음부터 통합하는 방식보다 메이커 프로젝트에 훨씬 단순하다.

플랫폼과는 어떻게 연결되는가?
칩 셀렉트, SPI 단일 바이트 전송, SPI 버스트 전송, 크리티컬 섹션 훅, 하드웨어 리셋을 제공하는 보드 전용 HAL을 통해 연결된다. 글은 이 함수들을 포팅의 첫 단계로 직접 나열하고 있다.

이 프로젝트에서 W5500의 역할은 무엇인가?
애플리케이션 아래에서 실제 네트워크 엔드포인트 역할을 한다. MCU는 W5500을 설정하고 로컬 네트워크 정보를 적용한 뒤, 소켓 상태 전이를 이용해 TCP 서버를 실행하고, 이후 Modbus/TCP 서비스까지 확장한다.

초보자도 따라갈 수 있는가?
가능하다. 다만 MCU GPIO, SPI, 메인 폴링 루프 개념은 알고 있어야 한다. 글은 짧고 실용적이어서 메이커 용도에 잘 맞지만, 독자가 이미 저수준 드라이버를 포팅하고 소켓 상태를 해석할 수 있다고 가정한다.

LwIP와 비교하면 어떤 차이가 있는가?
LwIP는 더 유연하고 전체 스택에 대한 직접 제어권도 더 크지만, 더 많은 RAM, 더 많은 통합 작업, 더 많은 MCU 측 디버깅이 필요하다. 반면 여기의 W5500 방식은 TCP/IP 처리를 이더넷 컨트롤러로 넘기고, MCU에는 초기화, 소켓 제어, 애플리케이션 로직만 남기므로 펌웨어가 더 단순해진다.

Source

원문 출처: CSDN 블로그 게시물 “W5500.”
페이지에는 CC 4.0 BY-SA가 표시되어 있다.
글은 WIZnet 공식 라이브러리 파일과 FreeModbus/TCP 통합 경로를 함께 설명하며, 제품 관련 사실은 WIZnet 공식 W5500 데이터시트와 애플리케이션 문서를 기준으로 확인했다.

Tags

W5500, WIZnet, TCP Server, Modbus TCP, FreeModbus, Embedded Ethernet, Socket Offload, SPI, Maker, Network Stack, MCU Firmware, Hardwired TCP/IP

 
 
Documents
Comments Write