Open5
ESP32用Rustについてのメモ
ESP-IDFの各機能を使うためのライブラリはいくつかのクレートに分かれている。
-
esp-idf-hal: GPIOやADCなどのペリフェラル、delayなどの基本機能。
- embedded-hal(マイコンの種類を問わない標準化されたAPI)に準拠している
-
esp-idf-svc: 無線通信など
- WiFiの管理(モード変更、アクセスポイントへの接続など)はここ
- タイマなどに対する高水準なAPIや、ロギングなどの便利な機能も含まれている
-
esp-idf-sys: ESP-IDFのC関数をほぼそのままラップしたもの
- ESP-IDF特有のビルド時処理などもここに含まれる
- 直接
esp_idf_sys::
以下の関数を呼ぶことはなくても、必ず必要になる極めて重要なクレート。
- Rust標準ライブラリ(
std::
以下): PCではOSが提供するような機能(コンソールやスレッドなど)- ソケット通信はここ(標準の
std::net
を使用) - ESP-IDF向けの実装は主に、esp-rs/rustのUNIX向けstd実装の中に、
#[cfg(target_os = "espidf")]
の条件コンパイルで作られている。
- ソケット通信はここ(標準の
特別な設定をしなければmain関数はCore 0で動く。
Core 1にするにはsdkconfig.defaults
ファイルにCONFIG_ESP_MAIN_TASK_AFFINITY_CPU1=y
を追加(ESP-IDFと同じ)。
マルチタスクにはRust標準のstd::thread
を使う。これはUNIX系OSと同様のPOSIX Thread APIで実装されているが、実際にはFreeRTOS関数をラップしたもの。
優先度の設定や特定コアへの固定などはesp_idf_hal::task::thread::ThreadSpawnConfiguration
を使う。
これに値を設定してset
を呼ぶことでesp_pthread_set_cfg
が呼ばれ、その後作られるPOSIX Threadの設定を変えることができる。
ただしFreeRTOSタスクの名前(ThreadSpawnConfiguration
のname
フィールド)はC文字列(NULL終端)なので、次のように初期化する必要あり(once_cell使用)。
use once_cell::sync::Lazy;
use std::ffi::CString;
static TASK_NAME: Lazy<CString> = Lazy::new(|| CString::new("foo").unwrap());
fn main() {
...
ThreadSpawnConfiguration {
name: Some(TASK_NAME.as_bytes_with_nul()),
priority: 2,
..Default::default()
}
...
}
mDNSを使う場合、現在のESP-IDFではMDNS実装は外部コンポーネントになっているので、Cargo.tomlの設定で追加する必要がある。
参考: