🆓

FreeRTOS(RTOS)上でRustアプリを作る環境構築法まとめ

2024/05/05に公開

はじめに

環境その他

https://github.com/Embeded-ojisan/FreeRTOS_and_Rust/blob/21511e03628abde896f7b31477856e7dcecba9d7/Cargo.toml#L1-L9

  • ターゲットとしてはlm3s6965evb(QEMU)を採用します。
    • 採用した理由は以下であります。
      • QEMUを使用可能
      • FreeRTOS側にサンプルアプリが存在する
        • 今後、Rustアプリを書く際に参考に

概要

  • RTOS上でのRust開発環境を構築するための大まかな手順は以下であります。
    • bindgenによりC言語のヘッダーからRustのコード(バインディング)を生成しRustとC言語のコードのつなぎの部分を生成
    • RTOSとRustアプリのビルド設定
    • 環境の立ち上げ
    • アプリ開発
  • 上記の手順の中でハマりやすい部分に絞ってこれから解説します。

bindgenによりC言語のヘッダーからRustのコードを生成

  • bindgenとは
  • ハマりどころ①:別々にヘッダーのコードを生成するとコンフリクトが起きることも。
    • FreeRTOSにはtask.hやlist.hなど複数のヘッダーファイルが存在する。その各々をRustのバインディングに変換してもいいのでは?と思うがうまくいかないです。
    • 基本的にbindgenはヘッダーの中身を機械的にバインディングに変換します。そのため、ライブラリ共通の型定義などを各ヘッダーが展開する形式だと、各々の内容が機械的にRustに変換され、それらを取り込んでコンパイルする際にコンフリクトしてしまいます。それを避けるために以下のように変換したいヘッダーファイルを一度、あるヘッダーに集積し、それをbindgenに入力する方式にしないといけないです。

https://github.com/Embeded-ojisan/FreeRTOS_and_Rust/blob/main/freertos/FreeRTOSheader.h#L1-L8

  • ハマりどころ②:そのまま動かすとstdが入り込みます。
    • 上記のようになっているためno_std環境で使用するためにはひと手間必要です。
    • 調べると--use-coreしろと出てくるが最近のbindgenはそうしてもstd::os:rawを追加します。
    • そのため、--ctypes-prefix ctyも追加する必要があります。

https://x.com/ciniml/status/1138258449068781571

https://github.com/Embeded-ojisan/FreeRTOS_and_Rust/blob/main/scripts/bindgen.sh#L1-L9

  • 作成したバインディングは使う場所でinclude!マクロ等を使って紐づけを行います。

https://github.com/Embeded-ojisan/FreeRTOS_and_Rust/blob/main/src/main.rs#L4-L8

RTOSとRustアプリのビルド設定

  • ここでC言語で書かれたFreeRTOSとRustのコードを繋ぐのがcc(https://docs.rs/cc/latest/cc/)というcrateである。
  • 以下で記載されているccはbuild.rs内でC/C++のコードをコンパイルするのに便利なものであります。
  • これを使ってFreeRTOSのコードをビルドする手続きをbuild.rsに記載することでいい感じにRust側とリンクしてくれます。

https://github.com/Embeded-ojisan/FreeRTOS_and_Rust/blob/main/build.rs#L1-L73

  • クロスコンパイルさせたい場合も特別な設定は必要なく.cargo/config.toml内の設定を読んで実行してくれます。

https://github.com/Embeded-ojisan/FreeRTOS_and_Rust/blob/main/.cargo/config.toml#L1-L7

参考資料

Discussion