dual core setup

This commit is contained in:
Priec
2026-01-18 11:20:20 +01:00
parent 5c12591524
commit 273bf2f946
5 changed files with 62 additions and 27 deletions

View File

@@ -6,10 +6,13 @@
clippy::mem_forget,
reason = "mem::forget is generally not safe to do with esp_hal types"
)]
// TODO WARNING core 1 should be logic, core 0 wifi, its flipped now
use embassy_executor::Spawner;
use embassy_futures::select::{select3, Either3};
use embassy_net::{Runner, StackResources};
use embassy_sync::signal::Signal;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_time::{Duration, Timer};
use projekt_final::bus::I2cInner;
@@ -20,6 +23,7 @@ use esp_hal::{
clock::CpuClock,
i2c::master::{Config as I2cConfig, I2c},
rng::Rng,
system::{CpuControl, Stack},
timer::timg::TimerGroup,
};
use esp_wifi::{
@@ -43,6 +47,9 @@ extern crate alloc;
use alloc::format;
static I2C_BUS: StaticCell<RefCell<I2cInner>> = StaticCell::new();
static APP_CORE_STACK: StaticCell<Stack<8192>> = StaticCell::new();
static EXECUTOR_CORE1: StaticCell<esp_hal_embassy::Executor> = StaticCell::new();
static NETWORK_READY: Signal<CriticalSectionRawMutex, ()> = Signal::new();
macro_rules! mk_static {
($t:ty,$val:expr) => {{
@@ -97,21 +104,25 @@ async fn main(spawner: Spawner) -> ! {
let timg1 = TimerGroup::new(peripherals.TIMG1);
esp_hal_embassy::init(timg1.timer0);
let net_config = embassy_net::Config::dhcpv4(Default::default());
let seed = (rng.random() as u64) << 32 | rng.random() as u64;
let (stack, runner) = embassy_net::new(
wifi_interface,
net_config,
mk_static!(StackResources<3>, StackResources::<3>::new()),
seed,
);
// Start core 1 for WiFi and MQTT (network stack created there)
let mut cpu_control = CpuControl::new(peripherals.CPU_CTRL);
let _guard = cpu_control.start_app_core(
APP_CORE_STACK.init(Stack::new()),
move || {
let executor = EXECUTOR_CORE1.init(esp_hal_embassy::Executor::new());
executor.run(|spawner| {
spawner.spawn(core1_network_task(spawner, controller, wifi_interface, seed)).ok();
});
}
).unwrap();
spawner.spawn(connection_task(controller)).expect("spawn connection_task");
spawner.spawn(net_task(runner)).expect("spawn net_task");
wait_for_network(stack).await;
// Wait for network to be ready (signaled from core 1)
NETWORK_READY.wait().await;
info!("Network ready, starting core 0 tasks");
spawner.spawn(mqtt_task(stack)).expect("spawn mqtt_task");
// Core 0: display and MPU tasks
spawner.spawn(display::task::display_task(display_i2c)).expect("spawn display_task");
spawner.spawn(mpu::task::mpu_task(mpu_i2c)).expect("spawn mpu_task");
@@ -156,7 +167,27 @@ async fn main(spawner: Spawner) -> ! {
}
}
async fn wait_for_network(stack: embassy_net::Stack<'static>) {
// Runs on core 1 - creates and owns the network stack
#[embassy_executor::task]
async fn core1_network_task(
spawner: Spawner,
controller: WifiController<'static>,
wifi_interface: WifiDevice<'static>,
seed: u64,
) {
spawner.spawn(connection_task(controller)).ok();
let net_config = embassy_net::Config::dhcpv4(Default::default());
let (stack, runner) = embassy_net::new(
wifi_interface,
net_config,
mk_static!(StackResources<3>, StackResources::<3>::new()),
seed,
);
spawner.spawn(net_task(runner)).ok();
// Wait for network
loop {
if stack.is_link_up() { break; }
Timer::after(Duration::from_millis(500)).await;
@@ -168,6 +199,12 @@ async fn wait_for_network(stack: embassy_net::Stack<'static>) {
}
Timer::after(Duration::from_millis(500)).await;
}
// Signal core 0 that network is ready
NETWORK_READY.signal(());
// Start MQTT on this core (it needs the stack)
spawner.spawn(mqtt_task(stack)).ok();
}
async fn handle_mqtt_message(msg: IncomingMsg) {