EspressifのTutorial; Embedded Rust on Espressif / HTTP client
Http Client - Embedded Rust on Espressif
エラーは、EspHttpRequestWriteにはsubmitというメソッドがないというもの
$ cargo build --target=riscv32imc-esp-espidf Compiling http-client v0.1.0 (espressif-trainings/intro/http-client) warning: unused imports: `Headers`, `RequestWrite`, `Response`, `Status`, `io::Read` --> src/main.rs:6:35 | 6 | client::{Client, Request, RequestWrite, Response}, | ^^^^^^^^^^^^ ^^^^^^^^ 7 | Headers, Status, | ^^^^^^^ ^^^^^^ 8 | }, 9 | io::Read, | ^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default warning: unused import: `EspHttpClientConfiguration` --> src/main.rs:12:48 | 12 | use esp_idf_svc::http::client::{EspHttpClient, EspHttpClientConfiguration}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `submit` found for struct `EspHttpRequestWrite` in the current scope --> src/main.rs:55:27 | 55 | let response = writer.submit()?; | ^^^^^^ method not found in `EspHttpRequestWrite<'_>` For more information about this error, try `rustc --explain E0599`. warning: `http-client` (bin "http-client") generated 2 warnings error: could not compile `http-client` due to previous error; 2 warnings emitted
サンプルソースは以下(抜粋;tutorialのままに作成)
use embedded_svc::{ http::{ client::{Client, Request, RequestWrite, Response}, Headers, Status, }, io::Read, }; fn get(url: impl AsRef<str>) -> anyhow::Result<()> { let mut client = EspHttpClient::new_default()?; let request = client.get(url.as_ref())?; let writer = request.into_writer(0)?; let response = writer.submit()?; Ok(()) }
Cargo.toml抜粋
[package] name = "http-client" version = "0.1.0" authors = ["Anatol Ulrich <anatol.ulrich@ferrous-systems.com>"] edition = "2018" resolver = "2"
EspHttpRequestWriteにメソッドが無いと怒られてるのだが、そもそも、EspHttpRequestWriteの定義が分からない。Gitで探しても見つけられず
Gitのembedded-svcを参照、Requestにsubmitメソッドは存在した。だから、、上位には存在すると。
embedded-svc/client.rs at master · esp-rs/embedded-svc · GitHub
先人のサンプルコード*1
let mut response = client.get(&url)?.submit()?; let mut body = [0_u8; 3048]; let read = io::try_read_full(&mut response, &mut body).map_err(|err| err.0)?; info!( "Body (truncated to 3K):\n{:?}", String::from_utf8_lossy(&body[..read]).into_owned() ); // Complete the response while response.read(&mut body)? > 0 {} Ok(()) }
先人のサンプルと、Tutorialのサンプルを参考に以下と書いたらエラーは解消した
fn get(url: impl AsRef<str>) -> anyhow::Result<()> { let mut client = EspHttpClient::new_default()?; let mut response = client.get(&url)?.submit()?; let mut body = [0_u8; 3048]; let status = response.status(); let mut total_size = 0; println!("response code: {}\n", status); Ok(()) }
ビルドできたので以下のコマンドで書き込み、そのままモニタリング
$ cargo espflash --monitor /dev/ttyACM0
以下の通り、200応答にはなった。
response code: 200
次はbody部の取得か・・・
body部の取得用メソッドがどうやってもコンパイルエラー解消できず一旦断念
■参考URL
esp-idf-svc/http_request.rs at master · esp-rs/esp-idf-svc · GitHub
GitHub - esp-rs/embedded-svc: Rust APIs and abstractions for various embedded services (WiFi, Network, Httpd, Logging, etc.)
ESP HTTP Client - ESP32 - — ESP-IDF Programming Guide latest documentation
esp-idf/esp_http_client_example.c at bb25d6abd3398d0f06fb09fdc9935b791f9344ff · espressif/esp-idf · GitHub
ESP32+Rustでネット接続している例(こちらはちゃんと動いている・・まぁプロの方々だし)
M5PaperでRemo/Remo Eのセンサデータを表示する - Nature Engineering Blog
embedded-svc http client esp32 rust - Google 検索
https://github.com/ivmarkov/rust-esp32-std-demo#flash
ESP-MQTT - ESP32 - — ESP-IDF Programming Guide latest documentation
defaultがnightlyになっているべき??
$ rustup toolchain list stable-aarch64-unknown-linux-gnu (default) nightly-2022-03-10-aarch64-unknown-linux-gnu
■追記
Espressifの公式Tutorialを見ているがどうもエラーが解消できず、Gitに置かれたdemoプログラムもエラーが出る。根本的な原因は、ライブラリの参照のところがよくわかっておらず、ソースにあるのになぜundefiedになってしまうのか?が分からない。Pythonだったらインすペクトして調べられるけど、Rustでそんなことできるのだろうか。。zennやQiita等には、Espressifでない人がESP32+Rustで動かしている例があるようなので、そちらを見ながらサンプルを動かすことにする。
Rust (std) on ESP32-C3 で OSC からシリアル LED (WS2812 / SK6812) を動かす
■追記
以下は正常にビルド、動作した
// https://github.com/ivmarkov/rust-esp32-std-demo git clone https://github.com/ivmarkov/rust-esp32-std-demo rustup install nightly export RUST_ESP32_STD_DEMO_WIFI_SSID=xxxxxx export RUST_ESP32_STD_DEMO_WIFI_PASS=yyyyy cargo build --target riscv32imc-esp-espidf espflash /dev/ttyACM0 target/riscv32imc-esp-espidf/debug/rust-esp32-std-demo espflash serial-monitor /dev/ttyACM0
うまく行った時の設定等
$ rustup show Default host: aarch64-unknown-linux-gnu rustup home: /home/sumi/.rustup installed toolchains -------------------- stable-aarch64-unknown-linux-gnu nightly-2022-03-10-aarch64-unknown-linux-gnu nightly-aarch64-unknown-linux-gnu (default) esp active toolchain ---------------- nightly-aarch64-unknown-linux-gnu (default) rustc 1.69.0-nightly (5b8f28453 2023-02-12) file: config.toml [build] target = "xtensa-esp32-espidf" [target.xtensa-esp32-espidf] linker = "ldproxy" [target.xtensa-esp32s2-espidf] linker = "ldproxy" [target.xtensa-esp32s3-espidf] linker = "ldproxy" [target.riscv32imc-esp-espidf] linker = "ldproxy" rustflags = ["-C", "default-linker-libraries"] [unstable] build-std = ["std", "panic_abort"] [env] ESP_IDF_VERSION = "release/v4.4" ESP_IDF_SDKCONFIG_DEFAULTS = "sdkconfig.defaults;sdkconfig.defaults.esp32;sdkconfig.defaults.esp32s2"
バイナリのサイズを確認
sumi@sumi:~/lang/rust/tutorial/rust-esp32-std-demo$ size target/riscv32imc-esp-espidf/release/rust-esp32-std-demo text data bss dec hex filename 1178686 288400 1195338 2662424 28a018 target/riscv32imc-esp-espidf/release/rust-esp32-std-demo sumi@sumi:~/lang/rust/tutorial/rust-esp32-std-demo$ size target/riscv32imc-esp-espidf/debug/rust-esp32-std-demo text data bss dec hex filename 1295394 439472 1326410 3061276 2eb61c target/riscv32imc-esp-espidf/debug/rust-esp32-std-demo
WSL上のUbuntuは以下でビルド(リソース不足なのか途中で止まるのだが)
rustup install nightly cargo install ldproxy git clone https://github.com/ivmarkov/rust-esp32-std-demo cd rust-esp32-std-demo rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu cargo build --target riscv32imc-esp-espidf