ESP32, Embassy & Sockets

The Problem

I was running a webserver (picoserve), but I was only able to run one worker; somewhere in the picoserve code I was running into a panic from SocketSet add function, specifically this panic:

match &mut self.sockets {
    ManagedSlice::Borrowed(_) => panic!("adding a socket to a full SocketSet"),
    #[cfg(feature = "alloc")]
    ManagedSlice::Owned(sockets) => {
        sockets.push(SocketStorage { inner: None });
        let index = sockets.len() - 1;
        put(index, &mut sockets[index], socket)
    }
}

The problem, I eventually figured out, was that the network stack created with embassy-net was being initialized with 3 sockets: one for DHCP, one for DNS, and one for the rest of the code.

Note

DHCP & DNS were for the WiFi access point that was also running

// initialize network stack
let (stack, runner) = embassy_net::new(
    device,
    config,
    make_static!(StackResources<3>, StackResources::<3>::new()),
    seed,
);

The Solution

// initialize network stack
let (stack, runner) = embassy_net::new(
    device,
    config,
    // 1 socket for dns, 1 for dhcp and 2 for the webserver
    // 1 + 1 + 2 = 4 :bicep:
    make_static!(StackResources<4>, StackResources::<4>::new()),
    seed,
);

It was then possible to spawn two web tasks in main.rs for the webserver:

for task_id in 0..2 {
    spawner.spawn(web_task(task_id, stack, app).unwrap());
}

For the super curious, the commit for this fix is on tangled & github.

I don’t know how many sockets my ESP32C5 can do, might be fun to find out, but I have the additional one I needed and that’ll do for now.

 

cmac4603

A random assortment of notes.


Categories


2026-08-09