How to Use socket.c APIs with WIZnet W5500 on MCU Platforms?
This education-focused project explains how WIZnet W5500 socket APIs work inside socket.c. The MCU uses SPI-accessible W5500 socket registers through functions
How to Use socket.c APIs with WIZnet W5500 on MCU Platforms?
Summary
This education-focused project explains how WIZnet W5500 socket APIs work inside socket.c. The MCU uses SPI-accessible W5500 socket registers through functions such as socket(), listen(), connect(), send(), recv(), sendto(), and recvfrom(). W5500’s role is to provide the wired Ethernet MAC/PHY, hardwired TCP/IP stack, socket state machine, and internal packet buffers, while the firmware learns network-stack behavior through a compact socket API.
What the Project Does
The source article is a function-level walkthrough of W5500 socket.c, not a single application demo. It explains internal variables such as sock_io_mode, sock_is_sending, and sock_remained_size, then walks through macros and APIs that validate socket numbers, check socket mode, open sockets, close sockets, listen as a TCP server, connect as a TCP client, transmit and receive TCP data, and handle UDP/IPRAW/MACRAW datagrams.
The network-stack path starts with socket(). The article shows that W5500 socket protocol selection is done through the low bits of Sn_MR: TCP uses Sn_MR_TCP, UDP uses Sn_MR_UDP, IPRAW uses Sn_MR_IPRAW, and MACRAW uses Sn_MR_MACRAW. The same function writes the source port, issues the OPEN command through Sn_CR, waits for the command register to clear, and then checks the socket status register.
For education, this is useful because it exposes the layer between high-level examples and W5500 registers. A TCP server is not just “call listen”; it requires TCP mode, SOCK_INIT, a LISTEN command, and a transition to SOCK_LISTEN. A UDP receiver is not just “read data”; it must read W5500’s packet header, extract sender IP, sender port, and payload length, then issue RECV after consuming buffer data.
Where WIZnet Fits
The exact WIZnet product is W5500. W5500 is the wired Ethernet controller and hardware TCP/IP engine between an external MCU and the LAN. WIZnet documents W5500 as a hardwired TCP/IP controller with SPI access up to 80 MHz, embedded 10/100 Ethernet MAC and PHY, TCP/UDP/IPv4 support, 8 independent sockets, and 32 KB internal memory for Tx/Rx buffers.
In this architecture, the MCU does not run the full TCP/IP stack in firmware. The MCU calls socket-layer functions, and those functions manipulate W5500 registers such as Sn_MR, Sn_PORT, Sn_DIPR, Sn_DPORT, Sn_CR, Sn_SR, Sn_IR, Sn_TX_FSR, and Sn_RX_RSR. W5500 handles socket state, packet buffering, and Ethernet-side TCP/IP behavior.
This makes the article a good bridge between register education and practical networking. Students can see how socket.c converts application intent into W5500 socket operations: TCP server listen, TCP client connect, TCP send/receive, UDP send/receive, timeout handling, nonblocking behavior, and remaining-packet tracking.
Implementation Notes
File: Ethernet/socket.c
What it configures: socket protocol mode, source port, OPEN command, and internal socket bookkeeping.
Why it matters: this is the entry point that turns a socket number into a TCP, UDP, IPRAW, or MACRAW channel.
close(sn);
setSn_MR(sn, (protocol | (flag & 0xF0)));
setSn_PORT(sn, port);
setSn_CR(sn, Sn_CR_OPEN);
while(getSn_CR(sn));
sock_is_sending &= ~(1 << sn);
sock_remained_size[sn] = 0;
sock_pack_info[sn] = PACK_COMPLETED;This code exists because W5500 sockets are hardware resources. The firmware must close any previous socket state, write the socket mode register, set the local port, issue the OPEN command, and reset software-side tracking before the socket can be used safely. The article explains the same sequence in its socket() function walkthrough.
File: Ethernet/socket.c
What it configures: TCP server listen flow.
Why it matters: TCP listening requires a valid TCP socket already in SOCK_INIT; otherwise the server cannot accept a connection.
CHECK_SOCKMODE(Sn_MR_TCP);
CHECK_SOCKINIT();
setSn_CR(sn, Sn_CR_LISTEN);
while(getSn_CR(sn));
while(getSn_SR(sn) != SOCK_LISTEN)
{
close(sn);
return SOCKERR_SOCKCLOSED;
}This code exists to enforce the correct TCP server state transition. The function checks that the socket is in TCP mode, checks that it is initialized, issues LISTEN, then verifies that the W5500 status register reaches SOCK_LISTEN.
File: Ethernet/socket.c
What it configures: UDP/IPRAW/MACRAW receive behavior.
Why it matters: datagram receive is different from TCP receive because the firmware must recover sender metadata and track remaining packet length.
pack_len = getSn_RX_RSR(sn);
if(getSn_SR(sn) == SOCK_CLOSED)
return SOCKERR_SOCKCLOSED;
wiz_recv_data(sn, head, 8);
setSn_CR(sn, Sn_CR_RECV);
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
*port = (head[4] << 8) + head[5];This code exists because UDP receive data includes a W5500-provided header before the payload. The firmware reads that header, extracts sender IP and port, calculates remaining payload length, then reads the payload and issues RECV to release the consumed data.
Practical Tips / Pitfalls
- Check the socket number before every operation. W5500 has 8 sockets, so invalid socket IDs should fail before touching registers.
- Do not call
listen()beforesocket()has opened a TCP socket. The code requires TCP mode andSOCK_INIT. - For TCP
send(), verify that the socket isSOCK_ESTABLISHEDorSOCK_CLOSE_WAIT, and respectSn_TX_FSRso unsent data is not overwritten. - For TCP
recv(), read only within the configured receive-buffer size and issueSn_CR_RECVafter copying data. - For UDP
recvfrom(), parse the header first; sender IP, sender port, and packet length are not optional details. - Clear interrupt flags intentionally.
close()clears socket interrupt bits withsetSn_IR(sn, 0xFF), which prevents stale events from affecting the next socket use.
FAQ
Q: Why use WIZnet W5500 for teaching socket APIs?
A: W5500 exposes a clear hardware-socket model. Students can connect API calls such as socket(), listen(), connect(), send(), and recvfrom() to hardware registers such as Sn_MR, Sn_CR, Sn_SR, Sn_IR, and buffer-size registers. The chip also provides hardwired TCP/IP, 8 sockets, and internal buffers, so students can study network behavior without first porting a full software TCP/IP stack.
Q: How does W5500 connect to the MCU platform?
A: W5500 connects to an external MCU through SPI. The MCU provides SPI read/write and chip-select control, while W5500 provides the Ethernet MAC/PHY, socket registers, and internal Tx/Rx buffers. A complete teaching board should also expose reset and interrupt pins so students can observe recovery and socket events.
Q: What role does W5500 play in this socket.c project?
A: W5500 is the hardware socket engine being controlled by socket.c. The C functions validate parameters, write W5500 registers, issue socket commands, check status, move data into or out of W5500 buffers, and report socket errors back to the application.
Q: Can beginners follow this education project?
A: Yes, if they already understand basic C, SPI, IPv4 addresses, ports, and the difference between TCP and UDP. It is lower-level than an HTTP or MQTT example, but it is a good way to learn why those examples work.
Q: How does W5500 compare with LwIP and ENC28J60 for education?
A: W5500 teaches hardware-offloaded socket behavior: the TCP/IP engine, sockets, and packet buffers are inside the Ethernet controller. LwIP teaches software-stack behavior; it is a small independent TCP/IP implementation designed to reduce RAM usage while still providing full TCP support on embedded systems. ENC28J60 is a 10Base-T Ethernet controller with SPI interface, so the MCU typically handles more of the TCP/IP stack than it would with W5500.
Source
Original article: CSDN, “W5500之‘socket.c’中的相关函数,” first published on 2025-08-12 and updated on 2025-08-13. The article is marked CC 4.0 BY-SA.
WIZnet product reference: W5500 documentation and ioLibrary Driver information.
Alternative references for comparison: lwIP overview and Microchip ENC28J60 product information.
Tags
#W5500 #WIZnet #SocketAPI #socketc #MCU #SPI #Education #NetworkStack #TCP #UDP #IPRAW #MACRAW #ioLibrary #LwIP #ENC28J60
MCU 플랫폼에서 WIZnet W5500의 socket.c API를 사용하는 방법은?
요약
이 교육용 프로젝트는 WIZnet W5500의 socket.c 내부 소켓 API가 어떻게 동작하는지 설명합니다. MCU는 socket(), listen(), connect(), send(), recv(), sendto(), recvfrom() 같은 함수를 통해 SPI로 접근 가능한 W5500 소켓 레지스터를 사용합니다. W5500은 유선 Ethernet MAC/PHY, 하드웨어 TCP/IP 스택, 소켓 상태 머신, 내부 패킷 버퍼를 제공하고, 펌웨어는 간결한 소켓 API를 통해 네트워크 스택 동작을 학습합니다.
프로젝트가 하는 일
원문은 단일 애플리케이션 데모가 아니라 W5500 socket.c의 함수 단위 해설입니다. sock_io_mode, sock_is_sending, sock_remained_size 같은 내부 변수부터 시작해, 소켓 번호 검증, 소켓 모드 확인, 소켓 열기, 소켓 닫기, TCP 서버 listen, TCP 클라이언트 connect, TCP 데이터 송수신, UDP/IPRAW/MACRAW 데이터그램 처리를 설명합니다.
네트워크 스택 흐름은 socket()에서 시작합니다. 원문은 W5500의 소켓 프로토콜 선택이 Sn_MR의 하위 비트로 수행된다고 설명합니다. TCP는 Sn_MR_TCP, UDP는 Sn_MR_UDP, IPRAW는 Sn_MR_IPRAW, MACRAW는 Sn_MR_MACRAW를 사용합니다. 같은 함수에서 source port를 기록하고, Sn_CR을 통해 OPEN 명령을 실행하며, command register가 clear될 때까지 기다린 뒤 socket status register를 확인합니다.
교육 관점에서 이 자료는 고수준 예제와 W5500 레지스터 사이의 중간 계층을 보여준다는 점에서 유용합니다. TCP 서버는 단순히 listen()을 호출하는 것이 아니라 TCP 모드, SOCK_INIT, LISTEN 명령, SOCK_LISTEN 상태 전이가 필요합니다. UDP 수신도 단순히 데이터를 읽는 것이 아니라 W5500의 packet header를 읽고, sender IP, sender port, payload length를 추출한 뒤, buffer 데이터를 소비하고 RECV를 실행해야 합니다.
WIZnet이 들어가는 위치
이 프로젝트에서 사용되는 WIZnet 제품은 W5500입니다. W5500은 외부 MCU와 LAN 사이에 위치하는 유선 이더넷 컨트롤러이자 하드웨어 TCP/IP 엔진입니다. WIZnet 문서 기준으로 W5500은 최대 80 MHz SPI 접근, 내장 10/100 Ethernet MAC 및 PHY, TCP/UDP/IPv4 지원, 8개 독립 소켓, 32 KB 내부 Tx/Rx 버퍼 메모리를 제공하는 하드웨어 TCP/IP 컨트롤러입니다.
이 구조에서 MCU는 전체 TCP/IP 스택을 펌웨어에서 직접 실행하지 않습니다. MCU는 소켓 계층 함수를 호출하고, 이 함수들은 Sn_MR, Sn_PORT, Sn_DIPR, Sn_DPORT, Sn_CR, Sn_SR, Sn_IR, Sn_TX_FSR, Sn_RX_RSR 같은 W5500 레지스터를 조작합니다. W5500은 소켓 상태, 패킷 버퍼링, Ethernet 측 TCP/IP 동작을 담당합니다.
따라서 이 자료는 레지스터 학습과 실제 네트워크 프로그래밍 사이를 연결하는 좋은 예제입니다. 학생들은 socket.c가 애플리케이션의 의도를 W5500 소켓 동작으로 바꾸는 과정을 볼 수 있습니다. 여기에는 TCP 서버 listen, TCP 클라이언트 connect, TCP send/receive, UDP send/receive, timeout 처리, nonblocking 동작, remaining-packet tracking이 포함됩니다.
구현 참고 사항
파일: Ethernet/socket.c
설정 내용: 소켓 프로토콜 모드, source port, OPEN 명령, 내부 소켓 상태 추적
중요한 이유: 이 함수는 소켓 번호를 TCP, UDP, IPRAW, MACRAW 채널로 전환하는 진입점입니다.
close(sn);
setSn_MR(sn, (protocol | (flag & 0xF0)));
setSn_PORT(sn, port);
setSn_CR(sn, Sn_CR_OPEN);
while(getSn_CR(sn));
sock_is_sending &= ~(1 << sn);
sock_remained_size[sn] = 0;
sock_pack_info[sn] = PACK_COMPLETED;이 코드는 W5500 소켓이 하드웨어 자원이기 때문에 필요합니다. 펌웨어는 이전 소켓 상태를 닫고, socket mode register를 쓰고, local port를 설정하고, OPEN 명령을 실행한 뒤, 소프트웨어 측 추적 상태를 초기화해야 소켓을 안전하게 사용할 수 있습니다. 원문도 socket() 함수 설명에서 같은 순서를 다룹니다.
파일: Ethernet/socket.c
설정 내용: TCP 서버 listen 흐름
중요한 이유: TCP listen은 이미 SOCK_INIT 상태에 있는 유효한 TCP 소켓이 있어야 가능합니다. 그렇지 않으면 서버는 연결을 받을 수 없습니다.
CHECK_SOCKMODE(Sn_MR_TCP);
CHECK_SOCKINIT();
setSn_CR(sn, Sn_CR_LISTEN);
while(getSn_CR(sn));
while(getSn_SR(sn) != SOCK_LISTEN)
{
close(sn);
return SOCKERR_SOCKCLOSED;
}이 코드는 올바른 TCP 서버 상태 전이를 강제하기 위해 존재합니다. 함수는 소켓이 TCP 모드인지 확인하고, 초기화 상태인지 확인한 뒤, LISTEN 명령을 실행합니다. 이후 W5500 상태 레지스터가 SOCK_LISTEN에 도달했는지 검증합니다.
파일: Ethernet/socket.c
설정 내용: UDP/IPRAW/MACRAW 수신 동작
중요한 이유: 데이터그램 수신은 TCP 수신과 다릅니다. 펌웨어는 sender metadata를 복구하고, 남은 packet length를 추적해야 합니다.
pack_len = getSn_RX_RSR(sn);
if(getSn_SR(sn) == SOCK_CLOSED)
return SOCKERR_SOCKCLOSED;
wiz_recv_data(sn, head, 8);
setSn_CR(sn, Sn_CR_RECV);
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
*port = (head[4] << 8) + head[5];이 코드는 UDP 수신 데이터에 payload 앞의 W5500-provided header가 포함되기 때문에 필요합니다. 펌웨어는 이 header를 읽고 sender IP와 port를 추출하며, 남은 payload length를 계산합니다. 이후 payload를 읽고 RECV 명령을 실행해 소비한 데이터를 해제합니다.
실무 팁 / 주의점
- 모든 동작 전에 소켓 번호를 확인해야 합니다. W5500은 8개 소켓을 제공하므로, 잘못된 socket ID는 레지스터 접근 전에 실패 처리해야 합니다.
- TCP 소켓이
socket()으로 열린 뒤SOCK_INIT상태가 되기 전에listen()을 호출하면 안 됩니다. - TCP
send()에서는 소켓이SOCK_ESTABLISHED또는SOCK_CLOSE_WAIT상태인지 확인하고,Sn_TX_FSR을 준수해야 아직 전송되지 않은 데이터를 덮어쓰지 않습니다. - TCP
recv()에서는 설정된 receive-buffer 크기 안에서만 읽고, 데이터를 복사한 뒤Sn_CR_RECV를 실행해야 합니다. - UDP
recvfrom()에서는 header를 먼저 파싱해야 합니다. sender IP, sender port, packet length는 생략 가능한 정보가 아닙니다. - Interrupt flag는 의도적으로 clear해야 합니다.
close()는setSn_IR(sn, 0xFF)로 socket interrupt bit를 clear해 다음 소켓 사용에 stale event가 영향을 주지 않도록 합니다.
FAQ
Q: 소켓 API 교육에 왜 WIZnet W5500을 사용하나요?
A: W5500은 hardware-socket model을 명확하게 보여줍니다. 학생들은 socket(), listen(), connect(), send(), recvfrom() 같은 API 호출이 Sn_MR, Sn_CR, Sn_SR, Sn_IR, buffer-size register 같은 하드웨어 레지스터와 어떻게 연결되는지 볼 수 있습니다. 또한 W5500은 하드웨어 TCP/IP, 8개 소켓, 내부 버퍼를 제공하므로 전체 소프트웨어 TCP/IP 스택을 먼저 포팅하지 않고도 네트워크 동작을 학습할 수 있습니다.
Q: W5500은 MCU 플랫폼에 어떻게 연결하나요?
A: W5500은 SPI를 통해 외부 MCU에 연결됩니다. MCU는 SPI read/write와 chip-select control을 제공하고, W5500은 Ethernet MAC/PHY, socket register, 내부 Tx/Rx buffer를 제공합니다. 완전한 교육용 보드라면 reset과 interrupt pin도 노출해 복구 동작과 socket event를 관찰할 수 있게 하는 것이 좋습니다.
Q: 이 socket.c 프로젝트에서 W5500은 어떤 역할을 하나요?
A: W5500은 socket.c가 제어하는 hardware socket engine입니다. C 함수들은 parameter를 검증하고, W5500 register를 쓰고, socket command를 실행하고, status를 확인하고, W5500 buffer로 데이터를 넣거나 꺼내며, socket error를 애플리케이션에 반환합니다.
Q: 초보자도 이 교육용 프로젝트를 따라갈 수 있나요?
A: basic C, SPI, IPv4 address, port, TCP와 UDP의 차이를 이해하고 있다면 따라갈 수 있습니다. HTTP나 MQTT 예제보다 낮은 계층을 다루지만, 그런 예제가 왜 동작하는지 배우기 좋은 자료입니다.
Q: W5500은 교육 관점에서 LwIP 및 ENC28J60과 어떻게 다른가요?
A: W5500은 hardware-offloaded socket behavior를 가르칩니다. TCP/IP engine, socket, packet buffer가 Ethernet controller 내부에 있습니다. LwIP는 software-stack behavior를 가르치며, 임베디드 시스템에서 RAM 사용량을 줄이면서 full TCP support를 제공하도록 설계된 작은 독립 TCP/IP 구현입니다. ENC28J60은 SPI interface를 가진 10Base-T Ethernet controller이므로, MCU가 W5500을 사용할 때보다 TCP/IP stack을 더 많이 담당하는 구조가 일반적입니다.
출처
Original article: CSDN, “W5500之‘socket.c’中的相关函数,” 2025-08-12 게시, 2025-08-13 업데이트, CC 4.0 BY-SA로 표시됨.
https://blog.csdn.net/weixin_42550185/article/details/150273475?spm=1001.2014.3001.5502
WIZnet product reference: W5500 documentation and ioLibrary Driver information.
https://docs.wiznet.io/Product/Chip/Ethernet/W5500
Alternative references for comparison: lwIP overview and Microchip ENC28J60 product information.
https://www.nongnu.org/lwip/2_1_x/index.html
태그
#W5500 #WIZnet #SocketAPI #socketc #MCU #SPI #Education #NetworkStack #TCP #UDP #IPRAW #MACRAW #ioLibrary #LwIP #ENC28J60
