---
title: "w6300-evb-pico2-json"
url: "https://maker.wiznet.io/Grace_Koo/projects/w6300-evb-pico2-json/"
markdown_url: "https://maker.wiznet.io/Grace_Koo/projects/w6300-evb-pico2-json/md"
type: "UCC: User Created Content"
author: "lhalf"
author_url: "https://github.com/lhalf/w6300-evb-pico2-json"
editor: "WIZnet"
editor_url: "https://maker.wiznet.io/"
original_author: "lhalf"
original_url: "https://github.com/lhalf/w6300-evb-pico2-json"
published: "2026-02-19"
language: "en"
likes: 0
views: 299
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# w6300-evb-pico2-json

> https://github.com/lhalf/w6300-evb-pico2-json

Original author: lhalf (source: https://github.com/lhalf/w6300-evb-pico2-json)

## Article

## 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`:

```plaintext
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.

```plaintext
W6300-EVB-Pico2
├── W6300 (Hardware TCP/IP)
│     PIO SPI 15 MHz + DMA CH0/CH1
│     → handles all network processing
│
└── RP2350
      → JSON validation only
```

---

## Code Structure

### Socket Abstraction

Hardware dependencies are separated through the `Socket` trait.

```plaintext
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

```plaintext
main task
├── ethernet_task  → W6300 SPI event handling
├── network_task   → embassy-net TCP/IP stack
└── relay loop     → recv → JSON validation → send
```

Three 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

```plaintext
just flash      # build + flash
just check      # fmt + clippy
just test       # unit tests
just e2e-test   # E2E tests (board required)
just perf-test  # performance test
```

Release 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](https://github.com/lhalf/w6300-evb-pico2-json)

---

Source: https://maker.wiznet.io/Grace_Koo/projects/w6300-evb-pico2-json/
