-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Embassy Executor Linking Issue #61
Comments
Enable generic-queue-8 feature on embassy-time. |
Awesome, thanks! But now that it compiles, I get a panic:
And here's my code: #![feature(iter_intersperse)]
use edge_http::io::server::{DefaultServer, Handler};
use edge_nal::TcpBind;
use edge_ws::{FrameHeader, FrameType};
use esp_idf_svc::hal::task::block_on;
use edge_http::ws::MAX_BASE64_KEY_RESPONSE_LEN;
use esp_idf_svc::io::vfs;
use edge_http::io::Error as EdgeError;
use edge_http::Method as EdgeMethod;
use esp_idf_svc::nvs::EspDefaultNvsPartition;
use esp_idf_svc::timer::EspTaskTimerService;
use esp_idf_svc::wifi::{AsyncWifi, EspWifi};
use esp_idf_svc::{
eventloop::EspSystemEventLoop,
hal::peripherals::Peripherals,
};
use std::sync::{Arc, Mutex};
use wifi::WifiEnum;
use core::fmt::{Debug, Display};
use edge_http::io::server::Connection;
use embedded_io_async::{Read, Write};
// use wifi::get;
use ws2812_esp32_rmt_driver::{driver::color::LedPixelColorGrb24, LedPixelEsp32Rmt, RGB8};
// mod dns;
mod helpers;
mod led;
// mod routes;
mod wifi;
static BUILD_TIMESTAMP: &str = env!("VERGEN_BUILD_TIMESTAMP");
static RUSTC_VERSION: &str = env!("VERGEN_RUSTC_SEMVER");
static GIT_COMMIT_HASH: &str = env!("VERGEN_GIT_SHA");
static GIT_DESCRIBE: &str = env!("VERGEN_GIT_DESCRIBE");
static GIT_COMMIT_TIMESTAMP: &str = env!("VERGEN_GIT_COMMIT_TIMESTAMP");
static GIT_COMMIT_AUTHOR_NAME: &str = env!("VERGEN_GIT_COMMIT_AUTHOR_NAME");
pub type LedType<'a> = LedPixelEsp32Rmt<'static, RGB8, LedPixelColorGrb24>;
fn main() -> Result<(), ()> {
// It is necessary to call this function once. Otherwise some patches to the runtime
// implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
esp_idf_svc::sys::link_patches();
// Bind the log crate to the ESP Logging facilities
esp_idf_svc::log::EspLogger::initialize_default();
log::info!(
"Basic init done. Built on {} with Rustc {} from Commit {}, described as \"{}\" and commited on {} by {}.",
&BUILD_TIMESTAMP,
&RUSTC_VERSION,
&GIT_COMMIT_HASH,
&GIT_DESCRIBE,
&GIT_COMMIT_TIMESTAMP,
&GIT_COMMIT_AUTHOR_NAME
);
let peripherals = Peripherals::take().unwrap();
let rgb_led_pin = peripherals.pins.gpio21;
let rgb_led_channel = peripherals.rmt.channel0;
let ws2812: Arc<
Mutex<
LedPixelEsp32Rmt<
'_,
smart_leds::RGB<u8>,
ws2812_esp32_rmt_driver::driver::color::LedPixelColorImpl<3, 1, 0, 2, 255>,
>,
>,
> = Arc::new(Mutex::new(
LedType::new(rgb_led_channel, rgb_led_pin).unwrap(),
));
let pixels = std::iter::repeat(RGB8::new(255, 255, 0)).take(1);
ws2812.lock().unwrap().write_nocopy(pixels).unwrap();
let sysloop = EspSystemEventLoop::take().unwrap();
vfs::initialize_eventfd(5).unwrap();
let nvs = EspDefaultNvsPartition::take().unwrap();
let timer_service = EspTaskTimerService::new().unwrap();
let driver = EspWifi::new(peripherals.modem, sysloop.clone(), Some(nvs.clone())).unwrap();
let mut wifi = AsyncWifi::wrap(driver, sysloop, timer_service).unwrap();
let wifi_status: Arc<Mutex<WifiEnum>> = Arc::new(Mutex::new(WifiEnum::Working));
block_on(wifi::wifi_setup(
&mut wifi,
nvs.clone(),
ws2812.clone(),
wifi_status.clone(),
))
.unwrap();
log::info!("WiFi Started");
let mut server = DefaultServer::new();
block_on(run(&mut server)).unwrap();
Ok(())
}
pub async fn run(server: &mut DefaultServer) -> Result<(), anyhow::Error> {
let addr = "0.0.0.0:8881";
log::info!("Running HTTP server on {addr}");
let acceptor = edge_nal_std::Stack::new()
.bind(addr.parse().unwrap())
.await?;
server.run(None, acceptor, WsHandler).await.unwrap();
Ok(())
}
#[derive(Debug)]
enum WsHandlerError<C, W> {
Connection(C),
Ws(W),
}
impl<C, W> From<C> for WsHandlerError<C, W> {
fn from(e: C) -> Self {
Self::Connection(e)
}
}
struct WsHandler;
impl Handler for WsHandler {
type Error<E>
= WsHandlerError<EdgeError<E>, edge_ws::Error<E>>
where
E: Debug;
async fn handle<T, const N: usize>(
&self,
_task_id: impl Display + Clone,
conn: &mut Connection<'_, T, N>,
) -> Result<(), Self::Error<T::Error>>
where
T: Read + Write,
{
let headers = conn.headers()?;
if headers.method != EdgeMethod::Get {
conn.initiate_response(405, Some("Method Not Allowed"), &[])
.await?;
} else if headers.path != "/" {
conn.initiate_response(404, Some("Not Found"), &[]).await?;
} else if !conn.is_ws_upgrade_request()? {
conn.initiate_response(200, Some("OK"), &[("Content-Type", "text/plain")])
.await?;
conn.write_all(b"Initiate WS Upgrade request to switch this connection to WS")
.await?;
} else {
let mut buf = [0_u8; MAX_BASE64_KEY_RESPONSE_LEN];
conn.initiate_ws_upgrade_response(&mut buf).await?;
conn.complete().await?;
log::info!("Connection upgraded to WS, starting a simple WS echo server now");
// Now we have the TCP socket in a state where it can be operated as a WS connection
// Run a simple WS echo server here
let mut socket = conn.unbind()?;
let mut buf = [0_u8; 8192];
loop {
let mut header = FrameHeader::recv(&mut socket)
.await
.map_err(WsHandlerError::Ws)?;
let payload = header
.recv_payload(&mut socket, &mut buf)
.await
.map_err(WsHandlerError::Ws)?;
match header.frame_type {
FrameType::Text(_) => {
log::info!(
"Got {header}, with payload \"{}\"",
core::str::from_utf8(payload).unwrap()
);
}
FrameType::Binary(_) => {
log::info!("Got {header}, with payload {payload:?}");
}
FrameType::Close => {
log::info!("Got {header}, client closed the connection cleanly");
break;
}
_ => {
log::info!("Got {header}");
}
}
// Echo it back now
header.mask_key = None; // Servers never mask the payload
if matches!(header.frame_type, FrameType::Ping) {
header.frame_type = FrameType::Pong;
}
log::info!("Echoing back as {header}");
header.send(&mut socket).await.map_err(WsHandlerError::Ws)?;
header
.send_payload(&mut socket, payload)
.await
.map_err(WsHandlerError::Ws)?;
}
}
Ok(())
}
} |
"Stack protection fault" means you are running with a too small stack - likely for the main task. You have to increase it in sdkconfig.defaults. |
I did increase it even further now:
Still same error. |
Pretty sure that's the problem, so most likely you are placing the sdkconfig.defaults in the wrong location (it should be in the crate root except for a workspace setup) OR you are overriding its location in .cargo/config.toml Also you are enabling other parameters which do not make sense. You should only do this if you really need it. For example, the pthread one, or the httpd ws support one (you are not really using the esp idf http server). |
One more thing that will help lowering the stack usage: use |
Okay, that worked, but a new error occurs, but now the ESP just resets once it reaches the block_on call. It then just resets without any stack trace or anything.
Here's the updated snippet: let mut server = DefaultServer::new();
log::info!("Server created");
match block_on(run(&mut server)) {
Ok(_) => (),
Err(e) => log::error!("block_on: {:?}", e),
}; It's the same with futures-lite's block_on and esp-idf-svc's block_on. I also replaced every unwrap with a match and a logging in the run function. |
There are still issues in your app that have nothing to do with edge-ws/edge-http:
I suggest you remove Or the other way around: forget about block-on and use embassy-executor to schedule your async tasks. |
Thanks for the tip, but unfortunately that didn't help. I now removed the embassy-executor and upgraded
But please keep in mind, |
( I think you are in general taking too big steps whereas you might have had an easier life if you've started simple and only when you have something working add an extra dependency and try to do the next thing. BTW: If you want a faster turnaround from me, just upload your project and I'll take the time over the weekend to clean it up for you (though again, this has nothing to do with Also - maybe you want to join the ESP-RS Matrix chat and get help that way rather than via a GH issue. Anyway, perhaps it is now easier if we just finish the process instead of you starting simple. So another problem: Why is this thing there? So remove it. You have to start removing dependencies that you absolutely don't need on your first step until you get a clean error-free link. Perhaps, rather than generating an empty project with
I keep that in mind. (
So yeah, you are now on the right track, but you need to remove a few more dependencies until embassy-time is happy. |
Thank you for the offer to look over it. Here's the repo: https://github.com/mawoka-myblock/td-free/ and that's the edge-http branch: https://github.com/mawoka-myblock/td-free/tree/edge-http-test So, the thing is that I had an existing codebase around esp-idf-svc, but the fact that the DNS/DHCP server in SoftAP mode don't seem customizable and a very basic WebSocket implementation made my try edge-http because of its more advanced approach. If you'd take the time to check that, I'd be super grateful and please give me an option to donate to you! Feel free to change the communication channel to any of the ones listed on the website: https://mawoka.eu/contact |
Hi,
I'm trying to get a websocket server working with edge-ws, but when I want to compile, I get the following error:
I want to use std with esp-rs on an ESP32C3. My dependency-section from the Cargo.toml looks like that:
The text was updated successfully, but these errors were encountered: