Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
組込みRustでも でかい?JSONを扱いたい!
Search
Kenta IDA
June 07, 2023
Technology
3
1.3k
組込みRustでも でかい?JSONを扱いたい!
520kBしかメモリが無いESP32環境上の組込みRustで、100kB弱のJSONを扱うために、JSONストリームパーサーを作ったお話です。
Kenta IDA
June 07, 2023
Tweet
Share
More Decks by Kenta IDA
See All by Kenta IDA
日本の家電とMatterの世界
ciniml
0
75
Matter開発環境をざっくり眺める
ciniml
0
1.8k
ATOMDisplay_DisplayModule_M5Stack_UG_2023_Tokyo.pdf
ciniml
1
1.7k
Rusty Stack-chanのすすめ
ciniml
0
600
Raspberry Pi Picoデバッガ使用のすすめ
ciniml
0
2.1k
ベアメタル向けRust stdクレートの実装調査
ciniml
2
760
ESP32でSORACOM Arcつないでみた
ciniml
2
1.3k
RustでCMSIS-DAP実装してみた。
ciniml
3
970
技書博初出展してみた
ciniml
0
410
Other Decks in Technology
See All in Technology
VCpp Link and Library - C++ breaktime 2025 Summer
harukasao
0
210
BigQuery Remote FunctionでLooker Studioをインタラクティブ化
cuebic9bic
2
190
成立するElixirの再束縛(再代入)可という選択
kubell_hr
0
510
Model Mondays S2E02: Model Context Protocol
nitya
0
150
Agentic Workflowという選択肢を考える
tkikuchi1002
1
200
Uniadex__公開版_20250617-AIxIoTビジネス共創ラボ_ツナガルチカラ_.pdf
iotcomjpadmin
0
140
IIWレポートからみるID業界で話題のMCP
fujie
0
620
OTFSG勉強会 / Introduction to the History of Delta Lake + Iceberg
databricksjapan
0
110
20250623 Findy Lunch LT Brown
3150
0
690
活きてなかったデータを活かしてみた話 / Shirokane Kougyou vol 19
sansan_randd
1
390
從四件事帶你見識見識 事件驅動架構設計 (EDA)
line_developers_tw
PRO
0
910
Amplifyとゼロからはじめた AIコーディング 成果と展望
mkdev10
1
340
Featured
See All Featured
Faster Mobile Websites
deanohume
307
31k
A Modern Web Designer's Workflow
chriscoyier
693
190k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
161
15k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.5k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
29
9.5k
Optimizing for Happiness
mojombo
379
70k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
43
2.4k
The Language of Interfaces
destraynor
158
25k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
46
9.6k
Mobile First: as difficult as doing things right
swwweet
223
9.7k
How GitHub (no longer) Works
holman
314
140k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
Transcript
組込みRustでも でかい?JSONを扱いたい! 2023-06-07 人工衛星の開発現場でLT大会
自己紹介 • 井田 健太 • おしごと:ESP32のファームウェアを書く ◦ まえはXilinx FPGAさわってました • seccamp2022,
2023 RISC-V CPU自作ゼミ講師 • twitter: @ciniml
最近の組込みRust環境 • ESP32系がアツい! • ESP32 ◦ Espressifの無線機能 (Wi-Fi + Bluetooth)
付きマイコン ◦ 通常の開発環境はC/C++ ▪ ESP-IDFというTCP/IPスタックや RTOS搭載環境が提供されている • 搭載製品いろいろ ◦ 液晶付きモジュールが多い。M5StackとかM5Stackとか https://shop.m5stack.com/products/m5stack-core2-esp32-iot-development-kit
ESP32の組込みRust環境(1) • ESP32にはいくつかの系統がある • ESP32-C3 ◦ CPUコアがRISC-Vの低コスト製品 • ESP32, ESP32-S3
◦ CPUコアがXtensaの高性能製品 ◦ デュアルコア構成 • RISC-Vはいいけど、Xtensaって何?🤔 ◦ Cadence (に買収されたTensilica) のカスタム可能CPUコア ◦ プロセッサの構成情報からコンパイラ・デバッガ・シミュレータを 生成してくれるシステムで使われているベースプロセッサ
ESP32の組込みRust環境(2) • Xtensaに(公式)LLVMバックエンドが無かったので Espressifが自前でLLVMとrustcをビルドして提供 • 導入:インストール用のツール espup が用意されており簡単 ◦ https://github.com/esp-rs/espup
◦ espup installを実行するだけ。 • (余談:2~3年前はめっちゃめんどくさかった)
作ってみたもの:Remo monitor on M5Paper • M5Paperという電子ペーパー付きのESP32ユニットに Nature Remo / Remo
Eの各種センサー情報を表示 • センサデータはRemo Cloud API経由で取れる https://nature.global/nature-remo/nature-remo-3/ https://nature.global/nature-remo-e/ https://shop.m5stack.com/products/m5paper-esp32-development-kit-v1-1- 960x540-4-7-eink-display-235-ppi Nature Cloud (on AWS) 温湿度 電力使用量 送信 温湿度 電力使用量 取得
Nature Remo Cloud APIの仕様 • Webサイト上でREST APIの仕様を公開 ◦ https://developer.nature.global/ •
https://api.nature.global/1/appliances にアクセスすると 家電の情報を含むJSONが降ってくる ◦ スマートメーターの電力取得に使う • https://api.nature.global/1/devices にアクセスすると デバイス情報を含むJSONが降ってくる ◦ デバイスが持っている温湿度計の情報取得に使う
JSONのサイズ • 一般ユーザー:数kBくらい? ◦ まあ普通にparseできそうやね • Nature社員:100kB弱 ◦ いろんなデバッグ用機器が繋がっててデカいのが返ってくる ◦
PCとかで扱う分には全く問題ないが … • ESP32には520kBしかRAMない… • TLS接続でも結構メモリを使うので余裕はそんなにない • 普通にメモリに置いてparseすると死ぬ
JSONのストリーム型パーサー? • Rust実装探したけどぱっと見使いやすそうなの見つからず ◦ みんなserde大好きですね • 仕方ないので練習がてら実装してみた ◦ https://github.com/ciniml/fuga-json-seq-parser/ ◦
json-seq-parserだと汎用的な名前すぎるので、fugaってつけといた!
JSONのストリーム型パーサーの仕様 • no_std ◦ ヒープ使わない • 極力省メモリ ◦ 理屈上はJSONのキーを保持できるバッファがあればいけるはず •
コールバック呼び出し ◦ 配列開始・終了 ◦ マップ開始・終了 ◦ キーまたは値 ◦ 参照を渡す(コピーしない) pub enum JsonNode<'a> { StartMap, EndMap, StartArray, EndArray, Key(JsonScalarValue<'a>), Value(JsonScalarValue<'a>), } FnMut(JsonNode<'node>) -> Result<ParserCallbackAction, CallbackError>
JSONのストリーム型パーサーの使い方 // バッファ256、スタック10でパーサー作成 let mut parser: Parser<256, 10> = Parser::new();
let mut file = File::open("data/devices.json").unwrap(); let mut reader = embedded_io::adapters::FromStd::new(&mut file); let mut indent_level = 0; loop { let result = parser .parse(&mut reader, |node| { match node { JsonNode::EndMap => indent_level -= 1, JsonNode::EndArray => indent_level -= 1, _ => {} } for _ in 0..indent_level { print!(" "); } match node { JsonNode::StartMap => println!("{{"), JsonNode::StartArray => println!("["), JsonNode::Key(v) => print!("{}: ", v), JsonNode::Value(v) => println!("{},", v), JsonNode::EndMap => println!("}},"), JsonNode::EndArray => println!("],"), } match node { JsonNode::StartMap => indent_level += 1, JsonNode::StartArray => indent_level += 1, _ => {} } DefaultParserCallbackResult::Ok(ParserCallbackAction::N othing) });
実装したもの 室温 (Remo 3) 湿度 (Remo 3) 瞬時電力 (Remo E
Lite)
実装してみた感想 • タグ付き共用体とパターンマッチ便利 ◦ パーサーのステートマシン書くのがとても楽 ◦ タプルに対するマッチができるので、複数条件をフラットに書ける ▪ 条件を網羅しやすい •
nom便利 ◦ Rustのパーサーコンビネーターcrate ◦ 適当に関数組み合わせたらパースできる ◦ 主にJSONの値のパースに使っている
宣伝 • Interface 2023年5月号は組込みRust特集 • M5StampC3を使った記事あり ◦ なんかページ数おかしい… (65ページ) 中林さん書きすぎw
• 組込みRust本もよろしくね! https://interface.cqpub.c o.jp/magazine/202305/ https://www.c-r.com/boo k/detail/1403
おわり