組み込みプログラミング環境"mbed"はARM CPUを使った組み込み環境向けのもので、Arduinoとは別のエコシステム(笑)を作っている。mbedを用いることで、Arduino環境ではなかなか面倒だった
- もろもろのハードウェア割り込みをガンガン使ったコード
- 特定の組み込み用途により特化したコード
を書くことができるようになる。
STM32 nucleoシリーズのボードは、ARM CPUを使った簡易開発ボードの中でも一番廉価な部類に入る。Arduinoクローンと同じくらいの価格で手に入れることができるので、Arduino環境からも入りやすい気がする。
ここではMac上でmbed/nucleoの開発を行なう際のポイントと注意点をまとめておく。
ドライバ
公式には「Windows 7以降のみ対応」と書いてある。じっさい、Mbed上にはWindows用のファームウェアアップデートしか見当たらなかった。
ただ接続するとわかるけれど、最近のnucleo x 最近のMacなら、USBで接続すれば自動的にUSBストレージとして認識される。できたらファームウェアのアップデートもしておきたいけれど、まあ問題が生じるまではこのままでも大丈夫かな…。
mbed OSプログラムのビルド
ビルドはオンライン上で全て行われるMbed Compilerを使う方法と、オフラインでも使えるArm mbed toolsを使う方法がある。
mbed Compiler
USBストレージとして表示されたnucleoのディレクトリを開くとmbed.HTM
なるファイルがある。これがos.mbed.com
へのリンクになっていて、これを開くことで当該nucleoが「使用するデバイス」としてmbed Compilerに登録される(いちいち自分で対象のデバイス名を探したりしなくてよい)。
デバイスがひとつしかなければ、公開されているリポジトリで"Import into Compiler"を押すと、自動でそのnucleo向けの設定でプロジェクトが取り込まれる。
「コンパイル」ボタンでクラウド上でコンパイルが行われ、生成されたバイナリファイルがダウンロードできるようになる。
Arm mbed tools
コマンドラインから動くmbedツール群。使ったことがないので雰囲気しかわからない。オフラインで使えるという利便性に加えて、ターゲットとするデバイスやコンパイルオプションなどを自分で詳しく設定できる、というよさがあると思う。自分好みのIDEも使えるし。
mbed compile <options...>
でコンパイルが行われ、バイナリファイルが生成される。
プログラムのアップロード
ビルドすると.bin
という拡張子のバイナリファイルが生成されるので、これをnucleo USBストレージに保存する(オンラインのmbed Compilerを使っている場合は、直接保存先としてUSBストレージを指定してもよい)。
コピーが完了すると自動でデバイスがリセットされ、ブートローダが再起動する(Macだと「ディスクの不正な取り出し」的なメッセージが出てしまうけれど、nucleo側としては問題ないのでおそらく無視しても大丈夫)。Lチカ的なプログラムの場合、この段階で動いていることを確認できる。
注意点
USBストレージ上には、アップロードされたプログラムは表示されないので注意。
USB経由のシリアル通信
mbed OS上ではUSBTX
、USBRX
なるピンがあらかじめ定義されているので、mbedのSerial
クラスを用いて簡単にデバッグ用シリアルポートとして使うことができる(Serial_HelloWorldプロジェクト参照)。
デフォルトの設定は
- ボーレート9600
- 8データビット
- パリティなし
- 1ストップビット
の設定になっていると思う。もちろんこのあたりの設定はSerial
クラスから変更できる。
ホスト側からは/dev/tty.usbxxxx
(xxxxの部分はてきとうな数字)のような感じで見えているはず。
screenを利用した通信
これを
$ screen /dev/tty.usbxxxx 9600 -L
のような感じで開けば入出力をモニターできる(-L
でデバイスからの出力が見えるようになる)。screen
プログラムを終了するには、Ctrl-a
の後にk
(for "kill")をタイプする(Ctrl-a
がscreen
のエスケープシーケンスで、これでscreen
内部の通信モニターからscreen
そのものの操作に移れる)。
Arduinoアプリを利用した通信
screen
は強力だけれど、自分の入力した文字がエコーされない(はず…まだよくわからない)ので通信内容が不安になることがある。実のところシリアルコンソールであればなんでもよいので、たとえばArduinoのシリアルモニタをそのまま使ってやることもできる。
ツール
メニューのシリアルポート
のところでnucleoに対応したシリアルポートのパスを選択してやれば、シリアルモニタを開くことで通信ができる。
注意点
ホスト側のシリアルポートが開くたびにデバイスがリセットされるわけではないので注意(Leonardo系のArduinoと同じ)。シリアルポートを開くまでに通信を取りこぼしたくない場合は、たとえばホスト側からなんらかの通信があるまでデバイスを待たせる(シンプルにはgetchar()
などで)、などの対策が必要。
総括
いまいちどこにまとまった情報があるのかわからず、何かの問題にぶつかった時に、何が問題になっているのかを調べるのが大変で困る。それでも全体としては(何か祟りでもあるのではないかというレベルで)スムーズにプログラムできたので、とても便利な環境だと思う。