aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-05-23 03:50:43 +0200
committerDario Nieuwenhuis <[email protected]>2022-05-25 19:56:22 +0200
commita5aea995a802fea8fc1b3e4b5fe47bd6d1fca2a4 (patch)
tree0fcb4c01914347eff5b3be44b284aa9432e28678 /examples
parent36a1f203648dcb402727ea3eb5d30cf1f6993795 (diff)
WIP embassy-net v2
Diffstat (limited to 'examples')
-rw-r--r--examples/nrf/src/bin/usb_ethernet.rs75
-rw-r--r--examples/std/src/bin/net.rs51
-rw-r--r--examples/std/src/tuntap.rs2
-rw-r--r--examples/stm32f7/Cargo.toml7
-rw-r--r--examples/stm32f7/src/bin/eth.rs173
-rw-r--r--examples/stm32h7/Cargo.toml7
-rw-r--r--examples/stm32h7/src/bin/eth.rs181
7 files changed, 240 insertions, 256 deletions
diff --git a/examples/nrf/src/bin/usb_ethernet.rs b/examples/nrf/src/bin/usb_ethernet.rs
index 843487c03..49f2fb89a 100644
--- a/examples/nrf/src/bin/usb_ethernet.rs
+++ b/examples/nrf/src/bin/usb_ethernet.rs
@@ -12,8 +12,9 @@ use embassy::channel::Channel;
12use embassy::executor::Spawner; 12use embassy::executor::Spawner;
13use embassy::util::Forever; 13use embassy::util::Forever;
14use embassy_net::tcp::TcpSocket; 14use embassy_net::tcp::TcpSocket;
15use embassy_net::{PacketBox, PacketBoxExt, PacketBuf}; 15use embassy_net::{PacketBox, PacketBoxExt, PacketBuf, Stack, StackResources};
16use embassy_nrf::pac; 16use embassy_nrf::pac;
17use embassy_nrf::rng::Rng;
17use embassy_nrf::usb::Driver; 18use embassy_nrf::usb::Driver;
18use embassy_nrf::Peripherals; 19use embassy_nrf::Peripherals;
19use embassy_nrf::{interrupt, peripherals}; 20use embassy_nrf::{interrupt, peripherals};
@@ -27,6 +28,14 @@ use panic_probe as _;
27 28
28type MyDriver = Driver<'static, peripherals::USBD>; 29type MyDriver = Driver<'static, peripherals::USBD>;
29 30
31macro_rules! forever {
32 ($val:expr) => {{
33 type T = impl Sized;
34 static FOREVER: Forever<T> = Forever::new();
35 FOREVER.put_with(move || $val)
36 }};
37}
38
30#[embassy::task] 39#[embassy::task]
31async fn usb_task(mut device: UsbDevice<'static, MyDriver>) -> ! { 40async fn usb_task(mut device: UsbDevice<'static, MyDriver>) -> ! {
32 device.run().await 41 device.run().await
@@ -72,8 +81,8 @@ async fn usb_ncm_tx_task(mut class: Sender<'static, MyDriver>) {
72} 81}
73 82
74#[embassy::task] 83#[embassy::task]
75async fn net_task() -> ! { 84async fn net_task(stack: &'static Stack<Device>) -> ! {
76 embassy_net::run().await 85 stack.run().await
77} 86}
78 87
79#[embassy::main] 88#[embassy::main]
@@ -114,8 +123,7 @@ async fn main(spawner: Spawner, p: Peripherals) {
114 control_buf: [u8; 128], 123 control_buf: [u8; 128],
115 serial_state: State<'static>, 124 serial_state: State<'static>,
116 } 125 }
117 static RESOURCES: Forever<Resources> = Forever::new(); 126 let res: &mut Resources = forever!(Resources {
118 let res = RESOURCES.put(Resources {
119 device_descriptor: [0; 256], 127 device_descriptor: [0; 256],
120 config_descriptor: [0; 256], 128 config_descriptor: [0; 256],
121 bos_descriptor: [0; 256], 129 bos_descriptor: [0; 256],
@@ -158,28 +166,31 @@ async fn main(spawner: Spawner, p: Peripherals) {
158 unwrap!(spawner.spawn(usb_ncm_rx_task(rx))); 166 unwrap!(spawner.spawn(usb_ncm_rx_task(rx)));
159 unwrap!(spawner.spawn(usb_ncm_tx_task(tx))); 167 unwrap!(spawner.spawn(usb_ncm_tx_task(tx)));
160 168
161 // Init embassy-net 169 let config = embassy_net::ConfigStrategy::Dhcp;
162 struct NetResources { 170 //let config = embassy_net::ConfigStrategy::Static(embassy_net::Config {
163 resources: embassy_net::StackResources<1, 2, 8>, 171 // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24),
164 configurator: embassy_net::DhcpConfigurator, 172 // dns_servers: Vec::new(),
165 //configurator: StaticConfigurator, 173 // gateway: Some(Ipv4Address::new(10, 42, 0, 1)),
166 device: Device, 174 //});
167 } 175
168 static NET_RESOURCES: Forever<NetResources> = Forever::new(); 176 // Generate random seed
169 let res = NET_RESOURCES.put(NetResources { 177 let mut rng = Rng::new(p.RNG, interrupt::take!(RNG));
170 resources: embassy_net::StackResources::new(), 178 let mut seed = [0; 8];
171 configurator: embassy_net::DhcpConfigurator::new(), 179 rng.blocking_fill_bytes(&mut seed);
172 //configurator: embassy_net::StaticConfigurator::new(embassy_net::Config { 180 let seed = u64::from_le_bytes(seed);
173 // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 1), 24), 181
174 // dns_servers: Default::default(), 182 // Init network stack
175 // gateway: None, 183 let device = Device {
176 //}), 184 mac_addr: our_mac_addr,
177 device: Device { 185 };
178 mac_addr: our_mac_addr, 186 let stack = &*forever!(Stack::new(
179 }, 187 device,
180 }); 188 config,
181 embassy_net::init(&mut res.device, &mut res.configurator, &mut res.resources); 189 forever!(StackResources::<1, 2, 8>::new()),
182 unwrap!(spawner.spawn(net_task())); 190 seed
191 ));
192
193 unwrap!(spawner.spawn(net_task(stack)));
183 194
184 // And now we can use it! 195 // And now we can use it!
185 196
@@ -188,7 +199,7 @@ async fn main(spawner: Spawner, p: Peripherals) {
188 let mut buf = [0; 4096]; 199 let mut buf = [0; 4096];
189 200
190 loop { 201 loop {
191 let mut socket = TcpSocket::new(&mut rx_buffer, &mut tx_buffer); 202 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
192 socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10))); 203 socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10)));
193 204
194 info!("Listening on TCP:1234..."); 205 info!("Listening on TCP:1234...");
@@ -246,7 +257,7 @@ impl embassy_net::Device for Device {
246 } 257 }
247 } 258 }
248 259
249 fn capabilities(&mut self) -> embassy_net::DeviceCapabilities { 260 fn capabilities(&self) -> embassy_net::DeviceCapabilities {
250 let mut caps = embassy_net::DeviceCapabilities::default(); 261 let mut caps = embassy_net::DeviceCapabilities::default();
251 caps.max_transmission_unit = 1514; // 1500 IP + 14 ethernet header 262 caps.max_transmission_unit = 1514; // 1500 IP + 14 ethernet header
252 caps.medium = embassy_net::Medium::Ethernet; 263 caps.medium = embassy_net::Medium::Ethernet;
@@ -271,9 +282,3 @@ impl embassy_net::Device for Device {
271 self.mac_addr 282 self.mac_addr
272 } 283 }
273} 284}
274
275#[no_mangle]
276fn _embassy_rand(buf: &mut [u8]) {
277 // TODO
278 buf.fill(0x42)
279}
diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs
index daedffb0f..74073ee81 100644
--- a/examples/std/src/bin/net.rs
+++ b/examples/std/src/bin/net.rs
@@ -4,23 +4,24 @@ use clap::Parser;
4use embassy::executor::{Executor, Spawner}; 4use embassy::executor::{Executor, Spawner};
5use embassy::util::Forever; 5use embassy::util::Forever;
6use embassy_net::tcp::TcpSocket; 6use embassy_net::tcp::TcpSocket;
7use embassy_net::{ 7use embassy_net::{ConfigStrategy, Ipv4Address, Ipv4Cidr, Stack, StackResources};
8 Config, Configurator, DhcpConfigurator, Ipv4Address, Ipv4Cidr, StackResources,
9 StaticConfigurator,
10};
11use embedded_io::asynch::Write; 8use embedded_io::asynch::Write;
12use heapless::Vec; 9use heapless::Vec;
13use log::*; 10use log::*;
11use rand_core::{OsRng, RngCore};
14 12
15#[path = "../tuntap.rs"] 13#[path = "../tuntap.rs"]
16mod tuntap; 14mod tuntap;
17 15
18use crate::tuntap::TunTapDevice; 16use crate::tuntap::TunTapDevice;
19 17
20static DEVICE: Forever<TunTapDevice> = Forever::new(); 18macro_rules! forever {
21static CONFIG_STATIC: Forever<StaticConfigurator> = Forever::new(); 19 ($val:expr) => {{
22static CONFIG_DYNAMIC: Forever<DhcpConfigurator> = Forever::new(); 20 type T = impl Sized;
23static NET_RESOURCES: Forever<StackResources<1, 2, 8>> = Forever::new(); 21 static FOREVER: Forever<T> = Forever::new();
22 FOREVER.put_with(move || $val)
23 }};
24}
24 25
25#[derive(Parser)] 26#[derive(Parser)]
26#[clap(version = "1.0")] 27#[clap(version = "1.0")]
@@ -34,8 +35,8 @@ struct Opts {
34} 35}
35 36
36#[embassy::task] 37#[embassy::task]
37async fn net_task() { 38async fn net_task(stack: &'static Stack<TunTapDevice>) -> ! {
38 embassy_net::run().await 39 stack.run().await
39} 40}
40 41
41#[embassy::task] 42#[embassy::task]
@@ -46,28 +47,36 @@ async fn main_task(spawner: Spawner) {
46 let device = TunTapDevice::new(&opts.tap).unwrap(); 47 let device = TunTapDevice::new(&opts.tap).unwrap();
47 48
48 // Choose between dhcp or static ip 49 // Choose between dhcp or static ip
49 let config: &'static mut dyn Configurator = if opts.static_ip { 50 let config = if opts.static_ip {
50 CONFIG_STATIC.put(StaticConfigurator::new(Config { 51 ConfigStrategy::Static(embassy_net::Config {
51 address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), 52 address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24),
52 dns_servers: Vec::new(), 53 dns_servers: Vec::new(),
53 gateway: Some(Ipv4Address::new(192, 168, 69, 1)), 54 gateway: Some(Ipv4Address::new(192, 168, 69, 1)),
54 })) 55 })
55 } else { 56 } else {
56 CONFIG_DYNAMIC.put(DhcpConfigurator::new()) 57 ConfigStrategy::Dhcp
57 }; 58 };
58 59
59 let net_resources = StackResources::new(); 60 // Generate random seed
61 let mut seed = [0; 8];
62 OsRng.fill_bytes(&mut seed);
63 let seed = u64::from_le_bytes(seed);
60 64
61 // Init network stack 65 // Init network stack
62 embassy_net::init(DEVICE.put(device), config, NET_RESOURCES.put(net_resources)); 66 let stack = &*forever!(Stack::new(
67 device,
68 config,
69 forever!(StackResources::<1, 2, 8>::new()),
70 seed
71 ));
63 72
64 // Launch network task 73 // Launch network task
65 spawner.spawn(net_task()).unwrap(); 74 spawner.spawn(net_task(stack)).unwrap();
66 75
67 // Then we can use it! 76 // Then we can use it!
68 let mut rx_buffer = [0; 4096]; 77 let mut rx_buffer = [0; 4096];
69 let mut tx_buffer = [0; 4096]; 78 let mut tx_buffer = [0; 4096];
70 let mut socket = TcpSocket::new(&mut rx_buffer, &mut tx_buffer); 79 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
71 80
72 socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10))); 81 socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10)));
73 82
@@ -88,12 +97,6 @@ async fn main_task(spawner: Spawner) {
88 } 97 }
89} 98}
90 99
91#[no_mangle]
92fn _embassy_rand(buf: &mut [u8]) {
93 use rand_core::{OsRng, RngCore};
94 OsRng.fill_bytes(buf);
95}
96
97static EXECUTOR: Forever<Executor> = Forever::new(); 100static EXECUTOR: Forever<Executor> = Forever::new();
98 101
99fn main() { 102fn main() {
diff --git a/examples/std/src/tuntap.rs b/examples/std/src/tuntap.rs
index 09a4be070..b70767a3a 100644
--- a/examples/std/src/tuntap.rs
+++ b/examples/std/src/tuntap.rs
@@ -209,7 +209,7 @@ impl Device for TunTapDevice {
209 } 209 }
210 } 210 }
211 211
212 fn capabilities(&mut self) -> DeviceCapabilities { 212 fn capabilities(&self) -> DeviceCapabilities {
213 let mut caps = DeviceCapabilities::default(); 213 let mut caps = DeviceCapabilities::default();
214 caps.max_transmission_unit = self.device.get_ref().mtu; 214 caps.max_transmission_unit = self.device.get_ref().mtu;
215 caps 215 caps
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml
index e68d1d58c..cd7394a5c 100644
--- a/examples/stm32f7/Cargo.toml
+++ b/examples/stm32f7/Cargo.toml
@@ -8,7 +8,7 @@ resolver = "2"
8[dependencies] 8[dependencies]
9embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-timestamp-uptime"] } 9embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "net", "stm32f767zi", "unstable-pac", "time-driver-any", "exti"] } 10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "net", "stm32f767zi", "unstable-pac", "time-driver-any", "exti"] }
11embassy-net = { path = "../../embassy-net", features = ["defmt", "tcp", "medium-ethernet", "pool-16"] } 11embassy-net = { path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "pool-16"] }
12embedded-io = { version = "0.3.0", features = ["async"] } 12embedded-io = { version = "0.3.0", features = ["async"] }
13 13
14defmt = "0.3" 14defmt = "0.3"
@@ -24,8 +24,3 @@ nb = "1.0.0"
24rand_core = "0.6.3" 24rand_core = "0.6.3"
25critical-section = "0.2.3" 25critical-section = "0.2.3"
26embedded-storage = "0.3.0" 26embedded-storage = "0.3.0"
27
28[dependencies.smoltcp]
29version = "0.8.0"
30default-features = false
31features = ["defmt"]
diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs
index dca9338b2..af012f826 100644
--- a/examples/stm32f7/src/bin/eth.rs
+++ b/examples/stm32f7/src/bin/eth.rs
@@ -2,130 +2,123 @@
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)] 3#![feature(type_alias_impl_trait)]
4 4
5use cortex_m_rt::entry;
6use defmt::*; 5use defmt::*;
7use embassy::executor::{Executor, Spawner}; 6use embassy::executor::Spawner;
8use embassy::time::{Duration, Timer}; 7use embassy::time::{Duration, Timer};
9use embassy::util::Forever; 8use embassy::util::Forever;
10use embassy_net::tcp::TcpSocket; 9use embassy_net::tcp::TcpSocket;
11use embassy_net::{Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator}; 10use embassy_net::{Ipv4Address, Stack, StackResources};
12use embassy_stm32::eth::generic_smi::GenericSMI; 11use embassy_stm32::eth::generic_smi::GenericSMI;
13use embassy_stm32::eth::{Ethernet, State}; 12use embassy_stm32::eth::{Ethernet, State};
14use embassy_stm32::interrupt;
15use embassy_stm32::peripherals::ETH; 13use embassy_stm32::peripherals::ETH;
16use embassy_stm32::peripherals::RNG;
17use embassy_stm32::rng::Rng; 14use embassy_stm32::rng::Rng;
18use embassy_stm32::time::U32Ext; 15use embassy_stm32::time::U32Ext;
19use embassy_stm32::Config; 16use embassy_stm32::Config;
17use embassy_stm32::{interrupt, Peripherals};
20use embedded_io::asynch::Write; 18use embedded_io::asynch::Write;
21use heapless::Vec;
22 19
23use defmt_rtt as _; // global logger 20use defmt_rtt as _; // global logger
24use panic_probe as _; 21use panic_probe as _;
25 22use rand_core::RngCore;
26#[embassy::task] 23
27async fn main_task( 24macro_rules! forever {
28 device: &'static mut Ethernet<'static, ETH, GenericSMI, 4, 4>, 25 ($val:expr) => {{
29 config: &'static mut StaticConfigurator, 26 type T = impl Sized;
30 spawner: Spawner, 27 static FOREVER: Forever<T> = Forever::new();
31) { 28 FOREVER.put_with(move || $val)
32 let net_resources = NET_RESOURCES.put(StackResources::new()); 29 }};
33
34 // Init network stack
35 embassy_net::init(device, config, net_resources);
36
37 // Launch network task
38 unwrap!(spawner.spawn(net_task()));
39
40 info!("Network task initialized");
41
42 // Then we can use it!
43 let mut rx_buffer = [0; 1024];
44 let mut tx_buffer = [0; 1024];
45 let mut socket = TcpSocket::new(&mut rx_buffer, &mut tx_buffer);
46
47 socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10)));
48
49 let remote_endpoint = (Ipv4Address::new(192, 168, 0, 10), 8000);
50 let r = socket.connect(remote_endpoint).await;
51 if let Err(e) = r {
52 info!("connect error: {:?}", e);
53 return;
54 }
55 info!("connected!");
56 loop {
57 let r = socket.write_all(b"Hello\n").await;
58 if let Err(e) = r {
59 info!("write error: {:?}", e);
60 return;
61 }
62 Timer::after(Duration::from_secs(1)).await;
63 }
64}
65
66#[embassy::task]
67async fn net_task() {
68 embassy_net::run().await
69} 30}
70 31
71#[no_mangle] 32type Device = Ethernet<'static, ETH, GenericSMI, 4, 4>;
72fn _embassy_rand(buf: &mut [u8]) {
73 use rand_core::RngCore;
74 33
75 critical_section::with(|_| unsafe { 34#[embassy::task]
76 unwrap!(RNG_INST.as_mut()).fill_bytes(buf); 35async fn net_task(stack: &'static Stack<Device>) -> ! {
77 }); 36 stack.run().await
78} 37}
79 38
80static mut RNG_INST: Option<Rng<RNG>> = None;
81
82static EXECUTOR: Forever<Executor> = Forever::new();
83static STATE: Forever<State<'static, ETH, 4, 4>> = Forever::new();
84static ETH: Forever<Ethernet<'static, ETH, GenericSMI, 4, 4>> = Forever::new();
85static CONFIG: Forever<StaticConfigurator> = Forever::new();
86static NET_RESOURCES: Forever<StackResources<1, 2, 8>> = Forever::new();
87
88fn config() -> Config { 39fn config() -> Config {
89 let mut config = Config::default(); 40 let mut config = Config::default();
90 config.rcc.sys_ck = Some(200.mhz().into()); 41 config.rcc.sys_ck = Some(200.mhz().into());
91 config 42 config
92} 43}
93 44
94#[entry] 45#[embassy::main(config = "config()")]
95fn main() -> ! { 46async fn main(spawner: Spawner, p: Peripherals) -> ! {
96 info!("Hello World!"); 47 info!("Hello World!");
97 48
98 info!("Setup RCC..."); 49 // Generate random seed.
99 50 let mut rng = Rng::new(p.RNG);
100 let p = embassy_stm32::init(config()); 51 let mut seed = [0; 8];
101 52 rng.fill_bytes(&mut seed);
102 let rng = Rng::new(p.RNG); 53 let seed = u64::from_le_bytes(seed);
103 unsafe {
104 RNG_INST.replace(rng);
105 }
106 54
107 let eth_int = interrupt::take!(ETH); 55 let eth_int = interrupt::take!(ETH);
108 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; 56 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
109 let state = STATE.put(State::new());
110 57
111 let eth = unsafe { 58 let device = unsafe {
112 ETH.put(Ethernet::new( 59 Ethernet::new(
113 state, p.ETH, eth_int, p.PA1, p.PA2, p.PC1, p.PA7, p.PC4, p.PC5, p.PG13, p.PB13, 60 forever!(State::new()),
114 p.PG11, GenericSMI, mac_addr, 0, 61 p.ETH,
115 )) 62 eth_int,
63 p.PA1,
64 p.PA2,
65 p.PC1,
66 p.PA7,
67 p.PC4,
68 p.PC5,
69 p.PG13,
70 p.PB13,
71 p.PG11,
72 GenericSMI,
73 mac_addr,
74 0,
75 )
116 }; 76 };
117 77
118 let config = StaticConfigurator::new(NetConfig { 78 let config = embassy_net::ConfigStrategy::Dhcp;
119 address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 0, 61), 24), 79 //let config = embassy_net::ConfigStrategy::Static(embassy_net::Config {
120 dns_servers: Vec::new(), 80 // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24),
121 gateway: Some(Ipv4Address::new(192, 168, 0, 1)), 81 // dns_servers: Vec::new(),
122 }); 82 // gateway: Some(Ipv4Address::new(10, 42, 0, 1)),
83 //});
123 84
124 let config = CONFIG.put(config); 85 // Init network stack
86 let stack = &*forever!(Stack::new(
87 device,
88 config,
89 forever!(StackResources::<1, 2, 8>::new()),
90 seed
91 ));
125 92
126 let executor = EXECUTOR.put(Executor::new()); 93 // Launch network task
94 unwrap!(spawner.spawn(net_task(&stack)));
127 95
128 executor.run(move |spawner| { 96 info!("Network task initialized");
129 unwrap!(spawner.spawn(main_task(eth, config, spawner))); 97
130 }) 98 // Then we can use it!
99 let mut rx_buffer = [0; 1024];
100 let mut tx_buffer = [0; 1024];
101
102 loop {
103 let mut socket = TcpSocket::new(&stack, &mut rx_buffer, &mut tx_buffer);
104
105 socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10)));
106
107 let remote_endpoint = (Ipv4Address::new(10, 42, 0, 1), 8000);
108 info!("connecting...");
109 let r = socket.connect(remote_endpoint).await;
110 if let Err(e) = r {
111 info!("connect error: {:?}", e);
112 continue;
113 }
114 info!("connected!");
115 loop {
116 let r = socket.write_all(b"Hello\n").await;
117 if let Err(e) = r {
118 info!("write error: {:?}", e);
119 return;
120 }
121 Timer::after(Duration::from_secs(1)).await;
122 }
123 }
131} 124}
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml
index 8aa3b31e0..0f480f7a8 100644
--- a/examples/stm32h7/Cargo.toml
+++ b/examples/stm32h7/Cargo.toml
@@ -8,7 +8,7 @@ resolver = "2"
8[dependencies] 8[dependencies]
9embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits"] } 9embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits"] }
10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] } 10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
11embassy-net = { path = "../../embassy-net", features = ["defmt", "tcp", "medium-ethernet", "pool-16"] } 11embassy-net = { path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "pool-16"] }
12embedded-io = { version = "0.3.0", features = ["async"] } 12embedded-io = { version = "0.3.0", features = ["async"] }
13 13
14defmt = "0.3" 14defmt = "0.3"
@@ -28,11 +28,6 @@ micromath = "2.0.0"
28stm32-fmc = "0.2.4" 28stm32-fmc = "0.2.4"
29embedded-storage = "0.3.0" 29embedded-storage = "0.3.0"
30 30
31[dependencies.smoltcp]
32version = "0.8.0"
33default-features = false
34features = ["defmt"]
35
36# cargo build/run 31# cargo build/run
37[profile.dev] 32[profile.dev]
38codegen-units = 1 33codegen-units = 1
diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs
index 8ece29403..649ff2605 100644
--- a/examples/stm32h7/src/bin/eth.rs
+++ b/examples/stm32h7/src/bin/eth.rs
@@ -2,90 +2,40 @@
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)] 3#![feature(type_alias_impl_trait)]
4 4
5use defmt_rtt as _; // global logger
6use panic_probe as _;
7
8use cortex_m_rt::entry;
9use defmt::*; 5use defmt::*;
10use embassy::executor::{Executor, Spawner}; 6use embassy::executor::Spawner;
11use embassy::time::{Duration, Timer}; 7use embassy::time::{Duration, Timer};
12use embassy::util::Forever; 8use embassy::util::Forever;
13use embassy_net::tcp::TcpSocket; 9use embassy_net::tcp::TcpSocket;
14use embassy_net::{Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator}; 10use embassy_net::{Ipv4Address, Stack, StackResources};
15use embassy_stm32::eth::generic_smi::GenericSMI; 11use embassy_stm32::eth::generic_smi::GenericSMI;
16use embassy_stm32::eth::{Ethernet, State}; 12use embassy_stm32::eth::{Ethernet, State};
17use embassy_stm32::interrupt;
18use embassy_stm32::peripherals::ETH; 13use embassy_stm32::peripherals::ETH;
19use embassy_stm32::peripherals::RNG;
20use embassy_stm32::rng::Rng; 14use embassy_stm32::rng::Rng;
21use embassy_stm32::time::U32Ext; 15use embassy_stm32::time::U32Ext;
22use embassy_stm32::Config; 16use embassy_stm32::Config;
17use embassy_stm32::{interrupt, Peripherals};
23use embedded_io::asynch::Write; 18use embedded_io::asynch::Write;
24use heapless::Vec;
25
26#[embassy::task]
27async fn main_task(
28 device: &'static mut Ethernet<'static, ETH, GenericSMI, 4, 4>,
29 config: &'static mut StaticConfigurator,
30 spawner: Spawner,
31) {
32 let net_resources = NET_RESOURCES.put(StackResources::new());
33
34 // Init network stack
35 embassy_net::init(device, config, net_resources);
36
37 // Launch network task
38 unwrap!(spawner.spawn(net_task()));
39
40 info!("Network task initialized");
41
42 // Then we can use it!
43 let mut rx_buffer = [0; 1024];
44 let mut tx_buffer = [0; 1024];
45 let mut socket = TcpSocket::new(&mut rx_buffer, &mut tx_buffer);
46
47 socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10)));
48
49 let remote_endpoint = (Ipv4Address::new(192, 168, 0, 10), 8000);
50 let r = socket.connect(remote_endpoint).await;
51 if let Err(e) = r {
52 info!("connect error: {:?}", e);
53 return;
54 }
55 info!("connected!");
56 loop {
57 let r = socket.write_all(b"Hello\n").await;
58 if let Err(e) = r {
59 info!("write error: {:?}", e);
60 return;
61 }
62 Timer::after(Duration::from_secs(1)).await;
63 }
64}
65 19
66#[embassy::task] 20use defmt_rtt as _; // global logger
67async fn net_task() { 21use panic_probe as _;
68 embassy_net::run().await 22use rand_core::RngCore;
23
24macro_rules! forever {
25 ($val:expr) => {{
26 type T = impl Sized;
27 static FOREVER: Forever<T> = Forever::new();
28 FOREVER.put_with(move || $val)
29 }};
69} 30}
70 31
71#[no_mangle] 32type Device = Ethernet<'static, ETH, GenericSMI, 4, 4>;
72fn _embassy_rand(buf: &mut [u8]) {
73 use rand_core::RngCore;
74 33
75 critical_section::with(|_| unsafe { 34#[embassy::task]
76 unwrap!(RNG_INST.as_mut()).fill_bytes(buf); 35async fn net_task(stack: &'static Stack<Device>) -> ! {
77 }); 36 stack.run().await
78} 37}
79 38
80static mut RNG_INST: Option<Rng<RNG>> = None;
81
82static EXECUTOR: Forever<Executor> = Forever::new();
83static STATE: Forever<State<'static, ETH, 4, 4>> = Forever::new();
84static ETH: Forever<Ethernet<'static, ETH, GenericSMI, 4, 4>> = Forever::new();
85static CONFIG: Forever<StaticConfigurator> = Forever::new();
86static NET_RESOURCES: Forever<StackResources<1, 2, 8>> = Forever::new();
87
88#[allow(unused)]
89pub fn config() -> Config { 39pub fn config() -> Config {
90 let mut config = Config::default(); 40 let mut config = Config::default();
91 config.rcc.sys_ck = Some(400.mhz().into()); 41 config.rcc.sys_ck = Some(400.mhz().into());
@@ -94,40 +44,83 @@ pub fn config() -> Config {
94 config 44 config
95} 45}
96 46
97#[entry] 47#[embassy::main(config = "config()")]
98fn main() -> ! { 48async fn main(spawner: Spawner, p: Peripherals) -> ! {
99 info!("Hello World!"); 49 info!("Hello World!");
100 50
101 info!("Setup RCC..."); 51 // Generate random seed.
102 52 let mut rng = Rng::new(p.RNG);
103 let p = embassy_stm32::init(config()); 53 let mut seed = [0; 8];
104 54 rng.fill_bytes(&mut seed);
105 let rng = Rng::new(p.RNG); 55 let seed = u64::from_le_bytes(seed);
106 unsafe {
107 RNG_INST.replace(rng);
108 }
109 56
110 let eth_int = interrupt::take!(ETH); 57 let eth_int = interrupt::take!(ETH);
111 let mac_addr = [0x10; 6]; 58 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
112 let state = STATE.put(State::new()); 59
113 let eth = unsafe { 60 let device = unsafe {
114 ETH.put(Ethernet::new( 61 Ethernet::new(
115 state, p.ETH, eth_int, p.PA1, p.PA2, p.PC1, p.PA7, p.PC4, p.PC5, p.PG13, p.PB13, 62 forever!(State::new()),
116 p.PG11, GenericSMI, mac_addr, 0, 63 p.ETH,
117 )) 64 eth_int,
65 p.PA1,
66 p.PA2,
67 p.PC1,
68 p.PA7,
69 p.PC4,
70 p.PC5,
71 p.PG13,
72 p.PB13,
73 p.PG11,
74 GenericSMI,
75 mac_addr,
76 0,
77 )
118 }; 78 };
119 79
120 let config = StaticConfigurator::new(NetConfig { 80 let config = embassy_net::ConfigStrategy::Dhcp;
121 address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 0, 61), 24), 81 //let config = embassy_net::ConfigStrategy::Static(embassy_net::Config {
122 dns_servers: Vec::new(), 82 // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24),
123 gateway: Some(Ipv4Address::new(192, 168, 0, 1)), 83 // dns_servers: Vec::new(),
124 }); 84 // gateway: Some(Ipv4Address::new(10, 42, 0, 1)),
85 //});
86
87 // Init network stack
88 let stack = &*forever!(Stack::new(
89 device,
90 config,
91 forever!(StackResources::<1, 2, 8>::new()),
92 seed
93 ));
125 94
126 let config = CONFIG.put(config); 95 // Launch network task
96 unwrap!(spawner.spawn(net_task(&stack)));
127 97
128 let executor = EXECUTOR.put(Executor::new()); 98 info!("Network task initialized");
129 99
130 executor.run(move |spawner| { 100 // Then we can use it!
131 unwrap!(spawner.spawn(main_task(eth, config, spawner))); 101 let mut rx_buffer = [0; 1024];
132 }) 102 let mut tx_buffer = [0; 1024];
103
104 loop {
105 let mut socket = TcpSocket::new(&stack, &mut rx_buffer, &mut tx_buffer);
106
107 socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10)));
108
109 let remote_endpoint = (Ipv4Address::new(10, 42, 0, 1), 8000);
110 info!("connecting...");
111 let r = socket.connect(remote_endpoint).await;
112 if let Err(e) = r {
113 info!("connect error: {:?}", e);
114 continue;
115 }
116 info!("connected!");
117 loop {
118 let r = socket.write_all(b"Hello\n").await;
119 if let Err(e) = r {
120 info!("write error: {:?}", e);
121 return;
122 }
123 Timer::after(Duration::from_secs(1)).await;
124 }
125 }
133} 126}