Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ベアメタル向け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. 自己紹介 •井田 健太 (@ciniml) •仕事:FPGAの論理設計 •使用言語:C++, SystemVerilog, Rust, C# •組込みRust本の1割くらい書きました

    (サンプルアプリ作ったり、デバッガ試したり)→ 2021/10/24 ベアメタル向けRust std クレートの実装調査 2
  2. stdクレートが提供する機能 2021/10/24 ベアメタル向けRust std クレートの実装調査 •process - プロセス操作 •thread -

    スレッド操作 •fs - ファイル操作 • path - パス操作 •net - TCP/UDP通信 •io - I/O関連 4
  3. no_stdの難点 2021/10/24 ベアメタル向けRust std クレートの実装調査 • stdクレートの提供する機能が使えない • stdクレートに依存しているクレートが使えない (e.g.

    ネットワーク周りなど) • no_std対応クレートのみ使用可 • 一方、stdクレートの機能は ベアメタルの組込みシステムでも一般的な機能 • ファイル操作 • TCP/UDP通信 • スレッド (タスク) • RTOSがある場合 5
  4. 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
  5. stdクレートの依存関係 2021/10/24 ベアメタル向けRust std クレートの実装調査 • I/O周り • 大体のプラットフォームで libc

    クレートにあるlibcが提供する関数を使って実装されて いる • net周り • 大体socket APIで実装されている • thread周り • OS依存 • POSIX向け - pthreads • つまり、libc, socket, pthreadsがある環境であれば それぞれの部分は比較的容易に実装可能…なはず 8
  6. ESP32の開発環境 2021/10/24 ベアメタル向けRust std クレートの実装調査 •ESP-IDF • ESP32シリーズ向けの公式フレームワーク • C/C++で開発可能

    • FreeRTOS, lwIP, mbedtlsを含む • libcとしてnewlibを使用 • pthreadsにある程度対応 • C++11のthread対応のために元々実装されていた。 • FreeRTOSの機能で実装 10
  7. 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
  8. 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
  9. 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
  10. 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
  11. stdクレート実装を眺めた雑感 2021/10/24 ベアメタル向けRust std クレートの実装調査 •思ったよりも実装量は多くなさそう • libc, lwIP, pthreadsがあれば

    • unixモジュールに対してひたすら条件分岐追加 • それ以外の場合は対応した実装が必要 •使いたいプラットフォーム向けの実装をしてみたい • ESP32向けは既に公式で出たので… 16