Update to latest embassy, atomic-pool, smoltcp
This commit is contained in:
@ -8,10 +8,11 @@ edition = "2018"
|
||||
heapless = { version = "0.5.6", default-features = false }
|
||||
embassy = { version = "0.1.0", features=["std", "log"] }
|
||||
embassy-std = { version = "0.1.0" }
|
||||
embassy-net = { version = "0.1.0", path = "../embassy-net", features=["std", "log"] }
|
||||
embassy-net = { version = "0.1.0", path = "../embassy-net", features=["std", "log", "tcp", "dhcpv4"] }
|
||||
env_logger = "0.8.2"
|
||||
log = "0.4.11"
|
||||
futures = "0.3.8"
|
||||
libc = "0.2.81"
|
||||
async-io = "1.3.1"
|
||||
smoltcp = { version = "0.6.0", default-features = false }
|
||||
smoltcp = { version = "0.7.0", default-features = false }
|
||||
clap = { version = "3.0.0-beta.2", features = ["derive"] }
|
@ -1,6 +1,10 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(min_type_alias_impl_trait)]
|
||||
#![feature(impl_trait_in_bindings)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use embassy::executor::{task, Spawner};
|
||||
use clap::{AppSettings, Clap};
|
||||
use embassy::executor::Spawner;
|
||||
use embassy::io::AsyncWriteExt;
|
||||
use embassy::util::Forever;
|
||||
use embassy_net::*;
|
||||
@ -13,25 +17,39 @@ mod tuntap;
|
||||
use crate::tuntap::TunTapDevice;
|
||||
|
||||
static DEVICE: Forever<TunTapDevice> = Forever::new();
|
||||
static CONFIG: Forever<StaticConfigurator> = Forever::new();
|
||||
static CONFIG: Forever<DhcpConfigurator> = Forever::new();
|
||||
|
||||
#[task]
|
||||
#[derive(Clap)]
|
||||
#[clap(version = "1.0")]
|
||||
#[clap(setting = AppSettings::ColoredHelp)]
|
||||
struct Opts {
|
||||
/// TAP device name
|
||||
#[clap(long, default_value = "tap0")]
|
||||
tap: String,
|
||||
}
|
||||
|
||||
#[embassy::task]
|
||||
async fn net_task() {
|
||||
embassy_net::run().await
|
||||
}
|
||||
|
||||
#[task]
|
||||
#[embassy::task]
|
||||
async fn main_task(spawner: Spawner) {
|
||||
let opts: Opts = Opts::parse();
|
||||
|
||||
// Init network device
|
||||
let device = TunTapDevice::new("tap0").unwrap();
|
||||
let device = TunTapDevice::new(&opts.tap).unwrap();
|
||||
|
||||
// Static IP configuration
|
||||
let config = StaticConfigurator::new(UpConfig {
|
||||
address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 1), 24),
|
||||
let config = StaticConfigurator::new(Config {
|
||||
address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24),
|
||||
dns_servers: Vec::new(),
|
||||
gateway: Ipv4Address::new(192, 168, 69, 100),
|
||||
gateway: Some(Ipv4Address::new(192, 168, 69, 1)),
|
||||
});
|
||||
|
||||
// DHCP configruation
|
||||
let config = DhcpConfigurator::new();
|
||||
|
||||
// Init network stack
|
||||
embassy_net::init(DEVICE.put(device), CONFIG.put(config));
|
||||
|
||||
@ -45,7 +63,7 @@ async fn main_task(spawner: Spawner) {
|
||||
|
||||
socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10)));
|
||||
|
||||
let remote_endpoint = (Ipv4Address::new(192, 168, 69, 100), 8000);
|
||||
let remote_endpoint = (Ipv4Address::new(192, 168, 69, 74), 8000);
|
||||
info!("connecting to {:?}...", remote_endpoint);
|
||||
let r = socket.connect(remote_endpoint).await;
|
||||
if let Err(e) = r {
|
||||
|
@ -1,5 +1,4 @@
|
||||
use async_io::Async;
|
||||
use embassy::util::WakerRegistration;
|
||||
use libc;
|
||||
use log::*;
|
||||
use smoltcp::wire::EthernetFrame;
|
||||
@ -130,20 +129,21 @@ impl io::Write for TunTap {
|
||||
|
||||
pub struct TunTapDevice {
|
||||
device: Async<TunTap>,
|
||||
waker: WakerRegistration,
|
||||
waker: Option<Waker>,
|
||||
}
|
||||
|
||||
impl TunTapDevice {
|
||||
pub fn new(name: &str) -> io::Result<TunTapDevice> {
|
||||
Ok(Self {
|
||||
device: Async::new(TunTap::new(name)?)?,
|
||||
waker: WakerRegistration::new(),
|
||||
waker: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
use core::task::Waker;
|
||||
use embassy_net::{DeviceCapabilities, LinkState, Packet, PacketBox, PacketBuf};
|
||||
use embassy_net::{DeviceCapabilities, LinkState, Packet, PacketBox, PacketBoxExt, PacketBuf};
|
||||
use std::task::Context;
|
||||
|
||||
impl crate::Device for TunTapDevice {
|
||||
fn is_transmit_ready(&mut self) -> bool {
|
||||
@ -169,7 +169,8 @@ impl crate::Device for TunTapDevice {
|
||||
return Some(pkt.slice(0..n));
|
||||
}
|
||||
Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
|
||||
let ready = if let Some(mut cx) = self.waker.context() {
|
||||
let ready = if let Some(w) = self.waker.as_ref() {
|
||||
let mut cx = Context::from_waker(w);
|
||||
let ready = self.device.poll_readable(&mut cx).is_ready();
|
||||
ready
|
||||
} else {
|
||||
@ -184,8 +185,28 @@ impl crate::Device for TunTapDevice {
|
||||
}
|
||||
}
|
||||
|
||||
fn register_waker(&mut self, waker: &Waker) {
|
||||
self.waker.register(waker)
|
||||
fn register_waker(&mut self, w: &Waker) {
|
||||
match self.waker {
|
||||
// Optimization: If both the old and new Wakers wake the same task, we can simply
|
||||
// keep the old waker, skipping the clone. (In most executor implementations,
|
||||
// cloning a waker is somewhat expensive, comparable to cloning an Arc).
|
||||
Some(ref w2) if (w2.will_wake(w)) => {}
|
||||
_ => {
|
||||
// clone the new waker and store it
|
||||
if let Some(old_waker) = core::mem::replace(&mut self.waker, Some(w.clone())) {
|
||||
// We had a waker registered for another task. Wake it, so the other task can
|
||||
// reregister itself if it's still interested.
|
||||
//
|
||||
// If two tasks are waiting on the same thing concurrently, this will cause them
|
||||
// to wake each other in a loop fighting over this WakerRegistration. This wastes
|
||||
// CPU but things will still work.
|
||||
//
|
||||
// If the user wants to have two tasks waiting on the same thing they should use
|
||||
// a more appropriate primitive that can store multiple wakers.
|
||||
old_waker.wake()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn capabilities(&mut self) -> DeviceCapabilities {
|
||||
|
Reference in New Issue
Block a user