Embedded Web Server from Scratch on W5500-EVB-Pico
Hand-built embedded web server on W5500-EVB-Pico (RP2040 + W5500) in C, serving a personal blog from scratch. No frameworks, no OS.
0
Project description
π κ°μ
μ΄ νλ‘μ νΈλ WIZnet W5500-EVB-Pico 보λ(RP2040 + W5500 ν΅ν©)μμ HTTPλ‘ κ°μΈ λΈλ‘κ·Έλ₯Ό νΈμ€ν νλ μ²μλΆν° μ§μ ꡬνν μλ² λλ μΉμλ²μ λλ€. μΉ νλ μμν¬, RTOS, μΈλΆ λ€νΈμν¬ λΌμ΄λΈλ¬λ¦¬(lwIP, Mongoose λ±) μμ΄ CμΈμ΄(C11)λ§μΌλ‘ μμ±λ ν¬νΈν΄λ¦¬μ€ νλ‘μ νΈλ‘, μλ² λλ νλμ¨μ΄μμ μμΌ μμ€μ λ€νΈμν¬ νλ‘κ·Έλλ°μ λν κΉμ μ΄ν΄λ₯Ό μ€μ¦ν©λλ€.
"Embedded Web Server from Scratch" = μλ² λλ μΉμλ²λ₯Ό μ무 λΌμ΄λΈλ¬λ¦¬λ μ°μ§ μκ³ λ°λ°λ₯λΆν° μ§μ λ§λ€μλ€"
W5500-EVB-Picoλ μ΄ νλ‘μ νΈμ μ΅μ μ νλ«νΌμ λλ€. RP2040 λ§μ΄ν¬λ‘컨νΈλ‘€λ¬μ WIZnet W5500 μ΄λλ· μ»¨νΈλ‘€λ¬κ° νλμ 보λμ ν΅ν©λμ΄ μμ΄, λ³λμ μ΄λλ· λͺ¨λ λ°°μ μμ΄ μ»΄ν©νΈν νΌν©ν°λ§μΌλ‘ μμ ν μ μ HTTP μλ²λ₯Ό ꡬνν μ μμ΅λλ€.
π μμ€ν μν€ν μ²

π μ£Όμ κΈ°λ₯
- W5500 TCP μμΌμ μ¬μ©ν΄ HTTP/1.1 μλ² μ²μλΆν° μ§μ ꡬν
- μμ λ HTTP GET μμ²μ νμ±νκ³ HTML λΈλ‘κ·Έ μ½ν μΈ μλΉ
- W5500μ 8κ° νλμ¨μ΄ μμΌμΌλ‘ λ€μμ ν΄λΌμ΄μΈνΈ λμ μ°κ²° μ²λ¦¬
- RP2040 λ² μ΄λ©ν μ€ν (OS, FreeRTOS μμ)
- λ§μ΄ν¬λ‘컨νΈλ‘€λ¬ νλμμ μ§μ λΈλ‘κ·Έ μ½ν μΈ λ₯Ό μ μ₯ν΄ μλΉ
- LittleFS νμΌμμ€ν μΌλ‘ RP2040 λ΄μ₯ Flash κ΄λ¦¬
- USB μλ¦¬μΌ λλ²κ·Έ μ§μ (
pico_enable_stdio_usb)
π μ μ²μλΆν° μ§μ ꡬννλ?
μ΄ νλ‘μ νΈλ νμ΅ μ€μ¬μ ν¬νΈν΄λ¦¬μ€ μνμ λλ€. lwIPλ Mongoose κ°μ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νλ λμ TCP μλ², HTTP νμ, μλ΅ μμ±κΈ°λ₯Ό μ§μ ꡬνν¨μΌλ‘μ¨ μμΌ νλ‘κ·Έλλ°, HTTP νλ‘ν μ½ κ΅¬μ‘°, μλ² λλ C κ°λ°μ λν μ² μ ν μ΄ν΄λ₯Ό 보μ¬μ€λλ€.
μ€μ ꡬνλ ν΅μ¬ μμ:
| μμ | λ΄μ© |
|---|---|
| HTTP λ©μλ νμ | GET POST HEAD PUT DELETE OPTIONS TRACE CONNECT 8κ°μ§ |
| HTTP ν€λ νμ | Accept Content-Type Content-Length λ± 47κ° ν€λ νμ
|
| μν μ½λ | 200 OK 404 Not Found λ± 40κ° reason phrase μ§μ μ μ |
| 컀μ€ν W5500 λλΌμ΄λ² | lib/W5500/μ SPI λ μ§μ€ν° μμ€ λλΌμ΄λ² μ§μ μμ± |
| HTTP ꡬ쑰체 | http_request http_response request_line status_line http_header http_body |
| λΌμ°ν° | respondHTTP() β URI κΈ°λ° μ½ν
μΈ λΌμ°ν
|
π Hardware
| νλͺ© | λ΄μ© |
|---|---|
| 보λ | WIZnet W5500-EVB-Pico (RP2040 + W5500 보λ λ΄μ₯) |
| μ΄λλ· | RJ45 ν¬νΈ 보λ μ§κ²° β λ³λ μ΄λλ· λͺ¨λ λΆνμ |
| μΈμ΄ | C (C11 νμ€) |
| νλ μμν¬ | Raspberry Pi Pico SDK 2.2.0+ (λ² μ΄λ©ν) |
| λΉλ | CMake 3.12+ |
| νμΌμμ€ν | LittleFS (RP2040 λ΄μ₯ Flash) |
| λλ²κ·Έ | USB μλ¦¬μΌ (UART λΉνμ±ν) |
π HTTP μ²λ¦¬ νλ¦

π μμ€ κ΅¬μ‘°
EmbeddedWebServer/
βββ main.c # HTTP νμ, μλ΅ μμ±, λ©μΈ 루ν
βββ web_files.h # HTML/CSS νλμ μλ² λ© ν€λ
βββ CMakeLists.txt # CMake λΉλ μ€μ (Pico SDK 2.2.0+)
βββ lib/
β βββ W5500/ # 컀μ€ν
W5500 SPI λλΌμ΄λ²
β βββ littlefs/ # LittleFS νμΌμμ€ν
λΌμ΄λΈλ¬λ¦¬
βββ webFiles/ # λΈλ‘κ·Έ HTML/CSS μμ€ νμΌλ§ν¬ λΌμ΄λΈλ¬λ¦¬: pico_stdlib Β· hardware_spi Β· lfs Β· W5500
ν΅μ¬ ꡬ쑰체 (main.c)
struct http_request {
struct request_line rq_line; // λ©μλ, URI, HTTP λ²μ
struct http_header headers[32]; // μ΅λ 32κ° ν€λ
uint8_t header_cnt;
struct http_body body;
};
struct http_response {
struct status_line stat_line; // μν μ½λ, reason phrase
struct http_header headers[32];
uint8_t header_cnt;
struct http_body body;
};π μμ€ κ΅¬μ‘° λ€μ΄μ΄κ·Έλ¨
![μμ€ κ΅¬μ‘° λ° CMake λΉλ κ΅¬μ± λ€μ΄μ΄κ·Έλ¨]](/upload/_thumb/1280/ckeditor5/636705060%5F1779781065%2Epng.jpg)
λΉλ λ° νλμ
μꡬμ¬ν:
- Raspberry Pi Pico SDK 2.2.0 μ΄μ
- CMake 3.12+
- ARM GCC ν΄μ²΄μΈ
PICO_SDK_PATHνκ²½λ³μ μ€μ
# 1. μ μ₯μ ν΄λ‘
git clone https://github.com/UltraVioletWitch/EmbeddedWebServer
# 2. λΉλ λλ ν 리 μμ±
mkdir build && cd build
# 3. CMake ꡬμ±
cmake ..
# 4. λΉλ
make -j4
# 5. νλμ
# BOOTSEL λ²νΌμ λλ₯Έ μ± USB μ°κ²° β webServer.uf2λ₯Ό λλΌμ΄λΈμ 볡μ¬
cp webServer.uf2 /media/RPI-RP2/μ μ λ°©λ²:
- W5500-EVB-Picoλ₯Ό RJ45 μΌμ΄λΈλ‘ λ€νΈμν¬μ μ°κ²°
- USB μλ¦¬μΌ λͺ¨λν°μμ ν λΉλ IP μ£Όμ νμΈ
- λΈλΌμ°μ μμ
http://<ν λΉλ IP>/μ μ
π WIZnet W5500 μΉ©μ μν
μ¬μ© μΉ© λͺ¨λΈλͺ : W5500 (W5500-EVB-Picoμ ν΅ν©)
μ΄ νλ‘μ νΈμμ W5500μ λ¨μν μ΄λλ· μ»¨νΈλ‘€λ¬λ₯Ό λμ΄ νλ‘μ νΈ μ 체μ ν΅μ¬ κΈ°λ°μ λλ€. W5500-EVB-Picoμλ W5500μ΄ λ³΄λμ μ§μ ν΅ν©λμ΄ μμ΄ μΈλΆ λͺ¨λ μμ΄ RJ45 컀λ₯ν°λ§μΌλ‘ μ μ μ΄λλ· HTTP μλ²κ° κ°λ₯ν©λλ€.
μν :
- TCP μμΌ κ΄λ¦¬: W5500μ νλμ¨μ΄ TCP/IP μ€νμ΄ 8κ° λ 립 μμΌμ μ κ³΅ν΄ HTTP ν΄λΌμ΄μΈνΈ μ°κ²°μ μ²λ¦¬
- SPI μΈν°νμ΄μ€: Pico SDK
hardware_spiλ‘ RP2040κ³Ό W5500μ΄ SPI ν΅μ - HTTP μλ² λ€νΈμν¬ κ³μΈ΅:
parseHTTP()βrespondHTTP()βsendResponse()μ κ³Όμ μ λ€νΈμν¬ μ μ‘μ W5500 μμΌμ΄ λ΄λΉ - μμ μ μΈ μ μ μ°κ²°: WiFi μμ΄ RJ45 μ μ μ°κ²°λ‘ 24μκ° λΈλ‘κ·Έ νΈμ€ν
μ²μλΆν° ꡬνν μλ―Έ: 컀μ€ν
W5500 λλΌμ΄λ²(lib/W5500/)λ₯Ό μ§μ μμ±ν κ²μ W5500 μΉ©μ SPI λ μ§μ€ν° λ 벨 λμμ μμ ν μ΄ν΄νκ³ μ μ΄νλ€λ μλ―Έμ
λλ€. μ΄λ λ¨μν λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νλ κ²κ³Ό λ¬λ¦¬ κΉμ νλμ¨μ΄ μμ€μ μ΄ν΄λ₯Ό 보μ¬μ£Όλ ν¬νΈν΄λ¦¬μ€ μνμ
λλ€.
π μμ₯ λ° νμ© κ°μΉ
μλ² λλ μμ€ν ν¬νΈν΄λ¦¬μ€ νλ‘μ νΈ, λ€νΈμν¬ νλ‘κ·Έλλ° νμ΅, μ μ λ ₯ κ°μΈ λΈλ‘κ·Έ/μΉμλ² κ΅¬μΆ μλ리μ€μμ νμ©λ©λλ€. W5500-EVB-Picoλ μ λΉμ©($10 μμ€)μΌλ‘ μμ μ μΈ μ μ μ΄λλ· HTTP μλ²λ₯Ό ꡬνν μ μμ΄, Raspberry Piλ ν΄λΌμ°λ μλ² μμ΄ λ§μ΄ν¬λ‘컨νΈλ‘€λ¬λ‘ μΉ νΈμ€ν μ΄ κ°λ₯ν¨μ 보μ¬μ€λλ€.
π WIZnet μ λ΅μ κ°μΉ
μ΄ νλ‘μ νΈλ W5500-EVB-Picoκ° νμ΅Β·ν¬νΈν΄λ¦¬μ€ λͺ©μ μ μλ² λλ μΉμλ² νλ«νΌμΌλ‘ μ±νλ μ¬λ‘μ λλ€. 컀μ€ν HTTP νμμ 컀μ€ν W5500 λλΌμ΄λ²λ₯Ό λͺ¨λ μ§μ μμ±ν "μ²μλΆν° ꡬν" μ κ·Όλ²μ W5500 μΉ©κ³Ό W5500-EVB-Pico 보λμ κΈ°μ μ κΉμ΄μ νμ© κ°λ₯μ±μ μ 보μ¬μ€λλ€. lwIPλ ioLibrary μμ΄λ W5500μ μμ ν μ μ΄ν μ μμμ μ€μ¦νλ λλ¬Έ λ νΌλ°μ€μ λλ€.
π μμ½
W5500-EVB-Pico(RP2040 + W5500 ν΅ν©)μμ C(C11)λ‘ μ²μλΆν° ꡬνν μλ² λλ HTTP/1.1 μΉμλ²μ λλ€. HTTP νμ(8λ©μλ, 47ν€λ, 40μνμ½λ), 컀μ€ν W5500 SPI λλΌμ΄λ², LittleFS νμΌμμ€ν μ μΈλΆ λ€νΈμν¬ λΌμ΄λΈλ¬λ¦¬ μμ΄ μ§μ μμ±ν΄ κ°μΈ λΈλ‘κ·Έλ₯Ό νΈμ€ν ν©λλ€. Raspberry Pi Pico SDK 2.2.0+, CMake κΈ°λ° λΉλ. κΉμ νλμ¨μ΄Β·λ€νΈμν¬ νλ‘κ·Έλλ° μ΄ν΄λ₯Ό 보μ¬μ£Όλ ν¬νΈν΄λ¦¬μ€ νλ‘μ νΈμ λλ€.
π FAQ
Q1. μΉμλ²μ W5500-EVB-Picoλ₯Ό μ νν μ΄μ λ? W5500-EVB-Picoλ W5500μ 보λμ μ§μ ν΅ν©ν΄ μΈλΆ λ°°μ μ μ κ±°ν©λλ€. RP2040 + W5500 μ‘°ν©μ 8κ°μ νλμ¨μ΄ TCP/UDP μμΌκ³Ό νλμ¨μ΄ TCP/IP μ€νμ μ 곡ν΄, μννΈμ¨μ΄ TCP/IP μ€λ²ν€λ μμ΄ κ°λ¨νκ³ μμ μ μΈ μλ² λλ μΉμλ²λ₯Ό ꡬννκΈ°μ μ΅μ μ λλ€.
Q2. μ§μνλ HTTP κΈ°λ₯μ? μ²μλΆν° ꡬνν λ°©μμΌλ‘ μ μ λΈλ‘κ·Έ μ½ν μΈ μλΉμ νμν HTTP/1.1 μλΈμ μ ꡬννμ΅λλ€. GET μμ² νμ±, μλ΅ ν€λ(Content-Type, Content-Length), HTTP 200/404 μλ΅μ μ§μν©λλ€. νμ μμ€μμλ 8κ°μ§ λ©μλμ 47κ° ν€λ νμ μ μ²λ¦¬ν©λλ€.
Q3. λμ μ°κ²°μ μ²λ¦¬ν μ μλμ? W5500μ 8κ°μ λ 립μ μΈ νλμ¨μ΄ μμΌμ μ 곡ν©λλ€. μ¬λ¬ μμΌμ νμ©ν΄ λμ ν΄λΌμ΄μΈνΈλ₯Ό μ²λ¦¬ν μ μμΌλ©°, μ νν λμμ± λͺ¨λΈμ ꡬν μΈλΆμ¬νμ λ°λΌ λ€λ¦ λλ€.
Q4. μ lwIPλ Mongoose κ°μ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ°μ§ μμλμ? μ΄ νλ‘μ νΈμ ν΅μ¬ λͺ©νκ° "μ²μλΆν° μ§μ ꡬν"μ λλ€. λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νμ§ μμμΌλ‘μ¨ μμΌ νλ‘κ·Έλλ°, HTTP νλ‘ν μ½ κ΅¬μ‘°, W5500 λ μ§μ€ν° λμμ λͺ¨λ μ§μ μ΄ν΄νκ³ κ΅¬ννλ λ₯λ ₯μ ν¬νΈν΄λ¦¬μ€λ‘ μ¦λͺ ν©λλ€.
Q5. LittleFSλ μ΄λ»κ² μ¬μ©νλμ? RP2040 λ΄μ₯ Flashμ LittleFSλ₯Ό λ§μ΄νΈν΄ μΉ νμΌμ μ μ₯ν©λλ€. lib/littlefs/ λλ ν 리μ ν¬ν¨λ LittleFS λΌμ΄λΈλ¬λ¦¬λ₯Ό CMakeλ‘ λ§ν¬ν©λλ€. μΉ μ½ν
μΈ λ web_files.hμ C λ°°μ΄λ‘λ μλ² λ©λ©λλ€.
Q6. μΉ μ½ν
μΈ λ₯Ό μμ νλ €λ©΄? webFiles/ λλ ν 리μ HTML/CSS νμΌμ μμ νκ³ web_files.hλ₯Ό μ¬μμ±ν ν λ€μ λΉλΒ·νλμνλ©΄ λ©λλ€.
Q7. IP μ£Όμλ μ΄λ»κ² νμΈνλμ? pico_enable_stdio_usb=1 μ€μ μΌλ‘ USB μλ¦¬μΌ λͺ¨λν°μμ λΆν
μ μΆλ ₯λλ DHCP ν λΉ IPλ₯Ό νμΈν©λλ€. κ³ μ IPλ W5500 λλΌμ΄λ² μ΄κΈ°νμμ μ€μ κ°λ₯ν©λλ€.
Q8. Pico SDK 2.2.0μ΄ λ°λμ νμνκ°μ? CMakeLists.txtμ λͺ
μμ μΌλ‘ μꡬν©λλ€. μ΄ν λ²μ μμλ λΉλκ° μ€ν¨ν©λλ€.
Q9. 컀μ€ν
W5500 λλΌμ΄λ²λ μ΄λ»κ² λμνλμ? lib/W5500/μ λλΌμ΄λ²λ Pico SDK hardware_spiλ‘ W5500 SPI λ μ§μ€ν°μ μ§μ μ κ·Όν©λλ€. μμΌ μ΄κΈ°/λ«κΈ°, λ°μ΄ν° μ‘μμ , μ°κ²° μν νμΈ λ±μ λ μ§μ€ν° μμ€μμ μ μ΄νλ©°, WIZnet 곡μ ioLibrary μμ΄ λ°μ΄ν°μνΈ κΈ°λ°μΌλ‘ μμ±λμ΅λλ€.
Q10. μ΄ νλ‘μ νΈλ‘ 무μμ λ°°μΈ μ μλμ? TCP μμΌ νλ‘κ·Έλλ°, HTTP/1.1 νλ‘ν μ½ κ΅¬μ‘°, SPI λλΌμ΄λ² μμ±, LittleFS νμΌμμ€ν ν΅ν©, CMake λΉλ μμ€ν , λ² μ΄λ©ν RP2040 κ°λ°μ νλμ μ€μ λμνλ νλ‘μ νΈλ‘ νμ΅ν μ μμ΅λλ€.
π μ°Έκ³ λ§ν¬
- GitHub: https://github.com/UltraVioletWitch/EmbeddedWebServer
- W5500-EVB-Pico λ¬Έμ: https://docs.wiznet.io/Product/iEthernet/W5500/w5500-evb-pico
- WIZnet W5500 λ°μ΄ν°μνΈ: https://docs.wiznet.io/Product/iEthernet/W5500/datasheet
π Overview
This is a from-scratch embedded web server running on the WIZnet W5500-EVB-Pico board (RP2040 + W5500 integrated), serving a personal blog over HTTP. Written entirely in C (C11) with no web frameworks, no RTOS, and no external network libraries (lwIP, Mongoose, etc.), this portfolio project demonstrates deep understanding of network programming at the socket level on embedded hardware.
The W5500-EVB-Pico is the perfect platform for this project. The RP2040 microcontroller paired with an onboard WIZnet W5500 Ethernet controller delivers a complete wired HTTP server in a compact form factor β with no external Ethernet module or wiring required.
π System Architecture

π Key Features
- Implements an HTTP/1.1 server from scratch using W5500 TCP sockets
- Parses incoming HTTP GET requests and serves HTML blog content
- Handles multiple client connections using W5500's 8 hardware sockets
- Runs on RP2040 bare-metal (no OS, no FreeRTOS)
- Blog content served directly from the microcontroller's flash
- LittleFS filesystem for RP2040 onboard Flash management
- USB serial debug support (
pico_enable_stdio_usb)
π Why Build from Scratch?
This is a learning-focused portfolio project. Implementing the TCP server, HTTP parser, and response builder from scratch β rather than using a library like lwIP or Mongoose β demonstrates thorough knowledge of socket programming, HTTP protocol structure, and embedded C development.
Core elements implemented directly:
| Element | Details |
|---|---|
| HTTP method parser | GET POST HEAD PUT DELETE OPTIONS TRACE CONNECT β all 8 |
| HTTP header parser | 47 header types including Accept, Content-Type, Content-Length |
| Status codes | 40 reason phrases including 200 OK, 404 Not Found β defined directly |
| Custom W5500 driver | SPI register-level driver written from scratch in lib/W5500/ |
| HTTP structs | http_request, http_response, request_line, status_line, http_header, http_body |
| Router | respondHTTP() β URI-based content routing |
π Hardware
| Item | Details |
|---|---|
| Board | WIZnet W5500-EVB-Pico (RP2040 + W5500 integrated on-board) |
| Ethernet | RJ45 port on-board β no external Ethernet module needed |
| Language | C (C11 standard) |
| Framework | Raspberry Pi Pico SDK 2.2.0+ (bare-metal) |
| Build | CMake 3.12+ |
| Filesystem | LittleFS (RP2040 onboard Flash) |
| Debug | USB serial (UART disabled) |
π HTTP Request Processing Flow

π Source Structure
EmbeddedWebServer/
βββ main.c β HTTP parser, routing, response builder, main loop (457 lines)
βββ web_files.h β HTML/CSS embedded as C arrays
βββ CMakeLists.txt β CMake build config (Pico SDK 2.2.0+)
βββ lib/
β βββ W5500/ β Custom W5500 SPI driver (written from scratch)
β βββ littlefs/ β LittleFS filesystem library
βββ webFiles/ β Blog HTML/CSS source (about me, projects, etc.)Linked libraries: pico_stdlib Β· hardware_spi Β· lfs Β· W5500
Core structs in main.c:
struct http_request {
struct request_line rq_line; // method, URI, HTTP version
struct http_header headers[32]; // up to 32 headers
uint8_t header_cnt;
struct http_body body;
};
struct http_response {
struct status_line stat_line; // status code, reason phrase
struct http_header headers[32];
uint8_t header_cnt;
struct http_body body;
};π Source Structure Diagram

π Build Workflow
Requirements:
- Raspberry Pi Pico SDK 2.2.0 or later
- CMake 3.12+
- ARM GCC toolchain
PICO_SDK_PATHenvironment variable set
# 1. Clone
git clone https://github.com/UltraVioletWitch/EmbeddedWebServer
# 2. Create build directory and configure
mkdir build && cd build
cmake ..
# 3. Build
make -j4
# 4. Flash
# Hold BOOTSEL while connecting USB
# β drag and drop webServer.uf2 to the Pico USB drive
# 5. Access
# Check assigned IP from USB serial monitor
# β open http://<IP>/ in a browserπ Role and Application of the WIZnet's Chip
Chip model: W5500 (integrated on W5500-EVB-Pico)
In this project, the W5500 goes beyond a simple Ethernet controller β it is the foundation of the entire network layer. Integrated at board level on the W5500-EVB-Pico, the W5500 handles all network communication for the HTTP server.
Core roles of the W5500:
- Hardware TCP/IP stack β RP2040 uses TCP sockets directly without software TCP/IP overhead
- 8 independent hardware sockets β supports simultaneous HTTP client connections
- SPI interface β communicates with RP2040 via Pico SDK
hardware_spi - On-board RJ45 β no external Ethernet module needed, wiring minimized
- Network transport layer β handles all network transmission across the full
parseHTTP()βrespondHTTP()βsendResponse()pipeline
What the custom driver means: Writing the W5500 driver from scratch in lib/W5500/ means directly understanding and controlling the W5500 chip at the SPI register level. Unlike using the WIZnet official ioLibrary, this is a datasheet-driven implementation demonstrating deep hardware understanding β covering socket open/close, data send/receive, and connection state checking at the register level.
π Market & Application Value
- Portfolio project β proves embedded C, socket programming, and HTTP protocol implementation skills in a single working project
- Low-cost web hosting proof of concept β demonstrates that a microcontroller alone can serve a web server without Raspberry Pi or cloud infrastructure
- Educational reference β provides a fully functional from-scratch implementation for embedded networking learners
- W5500-EVB-Pico platform reference β validates the practical utility of the integrated board as a WIZnet ecosystem showcase
π WIZnet Strategic Value
This project demonstrates W5500-EVB-Pico adopted as an embedded web server platform for learning and portfolio purposes. Writing both a custom HTTP parser and a custom W5500 driver from scratch shows the technical depth and versatility of the W5500 chip and the W5500-EVB-Pico board. It is a rare reference implementation proving that W5500 can be fully controlled without lwIP or ioLibrary β driven directly from a datasheet.
π Summary
A from-scratch embedded HTTP/1.1 web server implemented in C (C11) on the W5500-EVB-Pico (RP2040 + W5500 integrated). An HTTP parser (8 methods, 47 header types, 40 status codes), a custom W5500 SPI driver, and a LittleFS filesystem were all written without any external network library to host a personal blog. The W5500's hardware TCP/IP stack simplifies socket-level programming while the RP2040 provides ample processing power β making this a compelling embedded web hosting platform. Built with Raspberry Pi Pico SDK 2.2.0+ and CMake. A portfolio project demonstrating deep understanding of socket programming, HTTP protocol structure, and embedded C development.
π FAQ
Q1. Why use W5500-EVB-Pico for a web server? The W5500-EVB-Pico integrates W5500 directly on the board, eliminating external wiring. The RP2040 + W5500 combination provides 8 hardware TCP/UDP sockets and a hardware TCP/IP stack β making it well-suited for a simple but reliable embedded web server without software TCP/IP overhead.
Q2. What HTTP features are supported? Targeting the minimal HTTP/1.1 subset needed for serving static blog content: GET request parsing, response headers (Content-Type, Content-Length), and HTTP 200/404 responses. At the parser level, 8 methods and 47 header types are handled.
Q3. Can this handle multiple simultaneous connections? The W5500 provides 8 independent hardware sockets. Multiple sockets can be used to handle concurrent clients β the exact concurrency model depends on the implementation details.
Q4. Why not use a library like lwIP or Mongoose? The core goal of this project is "build from scratch." Not using a library means directly understanding and implementing socket programming, HTTP protocol structure, and W5500 register behavior β proving that ability as a portfolio piece.
Q5. How is LittleFS used? LittleFS is mounted on the RP2040's onboard Flash to store web files. The lib/littlefs/ library is linked via CMake. Web content is also embedded as C arrays in web_files.h.
Q6. How do I modify the blog content? Edit the HTML/CSS files in the webFiles/ directory, regenerate web_files.h, then rebuild and reflash.
Q7. How do I find the IP address? The DHCP-assigned IP is printed at boot via the USB serial monitor (pico_enable_stdio_usb=1). A static IP can also be set in the W5500 driver initialization.
Q8. Is Pico SDK 2.2.0 strictly required? Yes β explicitly required in CMakeLists.txt. Builds will fail on earlier versions.
Q9. How does the custom W5500 driver work? The driver in lib/W5500/ accesses W5500 SPI registers directly using Pico SDK hardware_spi. It controls socket open/close, data send/receive, and connection state at the register level β written from the datasheet without the WIZnet official ioLibrary.
Q10. What can I learn from this project? TCP socket programming, HTTP/1.1 protocol structure, SPI driver implementation, LittleFS filesystem integration, CMake build system, and bare-metal RP2040 development β all in one working project.
π Reference Links
- GitHub: https://github.com/UltraVioletWitch/EmbeddedWebServer
- W5500-EVB-Pico docs: https://docs.wiznet.io/Product/iEthernet/W5500/w5500-evb-pico
- WIZnet W5500 datasheet: https://docs.wiznet.io/Product/iEthernet/W5500/datasheet