mirror of
https://github.com/ImplFerris/esp32-book.git
synced 2025-09-24 14:31:13 +00:00
migrated webserver-html to esp-hal 1.0.0-beta
This commit is contained in:
parent
75c8d5e262
commit
7060cc7048
@ -30,7 +30,7 @@ We will create two additional modules: web and wifi. These will be similar to wh
|
||||
├── rust-toolchain.toml
|
||||
├── src
|
||||
│ ├── bin
|
||||
│ │ └── async_main.rs
|
||||
│ │ └── main.rs
|
||||
│ ├── lib.rs
|
||||
│ ├── web.rs
|
||||
│ └── wifi.rs
|
||||
|
@ -80,7 +80,6 @@ use esp_hal::clock::CpuClock;
|
||||
use esp_hal::rng::Rng;
|
||||
use esp_hal::timer::timg::TimerGroup;
|
||||
use esp_println as _;
|
||||
use esp_println as _;
|
||||
use esp_println::println;
|
||||
use esp_wifi::wifi::{self, WifiController, WifiDevice, WifiEvent, WifiState};
|
||||
use esp_wifi::EspWifiController;
|
||||
|
@ -25,7 +25,7 @@ cp -r esp32-projects/webserver-base ~/YOUR_PROJECT_FOLDER/wifi-led
|
||||
├── rust-toolchain.toml
|
||||
├── src
|
||||
│ ├── bin
|
||||
│ │ └── async_main.rs
|
||||
│ │ └── main.rs
|
||||
│ ├── index.html
|
||||
│ ├── led.rs
|
||||
│ ├── lib.rs
|
||||
|
@ -65,7 +65,7 @@ cd esp32-projects/webserver-base
|
||||
├── rust-toolchain.toml
|
||||
├── src
|
||||
│ ├── bin
|
||||
│ │ └── async_main.rs
|
||||
│ │ └── main.rs
|
||||
│ ├── index.html
|
||||
│ ├── lib.rs
|
||||
│ ├── web.rs
|
||||
|
@ -23,11 +23,18 @@ To create the project, use the `esp-generate` command. Run the following:
|
||||
esp-generate --chip esp32 webserver-html
|
||||
```
|
||||
|
||||
This will open a screen asking you to select options.
|
||||
This will open a screen asking you to select options. In order to Enable Wi-Fi, we will first need to enable "unstable" and "alloc" features. If you noticed, until you select these two options, you wont be able to enable Wi-Fi option. So select one by one
|
||||
|
||||
- Select the option "Enables Wi-Fi via the esp-wifi crate. Requires alloc". It automatically selects the espa-alloc crate option also
|
||||
- First, select the option "Enable unstable HAL features."
|
||||
- Select the option "Enable allocations via the esp-alloc crate."
|
||||
- Now, you can enable "Enable Wi-Fi via esp-wifi crate."
|
||||
- Select the option "Adds embassy framework support".
|
||||
|
||||
Enable the logging feature also
|
||||
|
||||
- So, scroll to "Flashing, logging and debugging (espflash)" and hit Enter.
|
||||
- Then, Select "Use defmt to print messages".
|
||||
|
||||
Just save it by pressing "s" in the keyboard.
|
||||
|
||||
|
||||
@ -37,28 +44,20 @@ Just save it by pressing "s" in the keyboard.
|
||||
[picoserve](https://docs.rs/picoserve/latest/picoserve/) is a crate that provides an asynchronous HTTP server designed for bare-metal environments, heavily inspired by Axum. As you might have guessed from the name, it was first created with "Raspberry Pi Pico W" and embassy in mind. But it works fine with other embedded runtimes and hardware, including the ESP32. This crate makes our lives much easier. Without it, we would have to build the web server core from scratch, a time-consuming task that would be beyond the scope of this book.
|
||||
|
||||
```toml
|
||||
picoserve = { version = "0.13.3", features = ["embassy"] }
|
||||
picoserve = { version = "0.15.0", features = ["embassy"] }
|
||||
```
|
||||
|
||||
### Task arena size update
|
||||
We will update the embassy-executor with the task-arena-size-65536 feature. For more details, refer to the Task Arena Size documentation [here](https://docs.embassy.dev/embassy-executor/git/cortex-m/index.html#task-arena).
|
||||
|
||||
```toml
|
||||
embassy-executor = { version = "0.6.3", features = ["task-arena-size-65536"] }
|
||||
```
|
||||
|
||||
### Update the embassy-net
|
||||
To make some functions compatible with the latest picoserve crate, I needed to update embassy-net to version 0.5.0.
|
||||
|
||||
```toml
|
||||
embassy-net = { version = "0.5.0", features = [
|
||||
"tcp",
|
||||
"udp",
|
||||
"dhcpv4",
|
||||
"medium-ethernet",
|
||||
embassy-executor = { version = "0.7.0", features = [
|
||||
"defmt",
|
||||
"task-arena-size-65536",
|
||||
] }
|
||||
```
|
||||
|
||||
|
||||
## Project Structure
|
||||
|
||||
We will organize the logic by splitting it into modules. Under the lib, we will create two submodules: web.rs and wifi.rs.
|
||||
@ -69,7 +68,7 @@ We will organize the logic by splitting it into modules. Under the lib, we will
|
||||
├── rust-toolchain.toml
|
||||
├── src
|
||||
│ ├── bin
|
||||
│ │ └── async_main.rs
|
||||
│ │ └── main.rs
|
||||
│ ├── index.html
|
||||
│ ├── lib.rs
|
||||
│ ├── web.rs
|
||||
@ -98,7 +97,7 @@ macro_rules! mk_static {
|
||||
}
|
||||
```
|
||||
|
||||
## The main function (async_main.rs file)
|
||||
## The main function (main.rs file)
|
||||
|
||||
To use the lib module, we would normally have to reference it using the full project name (e.g., webserver::web). However, to keep the references consistent across different exercises, we will alias the import as "lib". This allows us to use it as "lib::web" instead.
|
||||
|
||||
@ -109,45 +108,47 @@ Next, we create a Wi-Fi controller, which we will pass to the start_wifi functio
|
||||
We will create a web application instance, configure routing and settings using the picoserve crate. We will then spawn multiple tasks to handle incoming requests based on the defined pool size. Each task receives the task ID, app instance, network stack, and server settings.
|
||||
|
||||
```rust
|
||||
use webserver as lib;
|
||||
use webserver_html as lib;
|
||||
|
||||
#[main]
|
||||
#[esp_hal_embassy::main]
|
||||
async fn main(spawner: Spawner) {
|
||||
let peripherals = esp_hal::init({
|
||||
let mut config = esp_hal::Config::default();
|
||||
config.cpu_clock = CpuClock::max();
|
||||
config
|
||||
});
|
||||
// generator version: 0.3.1
|
||||
|
||||
esp_alloc::heap_allocator!(72 * 1024);
|
||||
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
|
||||
let peripherals = esp_hal::init(config);
|
||||
|
||||
esp_println::logger::init_logger_from_env();
|
||||
esp_alloc::heap_allocator!(size: 72 * 1024);
|
||||
|
||||
let timer0 = esp_hal::timer::timg::TimerGroup::new(peripherals.TIMG1);
|
||||
let timer0 = TimerGroup::new(peripherals.TIMG1);
|
||||
esp_hal_embassy::init(timer0.timer0);
|
||||
|
||||
let rng = Rng::new(peripherals.RNG);
|
||||
|
||||
info!("Embassy initialized!");
|
||||
|
||||
let timg0 = esp_hal::timer::timg::TimerGroup::new(peripherals.TIMG0);
|
||||
let timer1 = TimerGroup::new(peripherals.TIMG0);
|
||||
// let _init = esp_wifi::init(
|
||||
// timer1.timer0,
|
||||
// esp_hal::rng::Rng::new(peripherals.RNG),
|
||||
// peripherals.RADIO_CLK,
|
||||
// )
|
||||
// .unwrap();
|
||||
|
||||
let wifi_init = lib::mk_static!(
|
||||
let rng = Rng::new(peripherals.RNG);
|
||||
let esp_wifi_ctrl = &*lib::mk_static!(
|
||||
EspWifiController<'static>,
|
||||
esp_wifi::init(timg0.timer0, rng, peripherals.RADIO_CLK).unwrap()
|
||||
esp_wifi::init(timer1.timer0, rng.clone(), peripherals.RADIO_CLK,).unwrap()
|
||||
);
|
||||
|
||||
let stack = lib::wifi::start_wifi(wifi_init, peripherals.WIFI, rng, &spawner).await;
|
||||
let stack = lib::wifi::start_wifi(esp_wifi_ctrl, peripherals.WIFI, rng, &spawner).await;
|
||||
|
||||
let web_app = lib::web::WebApp::default();
|
||||
for id in 0..lib::web::WEB_TASK_POOL_SIZE {
|
||||
spawner.must_spawn(lib::web::web_task(
|
||||
id,
|
||||
*stack,
|
||||
stack,
|
||||
web_app.router,
|
||||
web_app.config,
|
||||
));
|
||||
}
|
||||
println!("Web server started...");
|
||||
info!("Web server started...");
|
||||
}
|
||||
```
|
||||
|
@ -31,34 +31,37 @@ The `start_wifi` function is responsible for setting up and starting the Wi-Fi c
|
||||
```rust
|
||||
|
||||
pub async fn start_wifi(
|
||||
wifi_init: &'static EspWifiController<'static>,
|
||||
esp_wifi_ctrl: &'static EspWifiController<'static>,
|
||||
wifi: esp_hal::peripherals::WIFI,
|
||||
mut rng: Rng,
|
||||
spawner: &Spawner,
|
||||
) -> &'static Stack<'static> {
|
||||
let (wifi_interface, controller) =
|
||||
esp_wifi::wifi::new_with_mode(&wifi_init, wifi, WifiStaDevice).unwrap();
|
||||
) -> Stack<'static> {
|
||||
let (controller, interfaces) = esp_wifi::wifi::new(&esp_wifi_ctrl, wifi).unwrap();
|
||||
let wifi_interface = interfaces.sta;
|
||||
let net_seed = rng.random() as u64 | ((rng.random() as u64) << 32);
|
||||
|
||||
let dhcp_config = DhcpConfig::default();
|
||||
let net_config = embassy_net::Config::dhcpv4(dhcp_config);
|
||||
|
||||
let (stack, runner) = mk_static!(
|
||||
(
|
||||
Stack<'static>,
|
||||
Runner<'static, WifiDevice<'static, WifiStaDevice>>
|
||||
),
|
||||
embassy_net::new(
|
||||
wifi_interface,
|
||||
net_config,
|
||||
mk_static!(StackResources<3>, StackResources::<3>::new()),
|
||||
net_seed
|
||||
)
|
||||
// Init network stack
|
||||
let (stack, runner) = embassy_net::new(
|
||||
wifi_interface,
|
||||
net_config,
|
||||
mk_static!(StackResources<3>, StackResources::<3>::new()),
|
||||
net_seed,
|
||||
);
|
||||
|
||||
spawner.spawn(connection_task(controller)).ok();
|
||||
spawner.spawn(net_task(runner)).ok();
|
||||
|
||||
wait_for_connection(stack).await;
|
||||
|
||||
stack
|
||||
}
|
||||
|
||||
|
||||
async fn wait_for_connection(stack: Stack<'_>) {
|
||||
println!("Waiting for link to be up");
|
||||
loop {
|
||||
if stack.is_link_up() {
|
||||
break;
|
||||
@ -74,8 +77,6 @@ pub async fn start_wifi(
|
||||
}
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
}
|
||||
|
||||
stack
|
||||
}
|
||||
```
|
||||
|
||||
@ -99,7 +100,7 @@ async fn connection_task(mut controller: WifiController<'static>) {
|
||||
_ => {}
|
||||
}
|
||||
if !matches!(controller.is_started(), Ok(true)) {
|
||||
let client_config = Configuration::Client(ClientConfiguration {
|
||||
let client_config = wifi::Configuration::Client(wifi::ClientConfiguration {
|
||||
ssid: SSID.try_into().unwrap(),
|
||||
password: PASSWORD.try_into().unwrap(),
|
||||
..Default::default()
|
||||
@ -114,7 +115,7 @@ async fn connection_task(mut controller: WifiController<'static>) {
|
||||
match controller.connect_async().await {
|
||||
Ok(_) => println!("Wifi connected!"),
|
||||
Err(e) => {
|
||||
println!("Failed to connect to wifi: {e:?}");
|
||||
println!("Failed to connect to wifi: {:?}", e);
|
||||
Timer::after(Duration::from_millis(5000)).await
|
||||
}
|
||||
}
|
||||
@ -124,7 +125,7 @@ async fn connection_task(mut controller: WifiController<'static>) {
|
||||
|
||||
```rust
|
||||
#[embassy_executor::task]
|
||||
async fn net_task(runner: &'static mut Runner<'static, WifiDevice<'static, WifiStaDevice>>) -> ! {
|
||||
async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) {
|
||||
runner.run().await
|
||||
}
|
||||
```
|
||||
|
Loading…
x
Reference in New Issue
Block a user