Skip to content

Commit

Permalink
Add a benchmarking example for blocking and async (#328)
Browse files Browse the repository at this point in the history
* Unify examples

This PR merges the chip specific examples into one folder, inside the
esp-wifi project.

To simplify building, alias' have been added to
`esp-wifi/.cargo/config.toml` per chip to automatically select the right
target and enable the chip feature.

Add build script detection for invalid features

Fix CI, use build instead of check to detect linker errors

enable async feature of hal, this breaks because of interrupt definition for systimer

upgrade hal rev

upgrade hal rev c6

undo binding modifications

fix esp now

fix esp coex

use released hals, update async examples

sync example names

sync example names

Update examples.md

Document alias

update build alias

* Add bench server

* Add bench example

* Add async bench example

* Add bench example to ci

* fmt

* fix CI

* Document bench example
  • Loading branch information
MabezDev authored Nov 1, 2023
1 parent 7632e74 commit aa10cd0
Show file tree
Hide file tree
Showing 8 changed files with 662 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ env:
PASSWORD: ""
STATIC_IP: ""
GATEWAY_IP: ""
HOST_IP: ""
DEFMT_LOG: "trace"

# Cancel any currently running workflows from the same PR, branch, or
Expand Down Expand Up @@ -62,6 +63,8 @@ jobs:
run: cd esp-wifi && cargo b${{ matrix.chip }} --no-default-features --features=async,wifi,esp-now,embassy-net,defmt,${{ matrix.chip }}-hal/embassy-time-timg0
- name: build (dhcp)
run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=dhcp --features=wifi
- name: build (bench)
run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=bench --features=wifi
- name: build (static_ip)
run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=static_ip --features=wifi
- name: build (esp_now)
Expand All @@ -72,6 +75,8 @@ jobs:
run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=embassy_esp_now_duplex --features=async,esp-now,${{ matrix.chip }}-hal/embassy-time-timg0
- name: build (embassy_dhcp)
run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=embassy_dhcp --features=async,wifi,embassy-net,${{ matrix.chip }}-hal/embassy-time-timg0
- name: build (embassy_bench)
run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=embassy_bench --features=async,wifi,embassy-net,${{ matrix.chip }}-hal/embassy-time-timg0
- name: build (embassy_access_point)
run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=embassy_access_point --features=async,wifi,embassy-net,${{ matrix.chip }}-hal/embassy-time-timg0

Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"xtask",
]
exclude = [
"extras/bench-server",
"extras/esp-wifishark",
]
resolver = "2"
Expand Down Expand Up @@ -61,4 +62,4 @@ embedded-hal-async = { version = "1.0.0-rc.1" }
# required until https://github.com/esp-rs/esp-hal/pull/891 is released
[patch.crates-io]
esp32c3-hal = { git = "https://github.com/esp-rs/esp-hal.git", rev = "8eddb9e737a1bfe0a36f90f54103e9167114813a" }
esp-hal-common = { git = "https://github.com/esp-rs/esp-hal.git", rev = "8eddb9e737a1bfe0a36f90f54103e9167114813a" }
esp-hal-common = { git = "https://github.com/esp-rs/esp-hal.git", rev = "8eddb9e737a1bfe0a36f90f54103e9167114813a" }
245 changes: 245 additions & 0 deletions esp-wifi/examples/bench.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
#![no_std]
#![no_main]

#[path = "../../examples-util/util.rs"]
mod examples_util;
use examples_util::hal;

use embedded_io::blocking::*;
use embedded_svc::ipv4::Interface;
use embedded_svc::wifi::{AccessPointInfo, ClientConfiguration, Configuration, Wifi};

use esp_backtrace as _;
use esp_println::println;
use esp_wifi::wifi::utils::create_network_interface;
use esp_wifi::wifi::{WifiError, WifiMode};
use esp_wifi::wifi_interface::WifiStack;
use esp_wifi::{current_millis, initialize, EspWifiInitFor};
use hal::clock::ClockControl;
use hal::Rng;
use hal::{peripherals::Peripherals, prelude::*};
use smoltcp::iface::SocketStorage;
use smoltcp::wire::IpAddress;
use smoltcp::wire::Ipv4Address;

const SSID: &str = env!("SSID");
const PASSWORD: &str = env!("PASSWORD");
const HOST_IP: &str = env!("HOST_IP");

const TEST_DURATION: usize = 15;
const RX_BUFFER_SIZE: usize = 16384;
const TX_BUFFER_SIZE: usize = 16384;
const IO_BUFFER_SIZE: usize = 1024;
const DOWNLOAD_PORT: u16 = 4321;
const UPLOAD_PORT: u16 = 4322;
const UPLOAD_DOWNLOAD_PORT: u16 = 4323;

#[entry]
fn main() -> ! {
#[cfg(feature = "log")]
esp_println::logger::init_logger(log::LevelFilter::Info);

let peripherals = Peripherals::take();

let system = peripherals.SYSTEM.split();
let clocks = ClockControl::max(system.clock_control).freeze();

let server_address: Ipv4Address = HOST_IP.parse().expect("Invalid HOST_IP address");

#[cfg(target_arch = "xtensa")]
let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks).timer0;
#[cfg(target_arch = "riscv32")]
let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0;
let init = initialize(
EspWifiInitFor::Wifi,
timer,
Rng::new(peripherals.RNG),
system.radio_clock_control,
&clocks,
)
.unwrap();

let wifi = peripherals.WIFI;
let mut socket_set_entries: [SocketStorage; 3] = Default::default();
let (iface, device, mut controller, sockets) =
create_network_interface(&init, wifi, WifiMode::Sta, &mut socket_set_entries).unwrap();
let wifi_stack = WifiStack::new(iface, device, sockets, current_millis);

let client_config = Configuration::Client(ClientConfiguration {
ssid: SSID.into(),
password: PASSWORD.into(),
..Default::default()
});
let res = controller.set_configuration(&client_config);
println!("wifi_set_configuration returned {:?}", res);

controller.start().unwrap();
println!("is wifi started: {:?}", controller.is_started());

println!("Start Wifi Scan");
let res: Result<(heapless::Vec<AccessPointInfo, 10>, usize), WifiError> = controller.scan_n();
if let Ok((res, _count)) = res {
for ap in res {
println!("{:?}", ap);
}
}

println!("{:?}", controller.get_capabilities());
println!("wifi_connect {:?}", controller.connect());

// wait to get connected
println!("Wait to get connected");
loop {
let res = controller.is_connected();
match res {
Ok(connected) => {
if connected {
break;
}
}
Err(err) => {
println!("{:?}", err);
loop {}
}
}
}
println!("{:?}", controller.is_connected());

// wait for getting an ip address
println!("Wait to get an ip address");
loop {
wifi_stack.work();

if wifi_stack.is_iface_up() {
println!("got ip {:?}", wifi_stack.get_ip_info());
break;
}
}

let mut rx_buffer = [0u8; RX_BUFFER_SIZE];
let mut tx_buffer = [0u8; TX_BUFFER_SIZE];
let mut socket = wifi_stack.get_socket(&mut rx_buffer, &mut tx_buffer);

let delay = hal::Delay::new(&clocks);

loop {
test_download(server_address, &mut socket);
delay.delay(3_000_000);
socket.work();
test_upload(server_address, &mut socket);
socket.work();
delay.delay(3_000_000);
test_upload_download(server_address, &mut socket);
socket.work();
delay.delay(3_000_000);
}
}

fn test_download<'a>(
server_address: Ipv4Address,
socket: &mut esp_wifi::wifi_interface::Socket<'a, 'a>,
) {
println!("Testing download...");
socket.work();

socket
.open(IpAddress::Ipv4(server_address), DOWNLOAD_PORT)
.unwrap();

let mut buf = [0; IO_BUFFER_SIZE];

let mut total = 0;
let wait_end = current_millis() + (TEST_DURATION as u64 * 1000);
loop {
socket.work();
if let Ok(len) = socket.read(&mut buf) {
total += len;
} else {
break;
}

if current_millis() > wait_end {
break;
}
}

let kbps = (total + 512) / 1024 / TEST_DURATION;
println!("download: {} kB/s", kbps);

socket.disconnect();
}

fn test_upload<'a>(
server_address: Ipv4Address,
socket: &mut esp_wifi::wifi_interface::Socket<'a, 'a>,
) {
println!("Testing upload...");
socket.work();

socket
.open(IpAddress::Ipv4(server_address), UPLOAD_PORT)
.unwrap();

let buf = [0; IO_BUFFER_SIZE];

let mut total = 0;
let wait_end = current_millis() + (TEST_DURATION as u64 * 1000);
loop {
socket.work();
if let Ok(len) = socket.write(&buf) {
total += len;
} else {
break;
}

if current_millis() > wait_end {
break;
}
}

let kbps = (total + 512) / 1024 / TEST_DURATION;
println!("upload: {} kB/s", kbps);

socket.disconnect();
}

fn test_upload_download<'a>(
server_address: Ipv4Address,
socket: &mut esp_wifi::wifi_interface::Socket<'a, 'a>,
) {
println!("Testing upload+download...");
socket.work();

socket
.open(IpAddress::Ipv4(server_address), UPLOAD_DOWNLOAD_PORT)
.unwrap();

let tx_buf = [0; IO_BUFFER_SIZE];
let mut rx_buf = [0; IO_BUFFER_SIZE];

let mut total = 0;
let wait_end = current_millis() + (TEST_DURATION as u64 * 1000);
loop {
socket.work();
if let Err(_) = socket.write(&tx_buf) {
break;
}

socket.work();

if let Ok(len) = socket.read(&mut rx_buf) {
total += len;
} else {
break;
}

if current_millis() > wait_end {
break;
}
}

let kbps = (total + 512) / 1024 / TEST_DURATION;
println!("upload+download: {} kB/s", kbps);

socket.disconnect();
}
Loading

0 comments on commit aa10cd0

Please sign in to comment.