w6300-evb-pico2-json
https://github.com/lhalf/w6300-evb-pico2-json
W6300-EVB-Pico2 JSON UDP Relay
What It Does
If an incoming UDP packet is valid JSON, echo it back. Otherwise, drop it silently.
The core logic is three lines in relay.rs:
if let Ok((data, metadata)) = socket.recv(buffer).await
&& serde_json_core::from_slice::<serde::de::IgnoredAny>(data).is_ok()
{
let _ = socket.send(data, metadata).await;
}The feature itself is simple. The code structure is the more interesting part.
The Role of W6300
In this project, the W6300 is more than just an Ethernet chip. Its hardware TCP/IP stack handles all network processing, which means the RP2350 can focus entirely on JSON validation. Compared to running a software network stack on the MCU itself, the separation of CPU load is clean.
The embassy-net-wiznet driver in the Rust + Embassy ecosystem has official support for the W6300, so no low-level driver code was needed. The RP2350's PIO and DMA channels (CH0, CH1) handle SPI communication with the W6300 asynchronously, without CPU involvement.
W6300-EVB-Pico2
├── W6300 (Hardware TCP/IP)
│ PIO SPI 15 MHz + DMA CH0/CH1
│ → handles all network processing
│
└── RP2350
→ JSON validation onlyCode Structure
Socket Abstraction
Hardware dependencies are separated through the Socket trait.
pub trait Socket<'a> {
async fn recv(&self, buffer: &'a mut [u8]) -> Result<(&'a [u8], UdpMetadata), RecvError>;
async fn send(&self, data: &[u8], metadata: UdpMetadata) -> Result<(), SendError>;
}In production, UdpSocket implements this trait. In tests, a SocketSpy generated by autospy takes its place. This is what allows the relay() logic to be unit tested on x86 without any hardware.
Embassy Async Tasks
main task
├── ethernet_task → W6300 SPI event handling
├── network_task → embassy-net TCP/IP stack
└── relay loop → recv → JSON validation → sendThree tasks run cooperatively via async/await, no RTOS required.
JSON Parsing
serde_json_core is a no_std JSON parser that works without heap allocation. Using IgnoredAny as the target type skips deserialization entirely — it only checks whether the input is valid JSON.
Build
just flash # build + flash
just check # fmt + clippy
just test # unit tests
just e2e-test # E2E tests (board required)
just perf-test # performance testRelease builds use LTO + opt-level = 'z' (size-optimized).
Use Cases
- Network ingress validation In environments where multiple devices send data to a central server, the W6300-EVB-Pico2 can sit at the edge and filter out malformed packets before they reach the server. This moves the validation burden to hardware and reduces the chance of parse errors propagating into the system.
- Industrial / factory environments On lines where PLCs or sensors send JSON over UDP, this can act as a gateway that blocks malformed packets from reaching control systems.
- Prototyping tool A simple way to verify that an IoT device under development is producing valid JSON. If the echo comes back, the format is correct. If it doesn't, there's a formatting issue.
- Edge computing pre-processing As a first-stage data quality filter at the edge, before data is forwarded to the cloud.
The current implementation only does "validate and echo," so extending it to forward or transform packets to other destinations would be needed for more practical use cases. As it stands, it works well as a reference project showing how to build clean, testable embedded networking code with Rust and the W6300.
GitHub Repository: https://github.com/lhalf/w6300-evb-pico2-json
