$30 off During Our Annual Pro Sale. View Details »

ベアメタル向けRust stdクレートの実装調査

Kenta IDA
October 24, 2021

ベアメタル向けRust stdクレートの実装調査

TOPPERS開発者会議2021のLTで発表した内容のスライドです。

Kenta IDA

October 24, 2021
Tweet

More Decks by Kenta IDA

Other Decks in Programming

Transcript

  1. ベアメタル向け
    Rust std クレートの実装調査
    TOPPERS開発者会議2021 LT 2021/10/24
    Kenta Ida (@ciniml)

    View Slide

  2. 自己紹介
    •井田 健太 (@ciniml)
    •仕事:FPGAの論理設計
    •使用言語:C++, SystemVerilog, Rust, C#
    •組込みRust本の1割くらい書きました
    (サンプルアプリ作ったり、デバッガ試したり)→
    2021/10/24
    ベアメタル向けRust std クレートの実装調査 2

    View Slide

  3. ベアメタルRust
    2021/10/24
    ベアメタル向けRust std クレートの実装調査
    •OSが無い環境 (ベアメタル) 向けのソフトウェアを
    Rustで開発する方法
    •OS機能に依存している std クレート無しでの開発
    • core, alloc クレートのみに依存
    • #[no_std]
    3

    View Slide

  4. stdクレートが提供する機能
    2021/10/24
    ベアメタル向けRust std クレートの実装調査
    •process - プロセス操作
    •thread - スレッド操作
    •fs - ファイル操作
    • path - パス操作
    •net - TCP/UDP通信
    •io - I/O関連
    4

    View Slide

  5. no_stdの難点
    2021/10/24
    ベアメタル向けRust std クレートの実装調査
    • stdクレートの提供する機能が使えない
    • stdクレートに依存しているクレートが使えない (e.g. ネットワーク周りなど)
    • no_std対応クレートのみ使用可
    • 一方、stdクレートの機能は
    ベアメタルの組込みシステムでも一般的な機能
    • ファイル操作
    • TCP/UDP通信
    • スレッド (タスク)
    • RTOSがある場合
    5

    View Slide

  6. stdクレートのベアメタル向け実装
    2021/10/24
    ベアメタル向けRust std クレートの実装調査
    •そもそもstdクレートが提供する機能が
    ベアメタル向けのフレームワークにあるのであれば
    stdクレートも実装できるはずでは?
    • というか、
    今日のメインセッションでSOLID向け実装されてましたね。
    • 今朝stdのソースを確認していて気づきました
    6

    View Slide

  7. stdクレートの構造
    2021/10/24
    ベアメタル向けRust std クレートの実装調査
    •各トップレベルのモジュールは
    sys, sys_common, os サブモジュールを使って実装
    • sys - 各プラットフォーム向けのstdクレート実装の実体
    • sys_common
    - 各プラットフォームで共通の処理の実装
    • socket APIによる通信処理など
    • os - OS固有の処理の実装
    ...
    ├── os
    │ ├── espidf
    │ ├── linux
    │ ├── solid
    │ ├── unix
    │ ├── vxworks
    │ ├── wasi
    │ └── windows
    ├── sys
    │ ├── common
    │ ├── itron
    │ ├── solid
    │ ├── unix
    │ ├── unsupported
    │ ├── wasi
    │ └── windows
    ├── sys_common
    │ ├── fs.rs
    │ ├── io.rs
    │ ├── net.rs
    │ ├── thread.rs
    ...
    7

    View Slide

  8. stdクレートの依存関係
    2021/10/24
    ベアメタル向けRust std クレートの実装調査
    • I/O周り
    • 大体のプラットフォームで libc クレートにあるlibcが提供する関数を使って実装されて
    いる
    • net周り
    • 大体socket APIで実装されている
    • thread周り
    • OS依存
    • POSIX向け - pthreads
    • つまり、libc, socket, pthreadsがある環境であれば
    それぞれの部分は比較的容易に実装可能…なはず
    8

    View Slide

  9. ESP32の開発環境
    2021/10/24
    ベアメタル向けRust std クレートの実装調査
    •ESP32
    • 中国Espressifが製造している無線機能付きMCU
    • ESP32 - CPUはXtensa LX6 (カスタム版rustcで対応)
    • ESP32-C3 - CPUはRISC-V RV32IMC
    9

    View Slide

  10. ESP32の開発環境
    2021/10/24
    ベアメタル向けRust std クレートの実装調査
    •ESP-IDF
    • ESP32シリーズ向けの公式フレームワーク
    • C/C++で開発可能
    • FreeRTOS, lwIP, mbedtlsを含む
    • libcとしてnewlibを使用
    • pthreadsにある程度対応
    • C++11のthread対応のために元々実装されていた。
    • FreeRTOSの機能で実装
    10

    View Slide

  11. ESP32のRust対応
    2021/10/24
    ベアメタル向けRust std クレートの実装調査
    • 2018年頃からLLVMをforkしてclang対応
    • LLVMはXtensaに対応していない
    • 有志がfork版LLVMをつかってrustcをXtensa対応
    • fork版LLVMの更新は継続中
    • 最新のLLVMに対応
    • upstreamにパッチを投げているが2021/5より進捗なし
    • RISC-V版ESP32 (ESP32-C3)登場後 stdクレート対応
    • 元々第3者による開発だったが、開発者はEspressifに入った模様
    • ESP-IDF向けだったので、Xtensa版でも動作する
    11

    View Slide

  12. ESP-IDF向けstdクレート
    2021/10/24
    ベアメタル向けRust std クレートの実装調査
    •newlibによるlibc機能
    unix向けに条件分岐を追加して対応
    • https://github.com/rust-lang/rust/pull/87666
    •libcクレートをESP-IDFのnewlib, lwIPに合わせて修正
    • https://github.com/rust-lang/libc/pull/2310
    12

    View Slide

  13. libcクレートの修正 (一部)
    2021/10/24
    ベアメタル向けRust std クレートの実装調査
    •newlib向け実装 (src/newlib) を修正
    • ESP-IDF向け実装を追加 (src/newlib/espidf)
    •lwIP向けに定義を分岐 (例: bind関数 → lwip_bind)
    #[cfg_attr(target_os = "espidf", link_name = "lwip_bind")]
    pub fn bind(fd: ::c_int, addr: *const sockaddr, len: socklen_t) ‐> ::c_int;
    cfg_if! {
    if #[cfg(target_os = "espidf")] {
    mod espidf;
    pub use self::espidf::*;
    13

    View Slide

  14. stdクレートの修正 (一部)
    2021/10/24
    ベアメタル向けRust std クレートの実装調査
    •processをサポートしないのでダミーの定義を追加
    impl Command {
    pub fn spawn(
    &mut self,
    default: Stdio,
    needs_stdin: bool,
    ) ‐> io::Result<(Process, StdioPipes)> {
    unsupported() // Unsupportedを返す
    }
    14

    View Slide

  15. stdクレートの修正 (一部)
    2021/10/24
    ベアメタル向けRust std クレートの実装調査
    •thread周り
    • スタックサイズなどが違うので条件分岐
    • sleepの実装を分岐
    #[cfg(target_os = "espidf")]
    pub fn sleep(dur: Duration) {
    let mut micros = dur.as_micros();
    unsafe {
    while micros > 0 {
    let st = if micros > u32::MAX as u128 { u32::MAX } else { micros as u32 };
    libc::usleep(st);
    micros ‐= st as u128;
    }
    }
    }
    15

    View Slide

  16. stdクレート実装を眺めた雑感
    2021/10/24
    ベアメタル向けRust std クレートの実装調査
    •思ったよりも実装量は多くなさそう
    • libc, lwIP, pthreadsがあれば
    • unixモジュールに対してひたすら条件分岐追加
    • それ以外の場合は対応した実装が必要
    •使いたいプラットフォーム向けの実装をしてみたい
    • ESP32向けは既に公式で出たので…
    16

    View Slide

  17. おしまい
    2021/10/24
    ベアメタル向けRust std クレートの実装調査 17

    View Slide