aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-05-19 05:54:15 +0200
committerDario Nieuwenhuis <[email protected]>2022-05-19 06:15:01 +0200
commite3b8e35498e9ff749db698ef82b3d86a65ba4ffb (patch)
tree8951e6907927003d20d4567f500c29bf76009001
parent0b2f43c391f1f1f6525484c369a24e72610dd8ef (diff)
Make embassy-net nightly-only.
It's useless without async traits, so juggling the `nightly` feature around is not worth the pain.
-rw-r--r--embassy-net/Cargo.toml4
-rw-r--r--embassy-net/src/lib.rs5
-rw-r--r--embassy-net/src/tcp.rs (renamed from embassy-net/src/tcp/mod.rs)129
-rw-r--r--embassy-net/src/tcp/io_impl.rs129
-rw-r--r--embassy-stm32/Cargo.toml2
-rw-r--r--examples/nrf/Cargo.toml4
-rw-r--r--examples/std/Cargo.toml2
7 files changed, 132 insertions, 143 deletions
diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml
index 8484aebc0..b58b52f18 100644
--- a/embassy-net/Cargo.toml
+++ b/embassy-net/Cargo.toml
@@ -31,15 +31,13 @@ pool-32 = []
31pool-64 = [] 31pool-64 = []
32pool-128 = [] 32pool-128 = []
33 33
34nightly = ["embedded-io/async"]
35
36[dependencies] 34[dependencies]
37 35
38defmt = { version = "0.3", optional = true } 36defmt = { version = "0.3", optional = true }
39log = { version = "0.4.14", optional = true } 37log = { version = "0.4.14", optional = true }
40 38
41embassy = { version = "0.1.0", path = "../embassy" } 39embassy = { version = "0.1.0", path = "../embassy" }
42embedded-io = "0.3.0" 40embedded-io = { version = "0.3.0", features = [ "async" ] }
43 41
44managed = { version = "0.8.0", default-features = false, features = [ "map" ] } 42managed = { version = "0.8.0", default-features = false, features = [ "map" ] }
45heapless = { version = "0.7.5", default-features = false } 43heapless = { version = "0.7.5", default-features = false }
diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs
index ded841909..18dc1ef61 100644
--- a/embassy-net/src/lib.rs
+++ b/embassy-net/src/lib.rs
@@ -1,9 +1,6 @@
1#![cfg_attr(not(feature = "std"), no_std)] 1#![cfg_attr(not(feature = "std"), no_std)]
2#![allow(clippy::new_without_default)] 2#![allow(clippy::new_without_default)]
3#![cfg_attr( 3#![feature(generic_associated_types, type_alias_impl_trait)]
4 feature = "nightly",
5 feature(generic_associated_types, type_alias_impl_trait)
6)]
7 4
8// This mod MUST go first, so that the others see its macros. 5// This mod MUST go first, so that the others see its macros.
9pub(crate) mod fmt; 6pub(crate) mod fmt;
diff --git a/embassy-net/src/tcp/mod.rs b/embassy-net/src/tcp.rs
index 425e6acbc..c18651b93 100644
--- a/embassy-net/src/tcp/mod.rs
+++ b/embassy-net/src/tcp.rs
@@ -1,15 +1,14 @@
1use core::future::Future;
1use core::marker::PhantomData; 2use core::marker::PhantomData;
2use core::mem; 3use core::mem;
3use core::task::Poll; 4use core::task::Poll;
5use futures::future::poll_fn;
4use smoltcp::iface::{Context as SmolContext, SocketHandle}; 6use smoltcp::iface::{Context as SmolContext, SocketHandle};
5use smoltcp::socket::TcpSocket as SyncTcpSocket; 7use smoltcp::socket::TcpSocket as SyncTcpSocket;
6use smoltcp::socket::{TcpSocketBuffer, TcpState}; 8use smoltcp::socket::{TcpSocketBuffer, TcpState};
7use smoltcp::time::Duration; 9use smoltcp::time::Duration;
8use smoltcp::wire::IpEndpoint; 10use smoltcp::wire::IpEndpoint;
9 11
10#[cfg(feature = "nightly")]
11mod io_impl;
12
13use super::stack::Stack; 12use super::stack::Stack;
14 13
15#[derive(PartialEq, Eq, Clone, Copy, Debug)] 14#[derive(PartialEq, Eq, Clone, Copy, Debug)]
@@ -221,10 +220,134 @@ impl<'d> embedded_io::Io for TcpSocket<'d> {
221 type Error = Error; 220 type Error = Error;
222} 221}
223 222
223impl<'d> embedded_io::asynch::Read for TcpSocket<'d> {
224 type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
225 where
226 Self: 'a;
227
228 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
229 poll_fn(move |cx| {
230 // CAUTION: smoltcp semantics around EOF are different to what you'd expect
231 // from posix-like IO, so we have to tweak things here.
232 with_socket(self.handle, |s, _| match s.recv_slice(buf) {
233 // No data ready
234 Ok(0) => {
235 s.register_recv_waker(cx.waker());
236 Poll::Pending
237 }
238 // Data ready!
239 Ok(n) => Poll::Ready(Ok(n)),
240 // EOF
241 Err(smoltcp::Error::Finished) => Poll::Ready(Ok(0)),
242 // Connection reset. TODO: this can also be timeouts etc, investigate.
243 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
244 // smoltcp returns no errors other than the above.
245 Err(_) => unreachable!(),
246 })
247 })
248 }
249}
250
251impl<'d> embedded_io::asynch::Write for TcpSocket<'d> {
252 type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
253 where
254 Self: 'a;
255
256 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
257 poll_fn(move |cx| {
258 with_socket(self.handle, |s, _| match s.send_slice(buf) {
259 // Not ready to send (no space in the tx buffer)
260 Ok(0) => {
261 s.register_send_waker(cx.waker());
262 Poll::Pending
263 }
264 // Some data sent
265 Ok(n) => Poll::Ready(Ok(n)),
266 // Connection reset. TODO: this can also be timeouts etc, investigate.
267 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
268 // smoltcp returns no errors other than the above.
269 Err(_) => unreachable!(),
270 })
271 })
272 }
273
274 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>>
275 where
276 Self: 'a;
277
278 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
279 poll_fn(move |_| {
280 Poll::Ready(Ok(())) // TODO: Is there a better implementation for this?
281 })
282 }
283}
284
224impl<'d> embedded_io::Io for TcpReader<'d> { 285impl<'d> embedded_io::Io for TcpReader<'d> {
225 type Error = Error; 286 type Error = Error;
226} 287}
227 288
289impl<'d> embedded_io::asynch::Read for TcpReader<'d> {
290 type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
291 where
292 Self: 'a;
293
294 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
295 poll_fn(move |cx| {
296 // CAUTION: smoltcp semantics around EOF are different to what you'd expect
297 // from posix-like IO, so we have to tweak things here.
298 with_socket(self.handle, |s, _| match s.recv_slice(buf) {
299 // No data ready
300 Ok(0) => {
301 s.register_recv_waker(cx.waker());
302 Poll::Pending
303 }
304 // Data ready!
305 Ok(n) => Poll::Ready(Ok(n)),
306 // EOF
307 Err(smoltcp::Error::Finished) => Poll::Ready(Ok(0)),
308 // Connection reset. TODO: this can also be timeouts etc, investigate.
309 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
310 // smoltcp returns no errors other than the above.
311 Err(_) => unreachable!(),
312 })
313 })
314 }
315}
316
228impl<'d> embedded_io::Io for TcpWriter<'d> { 317impl<'d> embedded_io::Io for TcpWriter<'d> {
229 type Error = Error; 318 type Error = Error;
230} 319}
320
321impl<'d> embedded_io::asynch::Write for TcpWriter<'d> {
322 type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
323 where
324 Self: 'a;
325
326 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
327 poll_fn(move |cx| {
328 with_socket(self.handle, |s, _| match s.send_slice(buf) {
329 // Not ready to send (no space in the tx buffer)
330 Ok(0) => {
331 s.register_send_waker(cx.waker());
332 Poll::Pending
333 }
334 // Some data sent
335 Ok(n) => Poll::Ready(Ok(n)),
336 // Connection reset. TODO: this can also be timeouts etc, investigate.
337 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
338 // smoltcp returns no errors other than the above.
339 Err(_) => unreachable!(),
340 })
341 })
342 }
343
344 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>>
345 where
346 Self: 'a;
347
348 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
349 poll_fn(move |_| {
350 Poll::Ready(Ok(())) // TODO: Is there a better implementation for this?
351 })
352 }
353}
diff --git a/embassy-net/src/tcp/io_impl.rs b/embassy-net/src/tcp/io_impl.rs
deleted file mode 100644
index b30c920b8..000000000
--- a/embassy-net/src/tcp/io_impl.rs
+++ /dev/null
@@ -1,129 +0,0 @@
1use core::future::Future;
2use core::task::Poll;
3use futures::future::poll_fn;
4
5use super::{with_socket, Error, TcpReader, TcpSocket, TcpWriter};
6
7impl<'d> embedded_io::asynch::Read for TcpSocket<'d> {
8 type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
9 where
10 Self: 'a;
11
12 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
13 poll_fn(move |cx| {
14 // CAUTION: smoltcp semantics around EOF are different to what you'd expect
15 // from posix-like IO, so we have to tweak things here.
16 with_socket(self.handle, |s, _| match s.recv_slice(buf) {
17 // No data ready
18 Ok(0) => {
19 s.register_recv_waker(cx.waker());
20 Poll::Pending
21 }
22 // Data ready!
23 Ok(n) => Poll::Ready(Ok(n)),
24 // EOF
25 Err(smoltcp::Error::Finished) => Poll::Ready(Ok(0)),
26 // Connection reset. TODO: this can also be timeouts etc, investigate.
27 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
28 // smoltcp returns no errors other than the above.
29 Err(_) => unreachable!(),
30 })
31 })
32 }
33}
34
35impl<'d> embedded_io::asynch::Write for TcpSocket<'d> {
36 type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
37 where
38 Self: 'a;
39
40 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
41 poll_fn(move |cx| {
42 with_socket(self.handle, |s, _| match s.send_slice(buf) {
43 // Not ready to send (no space in the tx buffer)
44 Ok(0) => {
45 s.register_send_waker(cx.waker());
46 Poll::Pending
47 }
48 // Some data sent
49 Ok(n) => Poll::Ready(Ok(n)),
50 // Connection reset. TODO: this can also be timeouts etc, investigate.
51 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
52 // smoltcp returns no errors other than the above.
53 Err(_) => unreachable!(),
54 })
55 })
56 }
57
58 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>>
59 where
60 Self: 'a;
61
62 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
63 poll_fn(move |_| {
64 Poll::Ready(Ok(())) // TODO: Is there a better implementation for this?
65 })
66 }
67}
68
69impl<'d> embedded_io::asynch::Read for TcpReader<'d> {
70 type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
71 where
72 Self: 'a;
73
74 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
75 poll_fn(move |cx| {
76 // CAUTION: smoltcp semantics around EOF are different to what you'd expect
77 // from posix-like IO, so we have to tweak things here.
78 with_socket(self.handle, |s, _| match s.recv_slice(buf) {
79 // No data ready
80 Ok(0) => {
81 s.register_recv_waker(cx.waker());
82 Poll::Pending
83 }
84 // Data ready!
85 Ok(n) => Poll::Ready(Ok(n)),
86 // EOF
87 Err(smoltcp::Error::Finished) => Poll::Ready(Ok(0)),
88 // Connection reset. TODO: this can also be timeouts etc, investigate.
89 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
90 // smoltcp returns no errors other than the above.
91 Err(_) => unreachable!(),
92 })
93 })
94 }
95}
96
97impl<'d> embedded_io::asynch::Write for TcpWriter<'d> {
98 type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
99 where
100 Self: 'a;
101
102 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
103 poll_fn(move |cx| {
104 with_socket(self.handle, |s, _| match s.send_slice(buf) {
105 // Not ready to send (no space in the tx buffer)
106 Ok(0) => {
107 s.register_send_waker(cx.waker());
108 Poll::Pending
109 }
110 // Some data sent
111 Ok(n) => Poll::Ready(Ok(n)),
112 // Connection reset. TODO: this can also be timeouts etc, investigate.
113 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
114 // smoltcp returns no errors other than the above.
115 Err(_) => unreachable!(),
116 })
117 })
118 }
119
120 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>>
121 where
122 Self: 'a;
123
124 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
125 poll_fn(move |_| {
126 Poll::Ready(Ok(())) // TODO: Is there a better implementation for this?
127 })
128 }
129}
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index ce36c7da2..e310d25f2 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -90,7 +90,7 @@ time-driver-tim12 = ["_time-driver"]
90time-driver-tim15 = ["_time-driver"] 90time-driver-tim15 = ["_time-driver"]
91 91
92# Enable nightly-only features 92# Enable nightly-only features
93nightly = ["embassy/nightly", "embassy-net?/nightly", "embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "dep:embedded-io"] 93nightly = ["embassy/nightly", "embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "dep:embedded-io"]
94 94
95# Reexport stm32-metapac at `embassy_stm32::pac`. 95# Reexport stm32-metapac at `embassy_stm32::pac`.
96# This is unstable because semver-minor (non-breaking) releases of embassy-stm32 may major-bump (breaking) the stm32-metapac version. 96# This is unstable because semver-minor (non-breaking) releases of embassy-stm32 may major-bump (breaking) the stm32-metapac version.
diff --git a/examples/nrf/Cargo.toml b/examples/nrf/Cargo.toml
index d96eedf98..124725f95 100644
--- a/examples/nrf/Cargo.toml
+++ b/examples/nrf/Cargo.toml
@@ -6,12 +6,12 @@ version = "0.1.0"
6 6
7[features] 7[features]
8default = ["nightly"] 8default = ["nightly"]
9nightly = ["embassy-nrf/nightly", "embassy-nrf/unstable-traits", "embassy-usb", "embassy-usb-serial", "embassy-usb-hid", "embassy-usb-ncm", "embedded-io/async", "embassy-net/nightly"] 9nightly = ["embassy-nrf/nightly", "embassy-nrf/unstable-traits", "embassy-usb", "embassy-usb-serial", "embassy-usb-hid", "embassy-usb-ncm", "embedded-io/async", "embassy-net"]
10 10
11[dependencies] 11[dependencies]
12embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-timestamp-uptime"] } 12embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-timestamp-uptime"] }
13embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } 13embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] }
14embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "pool-16"] } 14embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "pool-16"], optional = true }
15embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"], optional = true } 15embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"], optional = true }
16embassy-usb-serial = { version = "0.1.0", path = "../../embassy-usb-serial", features = ["defmt"], optional = true } 16embassy-usb-serial = { version = "0.1.0", path = "../../embassy-usb-serial", features = ["defmt"], optional = true }
17embassy-usb-hid = { version = "0.1.0", path = "../../embassy-usb-hid", features = ["defmt"], optional = true } 17embassy-usb-hid = { version = "0.1.0", path = "../../embassy-usb-hid", features = ["defmt"], optional = true }
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml
index 863760a45..7e1c2e4bb 100644
--- a/examples/std/Cargo.toml
+++ b/examples/std/Cargo.toml
@@ -6,7 +6,7 @@ version = "0.1.0"
6 6
7[dependencies] 7[dependencies]
8embassy = { version = "0.1.0", path = "../../embassy", features = ["log", "std", "time", "nightly"] } 8embassy = { version = "0.1.0", path = "../../embassy", features = ["log", "std", "time", "nightly"] }
9embassy-net = { version = "0.1.0", path = "../../embassy-net", features=["nightly", "std", "log", "medium-ethernet", "tcp", "dhcpv4", "pool-16"] } 9embassy-net = { version = "0.1.0", path = "../../embassy-net", features=[ "std", "log", "medium-ethernet", "tcp", "dhcpv4", "pool-16"] }
10embedded-io = { version = "0.3.0", features = ["async", "std", "futures"] } 10embedded-io = { version = "0.3.0", features = ["async", "std", "futures"] }
11 11
12async-io = "1.6.0" 12async-io = "1.6.0"