Raspberry Pi PicoでNuttXを動かす


Raspberry Pi PicoでFreeRTOSを動かしたのに続いて、今度はNuttXというリアルタイムOSを動かしてみました。

NuttXとは

NuttXはPOSIX準拠のAPIを持つリアルタイムOSです。FreeRTOSはスケジューラといくつかのカーネル資源を管理するのみのごく小さなOSでしたが、NuttXはカーネル本体にライブラリ群、各種ファイルシステムやネットワークスタックなども備えた、かなり本格的なOSになっています。
ドローンのフライトコントローラであるPX4やソニーのボードコンピュータSPRESENSEなどでの採用例があります。

ビルド環境準備

Getting started with Raspberry Pi Picoに従って、Pico SDKのインストールとHello WorldのUART版をビルドして動作できるところまでの環境を準備します1

また、NuttXのビルド時にPico SDKのソースコードの一部を利用しているため、環境変数 PICO_SDK_PATH にPico SDKの位置を指定しておく必要があります2

私はこの記事で紹介したWindowsのWSL環境で開発しています。ラズパイ4のRaspberry Pi OSでのビルドも可能だと思いますが未確認です。逆に、Windowsネイティブ環境でのビルドはかなり面倒なことが予想されますので避けた方が良いと思います。

kconfigのビルドとインストール

NuttXのビルドでは、Linuxカーネルのビルドにも使われているkconfigをコンフィグレーションのために使用します。まずこれをビルドしてインストールします。

ビルドに必要なパッケージをインストールします。

$ sudo apt install bison flex gettext libncurses5-dev gperf automake-1.15 libtool pkg-config

kconfig-frontendsのソースコードを取得してビルド、インストールします。

$ git clone https://bitbucket.org/nuttx/tools.git
$ cd tools/kconfig-frontends/
$ ./configure --enable-mconf --disable-nconf --disable-gconf --disable-qconf
$ make
$ sudo make install
$ sudo /sbin/ldconfig

NuttXのコード取得とビルド

Raspberry Pi Pico対応コードは既に公式リポジトリマージされています。
公式リポジトリからソースコードを取得してビルドします。

$ git clone https://github.com/apache/incubator-nuttx.git nuttx
$ git clone https://github.com/apache/incubator-nuttx-apps.git apps
$ cd nuttx
$ ./tools/configure.sh raspberrypi-pico:nsh
$ make

ビルドが完了すると、ELFバイナリであるnuttxと、インストール用イメージのnuttx.uf2ができます。

Linuxカーネルのコンフィグレーションと同じように、make menuconfigでカーネルやアプリケーションのコンフィグレーションを行うことができます。

実行

nuttx.uf2は通常のPico SDKアプリと同様に、BOOTSELを押しながら接続したPicoのマスストレージデバイスにドラッグ&ドロップすることでインストールできます。
起動に成功すると以下のメッセージとプロンプトが表示されます。
(起動確認用にPico基板上のLEDも点灯させています)


NuttShell (NSH) NuttX-10.0.1
nsh>

NuttShell(NSH)は、NuttXのアプリケーションに標準で含まれているシェルです。
以下のように、かなりLinuxに近い感覚で使えることが分かると思います3

nsh> help
help usage:  help [-v] [<cmd>]

  .         cd        df        free      mkdir     printf    sleep     uname
  [         cp        echo      help      mkrd      ps        source    umount
  ?         cmp       env       hexdump   mh        pwd       test      unset
  basename  dirname   exec      kill      mount     rm        time      usleep
  break     date      exit      ls        mv        rmdir     true      xd
  cat       dd        false     mb        mw        set       truncate

Builtin Apps:
  sh      ostest  hello   nsh
nsh> ls
/:
 dev/
nsh> ls -l /dev
/dev:
 crw-rw-rw-       0 console
 crw-rw-rw-       0 null
 crw-rw-rw-       0 ttyS0
nsh> mkdir /proc
nsh> mount -t procfs /proc
nsh> ps
  PID PRI POLICY   TYPE    NPX STATE    EVENT     SIGMASK   STACK COMMAND
    0   0 FIFO     Kthread N-- Ready              00000000 001024 Idle Task
    1 100 RR       Task    --- Running            00000000 002036 init
nsh> uname -a
NuttX 10.0.1 6b83f6a8fe Feb 20 2021 21:13:38 arm raspberrypi-pico
nsh> free
                     total       used       free    largest
        Umem:       264400       7200     257200     257184
nsh>

  1. 現時点でPico版NuttXはUARTコンソールしかサポートしていないため、UART接続環境は必須です。 

  2. Getting Startedの記述だとなぜかpico-examplesからの相対パスを指定していますが、これはpico-sdkのある絶対パスにしておくべきです。 

  3. 現時点では動作するデバイスがUARTしかないので使えるアプリは限られますが、appsに含まれているBASICインタプリタやVIエディタ(クローン)なども、コンフィグを有効にすれば動作します。