🆓
FreeRTOS(RTOS)上でRustアプリを作る環境構築法まとめ
はじめに
- 以前からRustのFFIに興味があったのと将来的には組み込みRustアプリプラットフォーム的なもの(https://zenn.dev/lowlvengineer/scraps/1cdd84cc98d923)を作りたくてその前準備のためにやってみました。
環境その他
- 構築した環境は以下のリポジトリに格納しました。
https://github.com/Embeded-ojisan/FreeRTOS_and_Rust - 使ったツールとそのversion
- bindgen(0.59.1)
- cc、ctyなど
- ターゲットとしてはlm3s6965evb(QEMU)を採用します。
- 採用した理由は以下であります。
- QEMUを使用可能
- FreeRTOS側にサンプルアプリが存在する
- 今後、Rustアプリを書く際に参考に
- 採用した理由は以下であります。
概要
- RTOS上でのRust開発環境を構築するための大まかな手順は以下であります。
- bindgenによりC言語のヘッダーからRustのコード(バインディング)を生成しRustとC言語のコードのつなぎの部分を生成
- RTOSとRustアプリのビルド設定
- 環境の立ち上げ
- アプリ開発
- 上記の手順の中でハマりやすい部分に絞ってこれから解説します。
bindgenによりC言語のヘッダーからRustのコードを生成
- bindgenとは
- C/C++のヘッダーを元にしてRustのコードを生成するツールであります。
- 以下リンクに記載のように手書きでC言語による下回りを書くことも可能ですがそこそこ手間になるため使ってみました。
- ハマりどころ①:別々にヘッダーのコードを生成するとコンフリクトが起きることも。
- FreeRTOSにはtask.hやlist.hなど複数のヘッダーファイルが存在する。その各々をRustのバインディングに変換してもいいのでは?と思うがうまくいかないです。
- 基本的にbindgenはヘッダーの中身を機械的にバインディングに変換します。そのため、ライブラリ共通の型定義などを各ヘッダーが展開する形式だと、各々の内容が機械的にRustに変換され、それらを取り込んでコンパイルする際にコンフリクトしてしまいます。それを避けるために以下のように変換したいヘッダーファイルを一度、あるヘッダーに集積し、それをbindgenに入力する方式にしないといけないです。
- ハマりどころ②:そのまま動かすとstdが入り込みます。
- 上記のようになっているためno_std環境で使用するためにはひと手間必要です。
- 調べると
--use-core
しろと出てくるが最近のbindgenはそうしてもstd::os:rawを追加します。 - そのため、
--ctypes-prefix cty
も追加する必要があります。
- 作成したバインディングは使う場所でinclude!マクロ等を使って紐づけを行います。
RTOSとRustアプリのビルド設定
- ここでC言語で書かれたFreeRTOSとRustのコードを繋ぐのがcc(https://docs.rs/cc/latest/cc/)というcrateである。
- 以下で記載されているccはbuild.rs内でC/C++のコードをコンパイルするのに便利なものであります。
- これを使ってFreeRTOSのコードをビルドする手続きをbuild.rsに記載することでいい感じにRust側とリンクしてくれます。
- クロスコンパイルさせたい場合も特別な設定は必要なく
.cargo/config.toml
内の設定を読んで実行してくれます。
Discussion