Skip to content
Tech News
← Back to articles

Running Bare-Metal Rust Alongside ESP-IDF on the ESP32-S3's Second Core

read original get ESP32-S3 Dual-Core Development Kit → more articles
Why This Matters

This article highlights an innovative approach to leveraging the dual-core architecture of the ESP32-S3 by running Rust code on one core while dedicating the other to ESP-IDF's Wi-Fi and BLE functionalities. This hybrid strategy allows developers to enjoy Rust's safety and productivity benefits alongside the mature wireless stacks, addressing the ecosystem limitations and enabling more reliable embedded applications.

Key Takeaways

Running Bare-Metal Rust Alongside ESP-IDF on the ESP32-S3's Second Core

I've been working with the RP2350 and no_std Rust for a while now, and I've really come to appreciate how Rust is designed — safe yet surprisingly straightforward. But my latest project needs Wi-Fi and BLE, and the RP2350 doesn't have wireless hardware built in. That meant switching to the ESP32-S3.

The ESP32-S3 is a great chip, but here's the catch: most Wi-Fi and Bluetooth functionality lives inside Espressif's ESP-IDF framework, which is a C-based SDK built on top of FreeRTOS. There are community Rust wrappers for parts of ESP-IDF, and Espressif themselves offer some Rust support, but both are a moving target — documentation is sparse compared to the mature C API, and there's always one or two critical features missing.

So I was stuck choosing between two imperfect options:

Go all-in on Rust. I'd get the language features and crates I love, but the no_std ecosystem on ESP32-S3 is still young. In a shipping product, I didn't want to risk hitting undefined behavior in an immature HAL at 2 AM.

I'd get the language features and crates I love, but the ecosystem on ESP32-S3 is still young. In a shipping product, I didn't want to risk hitting undefined behavior in an immature HAL at 2 AM. Go all-in on ESP-IDF (C). I'd get battle-tested Wi-Fi and BLE stacks, but I'd be writing C for everything — including the business logic, audio processing, and data handling where Rust really shines.

Then I remembered something: the ESP32-S3 has two CPU cores.

There's an option buried in ESP-IDF's Kconfig called CONFIG_FREERTOS_UNICORE . When you enable it, FreeRTOS only runs on Core 0. Core 1 just... sits there, stalled, doing nothing. That got me thinking: what if I let ESP-IDF own Core 0 for all the Wi-Fi, BLE, and system tasks, and then wake up Core 1 to run my own bare-metal Rust code — completely outside the RTOS?

Both cores share the same memory space, so passing data between them should be straightforward (though it does require some unsafe Rust). And since Core 1 wouldn't be managed by FreeRTOS, there'd be no scheduler preempting my time-critical audio processing loop.

After convincing myself this wasn't completely insane, I got to work. Here's how it all fits together.

... continue reading