Skip to content

How to Build an Interrupt-Driven W5500 UDP Server on STM32F4 with FreeRTOS and ioLibrary

An STM32F407 and WIZnet W5500 UDP echo server on FreeRTOS, using the ioLibrary hardware sockets with interrupt-driven receive over SPI.

Benjamin

Published June 17, 2026

Original author: arashamfOriginal source (new tab)

How to Build an Interrupt-Driven W5500 UDP Server on STM32F4 with FreeRTOS and ioLibrary

Components

Hardware components

WIZnet parts

Project description

๐Ÿ“Œ Overview

This project is a compact, code-complete reference for running a WIZnet W5500 as a UDP server on an STM32F407 under FreeRTOS. The STM32 talks to the W5500 over SPI, the W5500 handles the TCP/IP stack in hardware, and a FreeRTOS task waits on a hardware receive interrupt. When a UDP datagram arrives, the firmware reads it and replies "answer_OK". A second task blinks status LEDs. It is a clean starting point for anyone wiring the W5500 ioLibrary into an RTOS application rather than a finished product.

STM32F407 and WIZnet W5500 UDP server: PC client over Ethernet to the W5500 hardware sockets and over SPI to the STM32F407 running FreeRTOS Generated technical diagram: PC to Ethernet to W5500 hardware sockets to SPI to STM32F407.

System Configuration

The firmware targets an STM32F407 (STM32CubeMX project, 168 MHz clock) and a WIZnet W5500 Ethernet controller on SPI1. SPI1 runs as master in mode 0 (CPOL low, CPHA first edge) with software chip select and a /4 prescaler. The network settings are static (IP, MAC, gateway, mask), the UDP service port is 1111, and a single hardware socket is used in non-blocking mode. The build is Makefile based and splits the standard library, the W5500 library, and FreeRTOS into separate include files. Two Python helpers in scripts/udp act as test peers.

The networking code uses the WIZnet ioLibrary_Driver; FreeRTOS and the ST STM32F4 HAL are bundled as middleware and drivers. The W5500 parts are listed in the Hardware Components panel.

System Architecture and Data Flow

The data path is short and deterministic. A PC sends a UDP datagram to the board's static IP on port 1111. The packet reaches the W5500 over Ethernet, where the hardware TCP/IP stack stores it in the socket receive buffer and raises a receive interrupt. The STM32F407 reads the datagram over SPI with recvfrom, then answers with sendto("answer_OK"). Because the W5500 owns the protocol stack, the STM32 only moves bytes over SPI and runs application logic.

Data flow: PC UDP client over Ethernet to the WIZnet W5500 hardware socket, then SPI1 to the STM32F407 plus FreeRTOS which echoes a reply Generated technical diagram: the UDP echo path from PC to W5500 to STM32F407.

Software Stack on STM32F407

The firmware is layered cleanly. The application has two FreeRTOS tasks: udp_task for the echo service and led_task for a status LED. FreeRTOS provides the scheduler and non-blocking timing. The WIZnet ioLibrary_Driver exposes the socket API (socket, sendto, recvfrom, ctlsocket, getSn_SR). A thin W5500 SPI driver binds the chip select, single-byte, and burst callbacks to STM32 SPI through reg_wizchip_cs_cbfunc, reg_wizchip_spi_cbfunc, and reg_wizchip_spiburst_cbfunc. At the bottom is the W5500 itself, with eight hardware sockets, MAC and PHY, and a receive interrupt line.

Software stack: application tasks over FreeRTOS over the WIZnet ioLibrary over the W5500 SPI driver over the W5500 hardware TCP/IP chip Generated technical diagram: the five layers from application down to the W5500.

โš™๏ธ Role of the WIZnet Chip

The W5500 is the reason the firmware stays small. It is a hardwired TCP/IP controller, so the protocol stack runs inside the chip and the STM32F407 only drives it over SPI. The MCU never spends cycles or RAM on a software stack such as lwIP or Mongoose, which leaves more room for application tasks and keeps timing predictable. That hardware offload is what makes this a TCP/IP offload (TOE) design. The project also uses the W5500 the way it is meant to be used in an RTOS: the chip raises a receive interrupt, so the udp_task only does work when a datagram actually arrives instead of polling, which is friendlier to the FreeRTOS scheduler.

Interrupt-Driven Receive Loop

The receive path is interrupt gated. The socket interrupt mask is set with setSIMR and setSn_IMR, and INT_RECV_ON arms the receive interrupt. When the W5500 receives a datagram it sets the socket interrupt, the udp_task reads it with recvfrom, sends the "answer_OK" reply, and re-arms the interrupt. The socket is opened in non-blocking mode, so the task yields with vTaskDelay between events rather than spinning.

Interrupt receive loop: W5500 receive interrupt, socket interrupt flag, task wake, recvfrom, sendto answer_OK, re-arm interrupt Generated technical diagram: the non-blocking, interrupt-gated UDP echo handled inside a FreeRTOS task.

Where It Fits: Value and Limits

This is a good reference for the first milestone of many STM32 Ethernet projects: get the W5500 linked, open a socket, and exchange packets reliably under an RTOS. The interrupt-driven pattern and the clean SPI callback wiring are reusable in larger designs that add DHCP, TCP services, or MQTT later.

It is fair to note the limits. The repository has no README or project-level license, the address is static only (no DHCP), and the UDP echo is a demonstration rather than a full application; the TCP branch is guarded by a build flag and is not the default. A socket buffer sizing call is left commented out, so default sizes apply. Verify your own pin map, SPI speed, and network settings before reusing it.

Related WIZnet Maker Projects

This project sits among several STM32 plus W5500 examples on the Maker site. Three are close enough to compare directly.

STM32 W5500 TCP Server with FreeRTOS (Non-Blocking Multi-Tasking Setup) (Grade A) is the closest sibling: a non-blocking W5500 server on STM32 under FreeRTOS using the ioLibrary socket API. Both projects share the STM32 + W5500 + FreeRTOS + ioLibrary combination and a non-blocking socket design. The transport and event trigger differ: that project uses TCP and a polled accept() loop to handle connection requests; this one uses UDP (connectionless, no handshake overhead) and arms the W5500 receive interrupt so the udp_task wakes only when a datagram arrives. The interrupt-driven path avoids polling the SPI bus between packets and is friendlier to the FreeRTOS scheduler.

STM32F446_W5500__FREERTOS (Grade A) runs the same STM32F4 + W5500 + FreeRTOS + ioLibrary combination on an F446 instead of an F407, and adds DHCP for dynamic address assignment. Both projects are useful starting points for the ioLibrary-on-RTOS integration; the side-by-side shows the same pattern working across STM32F4 variants. The concrete differences are the MCU part (F446 vs F407), the address mode (DHCP vs static-only here), and the transport (TCP there; UDP with interrupt here).

How to Implement Mongoose Networking Library on STM32F4 using W5500 (Grade A) layers the Mongoose software networking library over the W5500 on an STM32F4, adding HTTP, WebSocket, and MQTT support above the hardware socket level. Both projects use STM32F4 + W5500 for embedded Ethernet. The design philosophy differs: Mongoose trades RAM and code size for protocol richness; this project drives the W5500 ioLibrary hardware sockets directly, keeping the firmware small and timing predictable. Comparing the two shows the concrete trade-off between a feature-rich software stack and a lean TOE design.

The shared thread is the WIZnet W5500 as a hardwired TCP/IP controller for STM32F4. This project is the minimal, interrupt-driven UDP reference of the group - the one that shows setSIMR / setSn_IMR / INT_RECV_ON wired into a FreeRTOS task with the fewest moving parts.

โ“ FAQ

Q. What does this project do? It runs a WIZnet W5500 as a UDP echo server on an STM32F407 under FreeRTOS. When a UDP datagram arrives on port 1111, the firmware reads it and replies "answer_OK".

Q. What is the role of the WIZnet chip? The W5500 is a hardwired TCP/IP controller. It runs the network stack in hardware and the STM32 only drives it over SPI, so the MCU stays free for application tasks (a TCP/IP offload design).

Q. How is the receive handled? It is interrupt driven. The W5500 raises a socket receive interrupt, a FreeRTOS task wakes, reads the datagram with recvfrom, replies with sendto, and re-arms the interrupt, so there is no busy polling.

Q. What is the hardest part to replicate? Getting the SPI callback wiring and the socket interrupt mask right. The W5500 chip-select, byte, and burst callbacks must match your SPI setup, and the static IP must suit your network.

Q. How does it compare to a software stack like Mongoose or lwIP? Here the W5500 owns the TCP/IP stack, so RAM and CPU use stay low and timing is predictable. A software stack adds features but costs MCU resources; this project favors the lean hardware-socket path.


ํ•œ๊ตญ์–ด (Korean)

๊ฐœ์š”

์ด ํ”„๋กœ์ ํŠธ๋Š” STM32F407์—์„œ FreeRTOS ์œ„์— WIZnet W5500์„ UDP ์„œ๋ฒ„๋กœ ๊ตฌ๋™ํ•˜๋Š”, ์ฝ”๋“œ๊นŒ์ง€ ์™„์„ฑ๋œ ๊ฐ„๊ฒฐํ•œ ์ฐธ๊ณ  ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค. STM32๋Š” SPI๋กœ W5500๊ณผ ํ†ต์‹ ํ•˜๊ณ , W5500์ด TCP/IP ์Šคํƒ์„ ํ•˜๋“œ์›จ์–ด๋กœ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, FreeRTOS ํƒœ์Šคํฌ๊ฐ€ ํ•˜๋“œ์›จ์–ด ์ˆ˜์‹  ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. UDP ๋ฐ์ดํ„ฐ๊ทธ๋žจ์ด ๋„์ฐฉํ•˜๋ฉด ํŽŒ์›จ์–ด๊ฐ€ ์ด๋ฅผ ์ฝ๊ณ  "answer_OK"๋กœ ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ํƒœ์Šคํฌ๋Š” ์ƒํƒœ LED๋ฅผ ๊นœ๋นก์ž…๋‹ˆ๋‹ค. ์™„์„ฑํ’ˆ์ด๋ผ๊ธฐ๋ณด๋‹ค, W5500 ioLibrary๋ฅผ RTOS ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋ถ™์ด๋Š” ๊น”๋”ํ•œ ์ถœ๋ฐœ์ ์ž…๋‹ˆ๋‹ค.

STM32F407๊ณผ WIZnet W5500 UDP ์„œ๋ฒ„: PC ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ด๋”๋„ท์œผ๋กœ W5500 ํ•˜๋“œ์›จ์–ด ์†Œ์ผ“์—, SPI๋กœ FreeRTOS ๊ตฌ๋™ STM32F407์— ์—ฐ๊ฒฐ ์ƒ์„ฑ ๋‹ค์ด์–ด๊ทธ๋žจ: PC โ†’ ์ด๋”๋„ท โ†’ W5500 ํ•˜๋“œ์›จ์–ด ์†Œ์ผ“ โ†’ SPI โ†’ STM32F407.

์‹œ์Šคํ…œ ๊ตฌ์„ฑ

ํŽŒ์›จ์–ด๋Š” STM32F407(STM32CubeMX ํ”„๋กœ์ ํŠธ, 168MHz)๊ณผ SPI1์— ์—ฐ๊ฒฐ๋œ WIZnet W5500์„ ๋Œ€์ƒ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. SPI1์€ ๋งˆ์Šคํ„ฐ, ๋ชจ๋“œ 0(CPOL low, CPHA 1edge), ์†Œํ”„ํŠธ์›จ์–ด CS, /4 ๋ถ„์ฃผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ ์„ค์ •์€ ์ •์ (IPยทMACยท๊ฒŒ์ดํŠธ์›จ์ดยท๋งˆ์Šคํฌ), UDP ์„œ๋น„์Šค ํฌํŠธ๋Š” 1111, ๋‹จ์ผ ํ•˜๋“œ์›จ์–ด ์†Œ์ผ“์„ ๋…ผ๋ธ”๋กœํ‚น์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋นŒ๋“œ๋Š” Makefile ๊ธฐ๋ฐ˜์œผ๋กœ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌยทW5500 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌยทFreeRTOS๋ฅผ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค. scripts/udp์˜ ํŒŒ์ด์ฌ ๋‘ ๊ฐœ๊ฐ€ ํ…Œ์ŠคํŠธ ํ”ผ์–ด ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํ‚น ์ฝ”๋“œ๋Š” WIZnet ioLibrary_Driver๋ฅผ ์“ฐ๊ณ , FreeRTOS์™€ ST STM32F4 HAL์ด ํ•จ๊ป˜ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. W5500 ๋ถ€ํ’ˆ์€ Hardware Components ํŒจ๋„์— ์ •๋ฆฌ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์‹œ์Šคํ…œ ๊ตฌ์กฐ์™€ ๋ฐ์ดํ„ฐ ํ๋ฆ„

๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ๋Š” ์งง๊ณ  ๊ฒฐ์ •์ ์ž…๋‹ˆ๋‹ค. PC๊ฐ€ ๋ณด๋“œ์˜ ์ •์  IP, ํฌํŠธ 1111๋กœ UDP ๋ฐ์ดํ„ฐ๊ทธ๋žจ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ํŒจํ‚ท์€ ์ด๋”๋„ท์œผ๋กœ W5500์— ๋„๋‹ฌํ•˜๊ณ , ํ•˜๋“œ์›จ์–ด TCP/IP ์Šคํƒ์ด ์†Œ์ผ“ ์ˆ˜์‹  ๋ฒ„ํผ์— ์ €์žฅํ•œ ๋’ค ์ˆ˜์‹  ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์˜ฌ๋ฆฝ๋‹ˆ๋‹ค. STM32F407์€ SPI๋กœ recvfrom์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๊ทธ๋žจ์„ ์ฝ๊ณ  sendto("answer_OK")๋กœ ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค. W5500์ด ํ”„๋กœํ† ์ฝœ ์Šคํƒ์„ ๋‹ด๋‹นํ•˜๋ฏ€๋กœ STM32๋Š” SPI๋กœ ๋ฐ”์ดํŠธ๋งŒ ์˜ฎ๊ธฐ๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ์ง๋งŒ ๋Œ๋ฆฝ๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ํ๋ฆ„: PC UDP ํด๋ผ์ด์–ธํŠธ โ†’ ์ด๋”๋„ท โ†’ WIZnet W5500 ํ•˜๋“œ์›จ์–ด ์†Œ์ผ“ โ†’ SPI1 โ†’ STM32F407+FreeRTOS๊ฐ€ ์‘๋‹ต ์ƒ์„ฑ ๋‹ค์ด์–ด๊ทธ๋žจ: PC์—์„œ W5500์„ ๊ฑฐ์ณ STM32F407๋กœ ๊ฐ€๋Š” UDP ์—์ฝ” ๊ฒฝ๋กœ.

STM32F407์˜ ์†Œํ”„ํŠธ์›จ์–ด ์Šคํƒ

ํŽŒ์›จ์–ด๋Š” ๊ณ„์ธต์ด ๋ช…ํ™•ํ•ฉ๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—๋Š” ๋‘ FreeRTOS ํƒœ์Šคํฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค: ์—์ฝ” ์„œ๋น„์Šค์šฉ udp_task, ์ƒํƒœ LED์šฉ led_task. FreeRTOS๊ฐ€ ์Šค์ผ€์ค„๋Ÿฌ์™€ ๋…ผ๋ธ”๋กœํ‚น ํƒ€์ด๋ฐ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. WIZnet ioLibrary_Driver๊ฐ€ ์†Œ์ผ“ API(socket, sendto, recvfrom, ctlsocket, getSn_SR)๋ฅผ ์ œ๊ณตํ•˜๊ณ , ์–‡์€ W5500 SPI ๋“œ๋ผ์ด๋ฒ„๊ฐ€ CSยท๋‹จ์ผ๋ฐ”์ดํŠธยท๋ฒ„์ŠคํŠธ ์ฝœ๋ฐฑ์„ reg_wizchip_*_cbfunc๋กœ STM32 SPI์— ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ๋งจ ์•„๋ž˜๋Š” 8๊ฐœ ํ•˜๋“œ์›จ์–ด ์†Œ์ผ“ยทMACยทPHYยท์ˆ˜์‹  ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๊ฐ–์ถ˜ W5500์ž…๋‹ˆ๋‹ค.

์†Œํ”„ํŠธ์›จ์–ด ์Šคํƒ: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํƒœ์Šคํฌ โ†’ FreeRTOS โ†’ WIZnet ioLibrary โ†’ W5500 SPI ๋“œ๋ผ์ด๋ฒ„ โ†’ W5500 ํ•˜๋“œ์›จ์–ด TCP/IP ์นฉ ์ƒ์„ฑ ๋‹ค์ด์–ด๊ทธ๋žจ: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋ถ€ํ„ฐ W5500๊นŒ์ง€ ๋‹ค์„ฏ ๊ณ„์ธต.

WIZnet ์นฉ์˜ ์—ญํ• 

W5500 ๋•๋ถ„์— ํŽŒ์›จ์–ด๊ฐ€ ์ž‘๊ฒŒ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ํ•˜๋“œ์™€์ด์–ด๋“œ TCP/IP ์ปจํŠธ๋กค๋Ÿฌ๋ผ์„œ ํ”„๋กœํ† ์ฝœ ์Šคํƒ์ด ์นฉ ๋‚ด๋ถ€์—์„œ ๋Œ๊ณ  STM32F407์€ SPI๋กœ ๊ตฌ๋™๋งŒ ํ•ฉ๋‹ˆ๋‹ค. MCU๊ฐ€ lwIP๋‚˜ Mongoose ๊ฐ™์€ ์†Œํ”„ํŠธ์›จ์–ด ์Šคํƒ์— ์‚ฌ์ดํดยทRAM์„ ์“ฐ์ง€ ์•Š์œผ๋‹ˆ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํƒœ์Šคํฌ์— ์—ฌ์œ ๊ฐ€ ์ƒ๊ธฐ๊ณ  ํƒ€์ด๋ฐ์ด ์˜ˆ์ธก ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด ํ•˜๋“œ์›จ์–ด ์˜คํ”„๋กœ๋“œ๊ฐ€ ์ด ์„ค๊ณ„๋ฅผ TOE(TCP/IP ์˜คํ”„๋กœ๋“œ)๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋˜ํ•œ RTOS์— ๋งž๊ฒŒ ์นฉ์ด ์ˆ˜์‹  ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์˜ฌ๋ ค, udp_task๋Š” ํด๋ง ๋Œ€์‹  ์‹ค์ œ ๋ฐ์ดํ„ฐ๊ทธ๋žจ์ด ์˜ฌ ๋•Œ๋งŒ ๋™์ž‘ํ•˜๋ฏ€๋กœ FreeRTOS ์Šค์ผ€์ค„๋Ÿฌ์— ์นœํ™”์ ์ž…๋‹ˆ๋‹ค.

์ธํ„ฐ๋ŸฝํŠธ ๊ธฐ๋ฐ˜ ์ˆ˜์‹  ๋ฃจํ”„

์ˆ˜์‹  ๊ฒฝ๋กœ๋Š” ์ธํ„ฐ๋ŸฝํŠธ๋กœ ๊ฒŒ์ดํŒ…๋ฉ๋‹ˆ๋‹ค. setSIMR๊ณผ setSn_IMR๋กœ ์†Œ์ผ“ ์ธํ„ฐ๋ŸฝํŠธ ๋งˆ์Šคํฌ๋ฅผ ์„ค์ •ํ•˜๊ณ  INT_RECV_ON์œผ๋กœ ์ˆ˜์‹  ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์ผญ๋‹ˆ๋‹ค. W5500์ด ๋ฐ์ดํ„ฐ๊ทธ๋žจ์„ ๋ฐ›์œผ๋ฉด ์†Œ์ผ“ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์˜ฌ๋ฆฌ๊ณ , udp_task๊ฐ€ recvfrom์œผ๋กœ ์ฝ์–ด "answer_OK"๋ฅผ ๋ณด๋‚ธ ๋’ค ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋‹ค์‹œ ์ผญ๋‹ˆ๋‹ค. ์†Œ์ผ“์€ ๋…ผ๋ธ”๋กœํ‚น์œผ๋กœ ์—ด๋ ค ์žˆ์–ด, ํƒœ์Šคํฌ๋Š” ์ด๋ฒคํŠธ ์‚ฌ์ด์— vTaskDelay๋กœ ์–‘๋ณดํ•ฉ๋‹ˆ๋‹ค.

์ธํ„ฐ๋ŸฝํŠธ ์ˆ˜์‹  ๋ฃจํ”„: W5500 ์ˆ˜์‹  ์ธํ„ฐ๋ŸฝํŠธ โ†’ ์†Œ์ผ“ ์ธํ„ฐ๋ŸฝํŠธ ํ”Œ๋ž˜๊ทธ โ†’ ํƒœ์Šคํฌ ๊นจ์–ด๋‚จ โ†’ recvfrom โ†’ sendto answer_OK โ†’ ์ธํ„ฐ๋ŸฝํŠธ ์žฌ๋ฌด์žฅ ์ƒ์„ฑ ๋‹ค์ด์–ด๊ทธ๋žจ: FreeRTOS ํƒœ์Šคํฌ ์•ˆ์—์„œ ์ฒ˜๋ฆฌ๋˜๋Š” ๋…ผ๋ธ”๋กœํ‚นยท์ธํ„ฐ๋ŸฝํŠธ ๊ธฐ๋ฐ˜ UDP ์—์ฝ”.

ํ™œ์šฉ ๊ฐ€์น˜์™€ ํ•œ๊ณ„

๋งŽ์€ STM32 ์ด๋”๋„ท ํ”„๋กœ์ ํŠธ์˜ ์ฒซ ๋งˆ์ผ์Šคํ†ค, ์ฆ‰ W5500 ๋งํฌ๋ฅผ ์˜ฌ๋ฆฌ๊ณ  ์†Œ์ผ“์„ ์—ด์–ด RTOS์—์„œ ์•ˆ์ •์ ์œผ๋กœ ํŒจํ‚ท์„ ์ฃผ๊ณ ๋ฐ›๋Š” ๋‹จ๊ณ„์— ์ข‹์€ ์ฐธ๊ณ ์ž…๋‹ˆ๋‹ค. ์ธํ„ฐ๋ŸฝํŠธ ๊ธฐ๋ฐ˜ ํŒจํ„ด๊ณผ ๊น”๋”ํ•œ SPI ์ฝœ๋ฐฑ ๋ฐฐ์„ ์€ ์ดํ›„ DHCPยทTCP ์„œ๋น„์ŠคยทMQTT๋ฅผ ๋”ํ•˜๋Š” ๋” ํฐ ์„ค๊ณ„์—์„œ๋„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ ํ•œ๊ณ„๋„ ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์ €์žฅ์†Œ์— README์™€ ํ”„๋กœ์ ํŠธ ๋ผ์ด์„ ์Šค๊ฐ€ ์—†๊ณ , ์ฃผ์†Œ๋Š” ์ •์ (DHCP ์—†์Œ)์ด๋ฉฐ, UDP ์—์ฝ”๋Š” ์™„์„ฑ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์•„๋‹ˆ๋ผ ๋ฐ๋ชจ์ž…๋‹ˆ๋‹ค. TCP ๋ถ„๊ธฐ๋Š” ๋นŒ๋“œ ํ”Œ๋ž˜๊ทธ๋กœ ๊ฐ€๋“œ๋˜์–ด ๊ธฐ๋ณธ๊ฐ’์ด ์•„๋‹ˆ๊ณ , ์†Œ์ผ“ ๋ฒ„ํผ ํฌ๊ธฐ ์„ค์ • ํ˜ธ์ถœ์€ ์ฃผ์„ ์ฒ˜๋ฆฌ๋˜์–ด ๊ธฐ๋ณธ ํฌ๊ธฐ๊ฐ€ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ์žฌ์‚ฌ์šฉ ์ „์— ํ•€๋งตยทSPI ์†๋„ยท๋„คํŠธ์›Œํฌ ์„ค์ •์„ ํ™•์ธํ•˜์„ธ์š”.

๊ด€๋ จ WIZnet ๋ฉ”์ด์ปค ํ”„๋กœ์ ํŠธ

๋ฉ”์ด์ปค ์‚ฌ์ดํŠธ์— ์žˆ๋Š” ์—ฌ๋Ÿฌ STM32+W5500 ์˜ˆ์ œ ์ค‘ ์ง์ ‘ ๋น„๊ตํ•˜๊ธฐ ์ข‹์€ ์„ธ ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.

STM32 W5500 TCP Server with FreeRTOS (๋…ผ๋ธ”๋กœํ‚น ๋ฉ€ํ‹ฐํƒœ์Šคํ‚น) (Grade A) - ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ํ˜•์ œ๋กœ, STM32 + W5500 + FreeRTOS + ioLibrary ์กฐํ•ฉ๊ณผ ๋…ผ๋ธ”๋กœํ‚น ์†Œ์ผ“ ์„ค๊ณ„๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. ์ „์†ก ๋ฐฉ์‹๊ณผ ์ด๋ฒคํŠธ ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๊ทธ ํ”„๋กœ์ ํŠธ๋Š” TCP๋ฅผ ์“ฐ๊ณ  ํด๋งํ˜• accept() ๋ฃจํ”„๋กœ ์—ฐ๊ฒฐ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ๋Š” UDP(์—ฐ๊ฒฐ ์—†์Œ, ํ•ธ๋“œ์…ฐ์ดํฌ ์˜ค๋ฒ„ํ—ค๋“œ ์—†์Œ)๋ฅผ ์“ฐ๊ณ  W5500 ์ˆ˜์‹  ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์„ค์ •ํ•ด ๋ฐ์ดํ„ฐ๊ทธ๋žจ์ด ์‹ค์ œ๋กœ ๋„์ฐฉํ•  ๋•Œ๋งŒ udp_task๊ฐ€ ๊นจ์–ด๋‚ฉ๋‹ˆ๋‹ค. ์ธํ„ฐ๋ŸฝํŠธ ๋ฐฉ์‹์€ ํŒจํ‚ท ์‚ฌ์ด์— SPI ๋ฒ„์Šค๋ฅผ ํด๋งํ•˜์ง€ ์•Š์•„ FreeRTOS ์Šค์ผ€์ค„๋Ÿฌ์— ๋” ์นœํ™”์ ์ž…๋‹ˆ๋‹ค.

STM32F446_W5500__FREERTOS (Grade A) - ๋™์ผํ•œ STM32F4 + W5500 + FreeRTOS + ioLibrary ์กฐํ•ฉ์„ F407 ๋Œ€์‹  F446์—์„œ ๊ตฌ๋™ํ•˜๋ฉฐ DHCP๋กœ ๋™์  ์ฃผ์†Œ ํ• ๋‹น์„ ๋”ํ•ฉ๋‹ˆ๋‹ค. ๋‘ ํ”„๋กœ์ ํŠธ๋Š” ioLibrary+RTOS ํ†ตํ•ฉ์˜ ์ข‹์€ ์ถœ๋ฐœ์ ์œผ๋กœ, ๋‚˜๋ž€ํžˆ ๋ณด๋ฉด ๊ฐ™์€ ํŒจํ„ด์ด STM32F4 ๊ณ„์—ด ์ „๋ฐ˜์—์„œ ๋™์ž‘ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ์ฒด์ ์ธ ์ฐจ์ด: MCU ๋ถ€ํ’ˆ(F446 vs F407), ์ฃผ์†Œ ๋ฐฉ์‹(DHCP vs ์ด ํ”„๋กœ์ ํŠธ์˜ ์ •์ ), ์ „์†ก ๋ฐฉ์‹(TCP vs ์—ฌ๊ธฐ์„œ ์ธํ„ฐ๋ŸฝํŠธ ๊ธฐ๋ฐ˜ UDP).

How to Implement Mongoose Networking Library on STM32F4 using W5500 (Grade A) - STM32F4 + W5500 ์œ„์— Mongoose ์†Œํ”„ํŠธ์›จ์–ด ๋„คํŠธ์›Œํ‚น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์˜ฌ๋ ค HTTPยทWebSocketยทMQTT ์ง€์›์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๋‘ ํ”„๋กœ์ ํŠธ ๋ชจ๋‘ STM32F4 + W5500์œผ๋กœ ์ž„๋ฒ ๋””๋“œ ์ด๋”๋„ท์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์„ค๊ณ„ ์ฒ ํ•™์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค. Mongoose๋Š” RAMยท์ฝ”๋“œ ํฌ๊ธฐ๋ฅผ ํ”„๋กœํ† ์ฝœ ํ’๋ถ€ํ•จ๊ณผ ๋งž๋ฐ”๊พธ๊ณ , ์ด ํ”„๋กœ์ ํŠธ๋Š” W5500 ioLibrary ํ•˜๋“œ์›จ์–ด ์†Œ์ผ“์„ ์ง์ ‘ ๊ตฌ๋™ํ•ด ํŽŒ์›จ์–ด๋ฅผ ์ž‘๊ณ  ํƒ€์ด๋ฐ์„ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ฒŒ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋‘˜์„ ๋น„๊ตํ•˜๋ฉด ๊ธฐ๋Šฅ ํ’๋ถ€ํ•œ ์†Œํ”„ํŠธ์›จ์–ด ์Šคํƒ๊ณผ ๊ฐ€๋ฒผ์šด TOE ์„ค๊ณ„์˜ ์ ˆ์ถฉ์ด ๋ช…ํ™•ํžˆ ๋ณด์ž…๋‹ˆ๋‹ค.

๊ณตํ†ต์ ์€ STM32F4์šฉ ํ•˜๋“œ์›จ์–ด TCP/IP ์ปจํŠธ๋กค๋Ÿฌ๋กœ์„œ์˜ WIZnet W5500์ž…๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ๋Š” ๊ทธ์ค‘ ๊ฐ€์žฅ ๋ฏธ๋‹ˆ๋ฉ€ํ•œ ์ธํ„ฐ๋ŸฝํŠธ ๊ธฐ๋ฐ˜ UDP ์ฐธ๊ณ  ์˜ˆ์ œ๋กœ, setSIMR / setSn_IMR / INT_RECV_ON์„ FreeRTOS ํƒœ์Šคํฌ์— ์—ฐ๊ฒฐํ•˜๋Š” ๊ณผ์ •์„ ๊ฐ€์žฅ ์ ์€ ๋ถ€ํ’ˆ์œผ๋กœ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์ž์ฃผ ๋ฌป๋Š” ์งˆ๋ฌธ (FAQ)

Q. ์ด ํ”„๋กœ์ ํŠธ๋Š” ๋ฌด์—‡์„ ํ•˜๋‚˜์š”? STM32F407์—์„œ FreeRTOS ์œ„์— WIZnet W5500์„ UDP ์—์ฝ” ์„œ๋ฒ„๋กœ ๊ตฌ๋™ํ•ฉ๋‹ˆ๋‹ค. ํฌํŠธ 1111๋กœ UDP ๋ฐ์ดํ„ฐ๊ทธ๋žจ์ด ์˜ค๋ฉด ์ฝ๊ณ  "answer_OK"๋กœ ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค.

Q. WIZnet ์นฉ์˜ ์—ญํ• ์€? W5500์€ ํ•˜๋“œ์™€์ด์–ด๋“œ TCP/IP ์ปจํŠธ๋กค๋Ÿฌ๋กœ, ๋„คํŠธ์›Œํฌ ์Šคํƒ์„ ํ•˜๋“œ์›จ์–ด์—์„œ ์ฒ˜๋ฆฌํ•˜๊ณ  STM32๋Š” SPI๋กœ ๊ตฌ๋™๋งŒ ํ•˜๋ฏ€๋กœ MCU๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ง‘์ค‘ํ•ฉ๋‹ˆ๋‹ค(TOE ์„ค๊ณ„).

Q. ์ˆ˜์‹ ์€ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋‚˜์š”? ์ธํ„ฐ๋ŸฝํŠธ ๊ธฐ๋ฐ˜์ž…๋‹ˆ๋‹ค. W5500์ด ์†Œ์ผ“ ์ˆ˜์‹  ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์˜ฌ๋ฆฌ๋ฉด FreeRTOS ํƒœ์Šคํฌ๊ฐ€ ๊นจ์–ด recvfrom์œผ๋กœ ์ฝ๊ณ  sendto๋กœ ์‘๋‹ตํ•œ ๋’ค ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋‹ค์‹œ ์ผญ๋‹ˆ๋‹ค. ๋ฐ”์œ ํด๋ง์ด ์—†์Šต๋‹ˆ๋‹ค.

Q. ์žฌํ˜„์ด ๊ฐ€์žฅ ์–ด๋ ค์šด ๋ถ€๋ถ„์€? SPI ์ฝœ๋ฐฑ ๋ฐฐ์„ ๊ณผ ์†Œ์ผ“ ์ธํ„ฐ๋ŸฝํŠธ ๋งˆ์Šคํฌ ์„ค์ •์ž…๋‹ˆ๋‹ค. W5500 CSยท๋ฐ”์ดํŠธยท๋ฒ„์ŠคํŠธ ์ฝœ๋ฐฑ์ด SPI ์„ค์ •๊ณผ ๋งž์•„์•ผ ํ•˜๊ณ , ์ •์  IP๊ฐ€ ๋„คํŠธ์›Œํฌ์— ๋งž์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Q. Mongoose๋‚˜ lwIP ๊ฐ™์€ ์†Œํ”„ํŠธ์›จ์–ด ์Šคํƒ๊ณผ ๋น„๊ตํ•˜๋ฉด? ์—ฌ๊ธฐ์„œ๋Š” W5500์ด TCP/IP ์Šคํƒ์„ ๋‹ด๋‹นํ•ด RAMยทCPU ์‚ฌ์šฉ์ด ๋‚ฎ๊ณ  ํƒ€์ด๋ฐ์ด ์˜ˆ์ธก ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์†Œํ”„ํŠธ์›จ์–ด ์Šคํƒ์€ ๊ธฐ๋Šฅ์ด ๋งŽ์ง€๋งŒ MCU ์ž์›์„ ์“ฐ๋ฉฐ, ์ด ํ”„๋กœ์ ํŠธ๋Š” ๊ฐ€๋ฒผ์šด ํ•˜๋“œ์›จ์–ด ์†Œ์ผ“ ๊ฒฝ๋กœ๋ฅผ ํƒํ•ฉ๋‹ˆ๋‹ค.

Documents

  • Project repository

    STM32F407 + W5500 + FreeRTOS UDP server (source, Makefile, scripts)

  • UDP server source (net.c)

    W5500 socket init, interrupt-driven recvfrom/sendto, udp_task

  • WIZnet ioLibrary_Driver

    WIZnet socket API and W5500 driver used by the project

  • WIZnet W5500

    Hardwired TCP/IP Ethernet controller product page

  • FreeRTOS

    Real-time kernel running the udp_task and led_task

Comments

Comments