Skip to content

Commit

Permalink
Status quo
Browse files Browse the repository at this point in the history
  • Loading branch information
ivmarkov committed May 2, 2024
1 parent 7d5722e commit 0fb8025
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 19 deletions.
1 change: 0 additions & 1 deletion .github/configs/sdkconfig.defaults
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Increase a bit these stack sizes as they are too low by default
CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4096
CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=8192 # For async-io

Expand Down
36 changes: 26 additions & 10 deletions examples/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ use core::pin::pin;
use embassy_futures::select::select;
use embassy_time::{Duration, Timer};

use esp_idf_matter::{Error, MatterStack, WifiBle};
use esp_idf_matter::{init_async_io, Error, MatterStack, WifiBle};

use esp_idf_svc::eventloop::EspSystemEventLoop;
use esp_idf_svc::hal::peripherals::Peripherals;
use esp_idf_svc::hal::task::block_on;
use esp_idf_svc::log::EspLogger;
use esp_idf_svc::nvs::EspDefaultNvsPartition;
use esp_idf_svc::timer::EspTaskTimerService;

use log::info;
use log::{error, info};

use rs_matter::data_model::cluster_basic_information::BasicInfoConfig;
use rs_matter::data_model::cluster_on_off;
Expand All @@ -37,23 +38,40 @@ mod dev_att;
fn main() -> Result<(), Error> {
EspLogger::initialize_default();

// We'll use `async-io` for networking, so ESP IDF VFS needs to be initialized
esp_idf_svc::io::vfs::initialize_eventfd(3)?;

info!("Starting...");

// Run in a higher-prio thread to avoid issues with `async-io` getting
// confused by the low priority of the ESP IDF main task
// Also allocate a very large stack (for now) as `rs-matter` futures do occupy quite some space
let thread = std::thread::Builder::new()
.stack_size(80 * 1024)
.spawn(run)
.stack_size(65 * 1024)
.spawn(|| {
// Eagerly initialize `async-io` to minimize the risk of stack blowups later on
init_async_io()?;

run()
})
.unwrap();

thread.join().unwrap()
}

#[inline(never)]
#[cold]
fn run() -> Result<(), Error> {
let result = block_on(matter());

if let Err(e) = &result {
error!("Matter aborted execution with error: {:?}", e);
}
{
info!("Matter finished execution successfully");
}

result
}

async fn matter() -> Result<(), Error> {
// Take the Matter stack (can be done only once),
// as we'll run it in this thread
let stack = MATTER_STACK.take();
Expand Down Expand Up @@ -126,9 +144,7 @@ fn run() -> Result<(), Error> {
});

// Schedule the Matter run & the device loop together
esp_idf_svc::hal::task::block_on(select(&mut matter, &mut device).coalesce())?;

Ok(())
select(&mut matter, &mut device).coalesce().await
}

/// The Matter stack is allocated statically to avoid
Expand Down
44 changes: 36 additions & 8 deletions src/stack.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use core::net::{Ipv4Addr, Ipv6Addr};
use core::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV6};
use core::pin::pin;
use core::time::Duration;

use embassy_futures::select::select3;
use embassy_sync::blocking_mutex::raw::{NoopRawMutex, RawMutex};

use esp_idf_svc::eventloop::EspSystemEventLoop;
use esp_idf_svc::hal::task::block_on;
use esp_idf_svc::nvs::{EspNvs, EspNvsPartition, NvsPartitionId};

use log::info;
Expand All @@ -18,7 +20,6 @@ use rs_matter::data_model::subscriptions::Subscriptions;
use rs_matter::error::ErrorCode;
use rs_matter::pairing::DiscoveryCapabilities;
use rs_matter::respond::DefaultResponder;
use rs_matter::transport::core::MATTER_SOCKET_BIND_ADDR;
use rs_matter::transport::network::{NetworkReceive, NetworkSend};
use rs_matter::utils::buf::{BufferAccess, PooledBuffers};
use rs_matter::utils::select::Coalesce;
Expand Down Expand Up @@ -124,7 +125,9 @@ where

info!("Got network with IPs: IPv4={ipv4}, IPv6={ipv6}, if={interface}");

let socket = async_io::Async::<std::net::UdpSocket>::bind(MATTER_SOCKET_BIND_ADDR)?;
let socket = async_io::Async::<std::net::UdpSocket>::bind(SocketAddr::V6(
SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, MATTER_PORT, 0, interface),
))?;

let mut main =
pin!(self.run_once(&socket, &socket, nvs.clone(), dev_comm.clone(), &handler));
Expand Down Expand Up @@ -223,19 +226,21 @@ where
interface: u32,
) -> Result<(), Error> {
use rs_matter::mdns::{
Host, MDNS_IPV4_BROADCAST_ADDR, MDNS_IPV6_BROADCAST_ADDR, MDNS_SOCKET_BIND_ADDR,
Host, MDNS_IPV4_BROADCAST_ADDR, MDNS_IPV6_BROADCAST_ADDR, MDNS_PORT,
};

let socket = async_io::Async::<std::net::UdpSocket>::bind(MDNS_SOCKET_BIND_ADDR)?;
let socket = async_io::Async::<std::net::UdpSocket>::bind(SocketAddr::V6(
SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, MDNS_PORT, 0, interface),
))?;

join_multicast_v4(&socket, MDNS_IPV4_BROADCAST_ADDR, Ipv4Addr::UNSPECIFIED)?;
join_multicast_v4(&socket, MDNS_IPV4_BROADCAST_ADDR, ipv4)?;
join_multicast_v6(&socket, MDNS_IPV6_BROADCAST_ADDR, interface)?;

self.matter()
.run_builtin_mdns(
&socket,
&socket,
Host {
&Host {
id: 0,
hostname: self.matter().dev_det().device_name,
ip: ipv4.octets(),
Expand Down Expand Up @@ -286,6 +291,8 @@ impl<'a> MatterStack<'a, Eth> {
P: NvsPartitionId,
E: NetifAccess,
{
info!("Matter Stack memory: {}B", core::mem::size_of_val(self));

self.run_with_netif(
sysloop,
nvs,
Expand All @@ -297,6 +304,27 @@ impl<'a> MatterStack<'a, Eth> {
}
}

#[inline(never)]
#[cold]
pub fn init_async_io() -> Result<(), Error> {
// We'll use `async-io` for networking, so ESP IDF VFS needs to be initialized
esp_idf_svc::io::vfs::initialize_eventfd(3)?;

block_on(init_async_io_async());

info!("Async IO initialized");

Ok(())
}

#[inline(never)]
#[cold]
async fn init_async_io_async() {
// Force the `async-io` lazy initialization to trigger earlier rather than later,
// as it consumes a lot of temp stack memory
async_io::Timer::after(Duration::from_millis(100)).await;
}

#[cfg(all(
not(esp32h2),
not(esp32s2),
Expand Down Expand Up @@ -638,7 +666,7 @@ mod wifible {
.chain(
endpoint_id,
general_commissioning::ID,
HandlerCompat(GenCommCluster::new(failsafe, rand)),
HandlerCompat(GenCommCluster::new(failsafe, false, rand)),
)
.chain(
endpoint_id,
Expand Down

0 comments on commit 0fb8025

Please sign in to comment.