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
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
