How to Build a Modbus TCP Slave with WIZnet W5500 on AI8051U?
This AI8051U commercial embedded project uses WIZnet W5500 to implement a Modbus TCP slave over wired Ethernet.
How to Build a Modbus TCP Slave with WIZnet W5500 on AI8051U?
Summary
This AI8051U commercial embedded project uses WIZnet W5500 to implement a Modbus TCP slave over wired Ethernet. The AI8051U firmware controls W5500 through SPI, while W5500 provides the Ethernet MAC/PHY, hardware TCP/IP stack, TCP socket transport, and packet buffering needed for a Modbus TCP client to read and write device registers. The public CSDN page confirms the project goal is to understand Modbus TCP, learn a Modbus TCP slave driver, and test with Modbus Poll.
What the Project Does
The project implements a Modbus TCP slave on an AI8051U microcontroller using a WIZnet W5500 Ethernet controller. Modbus TCP is described in the source article as an industrial communication protocol based on TCP/IP and designed for Ethernet environments. It extends the Modbus message model by encapsulating Modbus data inside TCP packets.
The system architecture is a typical commercial device pattern: a PC, HMI, PLC, gateway, or commissioning tool acts as the Modbus TCP client, while the AI8051U + W5500 board acts as the Modbus TCP slave/server. The client sends requests such as reading holding registers or writing a register, and the embedded device parses the Modbus TCP frame, maps the request to internal data or I/O state, and returns a response over the same TCP connection.
The public search summary states that the implementation focuses on function codes 0x03 and 0x06, includes C code for slave-side data handling, register read/write operations, and response frame construction, and uses W5500 for network communication. It also states that the program can process master read/write requests and control LED device state. The full source section is not visible on the public article page, so the exact project code cannot be quoted line by line.
Where WIZnet Fits
The exact WIZnet product is W5500. In this project, W5500 is the wired Ethernet and TCP transport engine for the AI8051U Modbus TCP slave. The AI8051U owns the Modbus application logic: register mapping, function-code parsing, response construction, LED or device-state updates, and firmware-level error handling. W5500 owns the Ethernet-side network work: MAC/PHY operation, TCP socket state, packet buffering, and SPI-accessible socket registers.
W5500 is a good fit for this architecture because it provides a hardwired TCP/IP stack, SPI mode 0/3 access up to 80 MHz, an embedded 10/100 Ethernet MAC/PHY, 8 independent sockets, and 32 KB internal memory for Tx/Rx buffers. It supports hardwired protocols including TCP, UDP, ICMP, IPv4, ARP, IGMP, and PPPoE.
For commercial Modbus TCP equipment, this split is practical. The AI8051U can keep its firmware centered on deterministic device behavior and Modbus register semantics, while W5500 handles TCP state and packet movement. That reduces the amount of RAM and timing-sensitive TCP/IP code that must run inside the MCU, which is useful for small industrial controllers, I/O modules, sensor nodes, retrofit gateways, and service interfaces.
Implementation Notes
The public article confirms W5500 Modbus TCP slave use, but the complete source code is behind CSDN subscription access. The implementation below is therefore not copied from the project.
Conceptual integration example based on WIZnet ioLibrary
#include "wizchip_conf.h"
#include "socket.h"
#define MODBUS_SOCKET 0
#define MODBUS_PORT 502
static uint8_t tx_size[8] = {2,2,2,2,2,2,2,2};
static uint8_t rx_size[8] = {2,2,2,2,2,2,2,2};
void w5500_modbus_network_init(void)
{
reg_wizchip_cs_cbfunc(w5500_select, w5500_deselect);
reg_wizchip_spi_cbfunc(w5500_spi_read, w5500_spi_write);
wizchip_init(tx_size, rx_size);
wizchip_setnetinfo(&net_info);
}This layer exists because WIZnet ioLibrary is platform-independent. The AI8051U firmware must provide W5500 chip-select and SPI read/write functions before it can use W5500 socket APIs. WIZnet describes ioLibrary as an Internet Offload Library for WIZnet chips, including W5500, and states that it provides Berkeley-style socket APIs.
void modbus_tcp_slave_task(void)
{
uint8_t status = getSn_SR(MODBUS_SOCKET);
switch (status) {
case SOCK_CLOSED:
socket(MODBUS_SOCKET, Sn_MR_TCP, MODBUS_PORT, 0);
break;
case SOCK_INIT:
listen(MODBUS_SOCKET);
break;
case SOCK_ESTABLISHED:
if (getSn_RX_RSR(MODBUS_SOCKET) > 0) {
int32_t len = recv(MODBUS_SOCKET, rx_buf, sizeof(rx_buf));
if (len > 0) {
int32_t rsp_len = modbus_build_response(rx_buf, len, tx_buf);
if (rsp_len > 0) {
send(MODBUS_SOCKET, tx_buf, rsp_len);
}
}
}
break;
case SOCK_CLOSE_WAIT:
disconnect(MODBUS_SOCKET);
close(MODBUS_SOCKET);
break;
}
}This task shows the expected firmware structure. W5500 maintains the TCP socket state and receive buffer, while the AI8051U parses the Modbus TCP Application Data Unit. A Modbus TCP message includes an MBAP header and a PDU; the article lists the MBAP fields as transaction identifier, protocol identifier, length, and unit identifier, followed by the PDU function code and data.
For function code 0x03, the firmware typically reads holding registers and returns register values. For function code 0x06, it writes a single register and echoes the accepted write request. The public search summary identifies these two function codes as the focus of the original implementation.
Practical Tips / Pitfalls
- Validate W5500 SPI communication before testing Modbus. If register access is unstable, the Modbus parser will appear unreliable even when the real fault is below TCP.
- Use port
502only when the deployment policy allows it. Modbus reserves TCP port502, but some test environments use a higher configurable port to avoid permissions or firewall restrictions. - Keep the MBAP transaction identifier unchanged in responses. The client uses it to match replies to requests.
- Separate the Modbus register map from raw device variables. Commercial firmware should define address ranges, access permissions, scaling, and invalid-address behavior.
- Handle socket recovery explicitly. Cable removal, client crash, duplicate connections, half-open TCP state, and switch reboot should return the W5500 socket to a known listen state.
- Bound-check every request. Validate length, function code, start address, register count, and output buffer size before constructing the response.
- Add installation diagnostics. Log IP address, link status, socket state, last function code, exception code, and request counter through UART or a service interface.
FAQ
Q: Why use WIZnet W5500 for a Modbus TCP slave on AI8051U?
A: W5500 provides the wired Ethernet MAC/PHY, hardwired TCP/IP stack, TCP socket state machine, 8 sockets, and internal Tx/Rx buffers. That lets the AI8051U focus on Modbus register logic, function-code handling, and device behavior rather than running a full TCP/IP stack in MCU firmware.
Q: How does W5500 connect to the AI8051U platform?
A: W5500 connects to the AI8051U through SPI plus chip select, reset, interrupt, power, ground, and the Ethernet RJ45/magnetics path. In firmware, the AI8051U must register W5500 SPI read/write and chip-select callbacks before using socket functions from ioLibrary.
Q: What role does W5500 play in this Modbus TCP project?
A: W5500 provides the TCP server transport for the Modbus TCP slave. The Modbus client connects to the W5500 socket, sends requests, and receives responses; the AI8051U parses the Modbus function code and maps it to registers, LEDs, or device state.
Q: Can beginners follow this commercial-style project?
A: It is suitable for developers who already understand embedded C, SPI, IPv4 addressing, TCP client/server behavior, and basic Modbus register concepts. For commercial use, the important additions are exception responses, register-map documentation, watchdog recovery, access control, and production diagnostics.
Q: How does W5500 compare with an LwIP-based Modbus TCP slave?
A: With W5500, TCP/IP processing, socket state, and packet buffering are handled by the Ethernet controller, so the AI8051U mainly drives SPI and Modbus application logic. With LwIP, the MCU typically owns more of the Ethernet driver integration, packet buffers, memory pools, protocol timers, and TCP state handling; that can be flexible, but it increases firmware complexity on small commercial controllers.
Source
Original article: CSDN, “[AI8051U入门第十二步]W5500-Modbus TCP从机.” The public page confirms the learning goals and Modbus TCP introduction, but the full implementation is not publicly visible without unlocking the article.
CSDN search summary: confirms W5500-based Modbus TCP slave implementation, function codes 0x03 and 0x06, register read/write handling, response-frame construction, and LED/device-state control.
WIZnet product reference: W5500 Ethernet Controller documentation.
WIZnet driver reference: Wiznet/ioLibrary_Driver, MIT license.
Modbus protocol reference: Modbus Organization, Modbus Application Protocol Specification V1.1b3.
Tags
#W5500 #WIZnet #AI8051U #ModbusTCP #TCPServer #IndustrialEthernet #SPI #ioLibrary #EmbeddedC #Commercial #NetworkStack #HardwareWiring #Firmware #Performance
AI8051U에서 WIZnet W5500으로 Modbus TCP Slave를 구축하는 방법은?
요약
이 AI8051U 상용 임베디드 프로젝트는 WIZnet W5500을 사용해 유선 이더넷 기반 Modbus TCP Slave를 구현합니다. AI8051U 펌웨어는 SPI로 W5500을 제어하고, W5500은 Modbus TCP Client가 장치 레지스터를 읽고 쓸 수 있도록 Ethernet MAC/PHY, 하드웨어 TCP/IP 스택, TCP 소켓 전송, 패킷 버퍼링을 제공합니다. 공개 CSDN 페이지에서는 이 프로젝트의 목표가 Modbus TCP 이해, Modbus TCP Slave 드라이버 학습, Modbus Poll을 이용한 테스트임을 확인할 수 있습니다.
프로젝트가 하는 일
이 프로젝트는 AI8051U 마이크로컨트롤러와 WIZnet W5500 이더넷 컨트롤러를 사용해 Modbus TCP Slave를 구현합니다. 원문에서는 Modbus TCP를 TCP/IP 기반 산업용 통신 프로토콜로 설명하며, Ethernet 환경에서 Modbus 데이터를 TCP 패킷 안에 캡슐화해 전송하는 구조로 소개합니다.
시스템 구조는 상용 장치에서 흔히 쓰이는 형태입니다. PC, HMI, PLC, 게이트웨이, 시운전 도구가 Modbus TCP Client 역할을 하고, AI8051U + W5500 보드는 Modbus TCP Slave 또는 Server 역할을 합니다. Client는 holding register 읽기나 단일 register 쓰기 같은 요청을 보내고, 임베디드 장치는 Modbus TCP 프레임을 파싱해 내부 데이터 또는 I/O 상태에 매핑한 뒤 같은 TCP 연결로 응답을 반환합니다.
공개 검색 요약에서는 구현이 function code 0x03과 0x06에 초점을 둔다고 설명합니다. 또한 Slave 측 데이터 처리, register read/write, response frame 생성, W5500을 통한 네트워크 통신, master의 read/write 요청 처리, LED 장치 상태 제어가 포함된다고 명시합니다. 다만 전체 소스 섹션은 공개 페이지에서 확인할 수 없으므로, 프로젝트 코드를 줄 단위로 직접 인용할 수는 없습니다.
WIZnet이 들어가는 위치
이 프로젝트에서 사용되는 WIZnet 제품은 W5500입니다. W5500은 AI8051U Modbus TCP Slave의 유선 Ethernet 및 TCP 전송 엔진입니다. AI8051U는 Modbus 애플리케이션 로직을 담당합니다. 여기에는 register mapping, function code parsing, response construction, LED 또는 device state update, firmware-level error handling이 포함됩니다. W5500은 Ethernet MAC/PHY 동작, TCP socket state, packet buffering, SPI로 접근 가능한 socket register를 담당합니다.
W5500은 이 구조에 적합합니다. W5500은 하드웨어 TCP/IP 스택, 최대 80 MHz SPI mode 0/3 접근, 내장 10/100 Ethernet MAC/PHY, 8개 독립 소켓, 32 KB 내부 Tx/Rx 버퍼를 제공합니다. 또한 TCP, UDP, ICMP, IPv4, ARP, IGMP, PPPoE 같은 하드웨어 프로토콜을 지원합니다.
상용 Modbus TCP 장비에서는 이 역할 분리가 실용적입니다. AI8051U는 결정적인 장치 동작과 Modbus register 의미에 집중하고, W5500은 TCP 상태와 패킷 이동을 처리합니다. 이 구조는 MCU 내부에서 실행해야 하는 RAM 사용량과 타이밍 민감한 TCP/IP 코드 양을 줄여줍니다. 소형 산업용 컨트롤러, I/O 모듈, 센서 노드, retrofit gateway, service interface 같은 장치에 적합합니다.
구현 참고 사항
공개 원문은 W5500 기반 Modbus TCP Slave 사용을 확인할 수 있지만, 전체 소스 코드는 CSDN 구독 접근 뒤에 있습니다. 따라서 아래 구현은 원문 프로젝트에서 복사한 코드가 아닙니다.
WIZnet ioLibrary 기반 개념적 통합 예제
#include "wizchip_conf.h"
#include "socket.h"
#define MODBUS_SOCKET 0
#define MODBUS_PORT 502
static uint8_t tx_size[8] = {2,2,2,2,2,2,2,2};
static uint8_t rx_size[8] = {2,2,2,2,2,2,2,2};
void w5500_modbus_network_init(void)
{
reg_wizchip_cs_cbfunc(w5500_select, w5500_deselect);
reg_wizchip_spi_cbfunc(w5500_spi_read, w5500_spi_write);
wizchip_init(tx_size, rx_size);
wizchip_setnetinfo(&net_info);
}이 계층은 WIZnet ioLibrary가 플랫폼 독립 구조이기 때문에 필요합니다. AI8051U 펌웨어는 W5500 소켓 API를 사용하기 전에 W5500 chip select와 SPI read/write 함수를 제공해야 합니다. WIZnet ioLibrary는 W5500을 포함한 WIZnet 칩용 Internet Offload Library이며 Berkeley 스타일 socket API를 제공합니다.
void modbus_tcp_slave_task(void)
{
uint8_t status = getSn_SR(MODBUS_SOCKET);
switch (status) {
case SOCK_CLOSED:
socket(MODBUS_SOCKET, Sn_MR_TCP, MODBUS_PORT, 0);
break;
case SOCK_INIT:
listen(MODBUS_SOCKET);
break;
case SOCK_ESTABLISHED:
if (getSn_RX_RSR(MODBUS_SOCKET) > 0) {
int32_t len = recv(MODBUS_SOCKET, rx_buf, sizeof(rx_buf));
if (len > 0) {
int32_t rsp_len = modbus_build_response(rx_buf, len, tx_buf);
if (rsp_len > 0) {
send(MODBUS_SOCKET, tx_buf, rsp_len);
}
}
}
break;
case SOCK_CLOSE_WAIT:
disconnect(MODBUS_SOCKET);
close(MODBUS_SOCKET);
break;
}
}이 task는 예상되는 펌웨어 구조를 보여줍니다. W5500은 TCP socket state와 receive buffer를 유지하고, AI8051U는 Modbus TCP Application Data Unit을 파싱합니다. Modbus TCP 메시지는 MBAP header와 PDU로 구성됩니다. 원문에서는 MBAP field를 transaction identifier, protocol identifier, length, unit identifier로 설명하고, 그 뒤에 PDU function code와 data가 이어진다고 설명합니다.
Function code 0x03은 일반적으로 holding register를 읽고 register 값을 반환하는 데 사용됩니다. Function code 0x06은 단일 register를 쓰고 수락된 write request를 echo하는 데 사용됩니다. 공개 검색 요약에서도 원문 구현의 핵심 function code로 이 두 가지가 언급됩니다.
실무 팁 / 주의점
- Modbus를 테스트하기 전에 W5500 SPI 통신을 먼저 검증해야 합니다. Register 접근이 불안정하면 실제 문제는 TCP 아래 계층에 있어도 Modbus parser가 불안정한 것처럼 보일 수 있습니다.
- Deployment policy가 허용할 때만 port
502를 사용해야 합니다. Modbus TCP의 표준 포트는502이지만, 일부 테스트 환경에서는 권한 문제나 방화벽 제한을 피하기 위해 더 높은 configurable port를 사용합니다. - Response에서 MBAP transaction identifier를 그대로 유지해야 합니다. Client는 이 값을 사용해 request와 response를 매칭합니다.
- Modbus register map과 raw device variable을 분리해야 합니다. 상용 펌웨어는 address range, access permission, scaling, invalid-address behavior를 명확히 정의해야 합니다.
- Socket recovery를 명시적으로 처리해야 합니다. Cable removal, client crash, duplicate connection, half-open TCP state, switch reboot 이후 W5500 socket이 알려진 listen 상태로 돌아와야 합니다.
- 모든 request를 bound-check해야 합니다. Response를 만들기 전에 length, function code, start address, register count, output buffer size를 검증해야 합니다.
- 설치 진단 기능을 추가하는 것이 좋습니다. UART 또는 service interface를 통해 IP address, link status, socket state, last function code, exception code, request counter를 확인할 수 있어야 합니다.
FAQ
Q: AI8051U에서 Modbus TCP Slave를 구현할 때 왜 WIZnet W5500을 사용하나요?
A: W5500은 유선 Ethernet MAC/PHY, 하드웨어 TCP/IP 스택, TCP socket state machine, 8개 socket, 내부 Tx/Rx buffer를 제공합니다. AI8051U는 전체 TCP/IP 스택을 MCU 펌웨어에서 직접 실행하지 않고 Modbus register logic, function-code handling, device behavior에 집중할 수 있습니다.
Q: W5500은 AI8051U 플랫폼에 어떻게 연결하나요?
A: W5500은 SPI와 chip select, reset, interrupt, power, ground, Ethernet RJ45/magnetics 경로를 통해 AI8051U에 연결합니다. 펌웨어에서는 ioLibrary socket 함수를 사용하기 전에 W5500 SPI read/write와 chip-select callback을 등록해야 합니다.
Q: 이 Modbus TCP 프로젝트에서 W5500은 어떤 역할을 하나요?
A: W5500은 Modbus TCP Slave를 위한 TCP server transport를 제공합니다. Modbus Client는 W5500 socket에 연결해 request를 보내고 response를 수신합니다. AI8051U는 Modbus function code를 파싱하고 이를 register, LED, device state에 매핑합니다.
Q: 초보자도 이 상용 스타일 프로젝트를 따라할 수 있나요?
A: 임베디드 C, SPI, IPv4 addressing, TCP client/server 동작, 기본 Modbus register 개념을 이해하는 개발자에게 적합합니다. 상용 제품으로 확장하려면 exception response, register-map documentation, watchdog recovery, access control, production diagnostics가 추가로 필요합니다.
Q: W5500 방식은 LwIP 기반 Modbus TCP Slave와 어떻게 다른가요?
A: W5500을 사용하면 TCP/IP 처리, socket state, packet buffering이 Ethernet controller 내부에서 처리되므로 AI8051U는 주로 SPI와 Modbus application logic을 구동합니다. LwIP를 사용하면 MCU가 Ethernet driver integration, packet buffer, memory pool, protocol timer, TCP state handling을 더 많이 담당합니다. 이 방식은 유연하지만 소형 상용 컨트롤러에서는 펌웨어 복잡도가 증가합니다.
출처
Original article: CSDN, “[AI8051U入门第十二步]W5500-Modbus TCP从机.” 공개 페이지에서는 학습 목표와 Modbus TCP 소개를 확인할 수 있지만, 전체 구현은 article unlock 없이 공개적으로 확인할 수 없습니다.
https://blog.csdn.net/sinat_58149788/article/details/149831167
CSDN search summary: W5500 기반 Modbus TCP Slave 구현, function code 0x03 및 0x06, register read/write 처리, response-frame construction, LED/device-state control을 확인할 수 있습니다.
https://blog.csdn.net/sinat_58149788/article/details/149831167
WIZnet product reference: W5500 Ethernet Controller documentation.
https://wiznet.io/products/ethernet-chips/w5500
WIZnet driver reference: Wiznet/ioLibrary_Driver, MIT license.
https://github.com/Wiznet/ioLibrary_Driver
Modbus protocol reference: Modbus Organization, Modbus Application Protocol Specification V1.1b3.
https://modbus.org/modbus-specifications
태그
#W5500 #WIZnet #AI8051U #ModbusTCP #TCPServer #IndustrialEthernet #SPI #ioLibrary #EmbeddedC #Commercial #NetworkStack #HardwareWiring #Firmware #Performance
