Rustをフル活用したリアルタイムOS「Tock」の特異性リアルタイムOS列伝(18)(3/3 ページ)

» 2021年12月27日 10時00分 公開
[大原雄介MONOist]
前のページへ 1|2|3       

アプリケーション開発はC/C++をサポート

 そんなわけで、カーネルそのものはRustで記述されているが、アプリケーションはRust以外にC/C++もサポートしている(というか、さすがにアプリケーション開発までRustにすると、開発者が付いてこられないことを懸念したようだ)。

 この結果として、例えばLチカのサンプルコードは、Rustであれば以下のように記述できる(リスト1)。

#![no_std]
use libtock::result::TockResult;
use libtock::timer::Duration;
libtock_core::stack_size! {0x400}
#[libtock::main]
async fn main -> TockResult<> {
    let mut drivers = libtock::retrieve_drivers?;
    let leds_driver = drivers.leds.init_driver?;
    let mut timer_driver = drivers.timer.create_timer_driver;
    let timer_driver = timer_driver.activate?;
    // Blink the LEDs in a binary count pattern and scale
    // to the number of LEDs on the board.
    let mut count: usize = 0;
    loop {
        for led in leds_driver.leds {
            let i = led.led_num;
            if count & (1 << i) == (1 << i) {
                led.on?;
            } else {
                led.off?;
            }
        }
        count = count.wrapping_add(1);
        // This delay uses an underlying timer in the kernel.
        timer_driver.sleep(Duration::from_ms(250)).await?;
    }
}
リスト1 Rustで記述したTock向けのLチカのサンプルコード

 一方、組み込み開発の技術者がなじみ深いであろうCで記述すると以下のようになる(リスト2)。

#include <led.h>
#include <timer.h>
int main(void) {
  // Ask the kernel how many LEDs are on this board.
  int num_leds;
  int err = led_count(&num_leds);
  if (err < 0) return err;
  // Blink the LEDs in a binary count pattern and scale
  // to the number of LEDs on the board.
  for (int count = 0; ; count++) {
    for (int i = 0; i < num_leds; i++) {
      if (count & (1 << i)) {
        led_on(i);
      } else {
        led_off(i);
      }
    }
    // This delay uses an underlying timer in the kernel.
    delay_ms(250);
  }
}
リスト2 Cで記述したTock向けのLチカのサンプルコード

 筆者もRustにはあまりなじみがないので、Cで記述できるのは正直有り難い。

 ところで、コードサイズは先に図8で示したが、性能はどうなっているかというと、SOSP 17の資料から抜粋すると図12の通りになる。Deep Sleepに入っていると2ms台を要するのはさすがにどうしようもないが、アクティブモードであればISRが1μs未満、カプセルまで2.03μsだからこれはそう悪くない数字だと思われる。

図12 図12 Deep Sleepの場合、説明にもあるがそもそも処理が再開するまでに2ms以上かかるので、これはTockの側ではどうしようもない[クリックで拡大]

 TockがサポートしているターゲットはArm Cortex-M(M0/M0+/M3/M4/M7)という話だったが、TockのGitHubを確認すると、RISC-V(RV32i)も追加されているようだ。逆に、それ以外のアーキテクチャには未対応である。

 開発ボードとしては25種類ほどが挙がっている。センサーやネットワークに関しては、開発ボードの中にそれらのドライバまで搭載されている格好だが、温度センサーおよびBLE、USBはともかく、それ以外のものについてはまだこれから、といった感じである。ただし、積極的に開発は行われており、Tockそのものは2021年8月にVersion 2.0がリリースされており、いろいろと対応ボードが増えたのもこのタイミングである(RISC-VのサポートはVersion 1.4で初めて入ったが、2.0でかなり充実した)。現時点ではまだlibtock-cのみがサポートで、libtock-rsはまだ開発途中ということなので、Rustでのアプリケーション開発はTock 1.5を使うか、もしくはTock 2.1まで待つ必要があるだろう。

 ちなみにTockはApache 2.0 LicenseとMIT Licenseのデュアルライセンスになっており、好きな方を使うことができる。そういう意味では商用として使う際のライセンス上の問題はない。ただデバイスのサポートという観点で言えば結構限られているので、標準的でない環境で利用するためには自身でドライバ類を記述しなければならない(それもRustで)ケースが多いだろう。それもあってか、研究プロジェクトで使われる(それもRust絡みで紹介される)ことが多いのが現状ではある。

 ただし、Signpost Projectのような、研究とは言っても大規模なものに利用されたケースもあるので、研究室レベルでとどまるというわけでもない。商用に使えるか? というといろいろ工夫というか努力が必要そうではあるが、面白いRTOS実装の試みだと思う。

前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.