NuttXというPOSIXに対応した組み込みOSをためしてみる

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

組み込み向けOSとして最近ちょっと話題になっているNuttXを動かしてみました。POSIXに対応しているので、UNIXを知っている人なら馴染みのある使い方ができるのが特徴です。STM32 F4 Discoveryという開発ボードを使って動かしてみたのでレポートします。

組み込みOS

以前、組み込み向けのOSとしてAmazon FreeRTOSを紹介しましたが、組み込み向けのOSは他にもいろいろな種類があります。 組み込み向けのOSは、規模や機能がピンキリで、単にスレッドを管理するモニター的な薄い軽量OSから、ちゃんとデバイスドライバーやシェルを装備したフル装備のものまであります。FreeRTOSは比較的軽量な部類に入ります。一方NuttXは、シェルや各種デバイスドライバ、ネットワーク、グラフィックスまで統合された高機能な組み込みOSです。最近はLinuxを使うことも多くなってきたように思いますが、Linuxほど大規模なOSを使いたくない場合の選択肢になるように思います。

最近、ソニーからSPRESENSEというMaker向けプロトタイピングボードが発売になりました。それに使われているOSがNuttXです。何か知見が役にたつかもしれません。

STM32 F4 Discovery

今回使用した開発ボードは、STMicroelectronicsのSTM32 F4 Discoveryです(2800円で秋月電子より購入可能)。

  • ARM Cortex-M4F
  • STM32F407VGT6 168MHz
  • Flash 1M, RAM 192kB
  • モーションセンサー、MEMSマイクロフォン、オーディオ出力搭載

NuttXをビルドする

NuttXを動かしてみるには、ターゲットに合わせてビルドする必要があります。そのためにまずはツール類を準備します。

ツールチェインを用意する

手元のmacOSに、Cortex-M4用のクロスコンパイラ他、必要なツールをbrewを使ってインストールします。gccのクロスコンパイラの他に、NuttXのコンフィギュレーションに使用するためのkconfigツールをインストールします。また、STM32 F4Discovery開発ボードへの書き込みを行うためのツールst-linkをインストールします。

$ brew tap PX4/homebrew-px4
$ brew update
$ brew install gcc-arm-none-eabi
$ brew install kconfig-frontends
$ brew install st-link

NuttXを用意する

NuttXのソースコードをgithubからcloneします。NuttX本体と、アプリケーションが分離されており、それぞれ個別にリポジトリがあります。これれらを隣り合わせになるようcloneしておきます。

$ git clone https://bitbucket.org/nuttx/nuttx.git
$ git clone https://bitbucket.org/nuttx/apps.git

コンフィギュレーション

NuttXは、目的に合わせてコンフィギュレーションを行う必要があります。専用のスクリプトconfigure.shが用意されています。引数なしで実行すると、選択可能な設定とオプションが表示されます。対応しているプラットフォームや設定はとてもたくさんあります。設定はnuttx/configsディレクトリにありますので、ここを探すことも可能です。STM32 F4 Discoveryボードの設定も複数あります。

今回は、NuttXのシェルNutt Shellを試したいので、USB経由でシェルを使えるstm32f4discovery/usbnshを指定します。

$ cd nuttx
$ tools/configure.sh stm32f4discovery/usbnsh

さらに設定を編集することが可能です。今回はmacOSでビルドするための設定を行います。

$ make menuconfig

メニュー画面が現れますので、Build Option->Build Host PlatformとしてmacOSを指定します。

実はmacOSを使用してビルドすることは、configure.shスクリプトに-mオプションを指定することでもOKです。

$ tools/configure.sh -m stm32f4discovery/usbnsh

ビルド

あとはmakeするだけです。

$ make
...snip...
AR:   stm32_boot.o stm32_autoleds.o stm32_buttons.o
LD: nuttx
CP: nuttx.hex
CP: nuttx.bin

ファームウェアを書き込む

.binファイルができたら、STM32 F4 Discoveryボードに書き込みます。Mini USBケーブルを接続します。

USBで接続したら、下記コマンドで書き込みます。

$ st-flash write nuttx.bin 0x8000000

USBでシェルに接続する

書き込みが成功したら、もう一つのUSBポートに、micro USBケーブルを接続します。

USBデバイスとして認識することを確認します。

$ ls /dev/cu.usbmodem1
/dev/cu.usbmodem1

デバイスが確認できたら、screenコマンドで接続します。bpsは115200を指定します。Enterもしくは、ボード上のResetボタンを押すとプロンプトが表示されます。

$ screen /dev/cu.usbmodem1

NuttShell (NSH)
nsh> 

無事プロンプトが表示されたら、helpでコマンド一覧を表示させてみます。

nsh> help
help usage:  help [-v] [<cmd>]
  [           cmp         false       mkdir       rm          true        
  ?           dirname     free        mh          rmdir       uname       
  basename    dd          help        mount       set         umount      
  break       df          hexdump     mv          sh          unset       
  cat         echo        kill        mw          sleep       usleep      
  cd          exec        ls          ps          test        xd          
  cp          exit        mb          pwd         time        
Builtin Apps:

見覚えのあるコマンドがちらほらとあります。試してみましょう。

nsh> ls
/:
 dev/
 proc/
nsh> uname
NuttX
nsh> ps
  PID PRI POLICY   TYPE    NPX STATE    EVENT     SIGMASK   STACK COMMAND
    0   0 FIFO     Kthread N-- Ready              00000000 000000 Idle Task
    1 100 FIFO     Task    --- Running            00000000 002028 init
nsh> echo Hello
Hello
nsh> free
             total       used       free    largest
Umem:       191664       9280     182384     123936

普通にUnixのシェルに近い感覚で使えます。psではスレッドが、freeの結果から180kByteほどの空きメモリがあることがわかります。

なんといってもシェルが使えるのは心強いです。開発に際しての試行錯誤において、パラメータを変えたり、ログを確認したりと、とても強力なツールとなります。しかも手に馴染んだPosixなので、リダイレクトなどのファイル操作がそのまま使えてしまうのは素晴らしいですね。

YouTubeチャネル

NuttXのドキュメントはそれなりに整備されていますが、対応範囲が広いのでドキュメントが多くて迷います。基本的な使い方であればYouTubeにNuttXチャネルがあり、これの解説が分かり易いです。英語ですが、字幕も出ますし、難しいことは何も無いので大丈夫です。

まとめ

Posix対応の組み込みOSであるNuttXをビルドして、STM32F4 Discoveryボードで動かすための手順を試してみました。対応している開発ボードで動かしてみる簡単にできました。

今回やってみたのはもっとも基本的な動作だけですが、この他にも、USBメモリをマウントしたり、RAMFSを作成したり、ELFフォーマットの外部コマンドを実行するなどが可能なようです。組み込みOSにしては相当に高機能です。またUSB経由のTCP/IPネットワーク接続も可能なようです。

ソースコードを探検してみると、センサや周辺チップ用のドライバがかなりの数用意されています。YouTubeチャネルには、基本的な活用方法が短い動画にまとめれらて、数多くアップロードされています。基本的な使い方を知るには最適かと思います。

参考