mbed cliをlinuxで構築してみた
これまで書いてきたマイコン記事の通り、ふだんの工作に使っているマイコンはARM mbedです。世の中で最も出回っているマイコンであり、安価で手に入りやすく、それでいてクラウドmbed環境はとても使いやすいからです。しかし日本ではPICやAVR(Arduino)に負けるらしく、日本語で情報を入手できにくい感があります。
今回オフラインコンパイラであるmbed OS 5のmbed CLI(コマンドラインインターフェイス)をLinux上に環境構築してみたので、備忘録代わりにブログに記してみます。STの安価なmbedボードであるNUCLEOシリーズをCLIでビルドする際、ハマってしまった点がいくつかあったのでその解決法も記してみます。
まずは、こちらのシステム環境です。
Ubuntu 16.04.3 LTS
Linux kernel 4.4.0-92-generic 64bit
GCC 5.4.0 20160609
Python 2.7.12
usbmountのインストール
USBをマウントして実行権付きで読み書きするパッケージをインストールします。
$sudo apt-get install usbmount
mbedボードをUSBポートに差し込んでUSBストレージとして認識させ、dfコマンドで見ると、/media/usb0などが見えるはずです。しかしこのままではファイルのユーザーがrootなので多少使いにくいです。そこで/etc/usbmount/usbmount.confを編集してみます。
MOUNTOPTIONS="sync,nodev,noatime,nodiratime" FS_MOUNTOPTIONS="-fstype=vfat,uid=yuji,gid=yuji"
この2箇所を書き換えると実行権が自分のものになるので使いやすくなります(あくまで個人環境で使う場合の設定です)。
Python 2.7を入れる
mbedはpythonのスクリプトを多用するので入ってなければPythonを入れておきます。デフォルトでpython3が動く環境だとエラーになるので注意して下さい。Pythonのモジュールインストーラーであるpipも使うので、
$sudo apt-get install python2.7 python-pip
としておきます。続いてmbed cliをpipでインストール。
$sudo pip install mbed-cli
ARM GCC, mercurial, gitをインストール
ツールチェーンであるARM GCC、レポジトリ管理のMercuialと必要ならばGitも入れておきます。
$sudo apt-get install gcc-arm-none-eabi mercurial git
Lチカのプロジェクトを作ってコンパイル
定番テストプログラムである「Lチカ」を動かしてみましょう。オンラインのmbed IDEと同様プロジェクトとしてディレクトリを用意しておきます。
$mkdir mbed-test $cd mbed-test $mbed new .
ここでmbed-osのすべてのライブラリをgithubからダウンロードしてくるので結構時間がかかります。
次に、ここのフォルダでUSBにマウントされているmbedボードを認識させます。ここではSTのNucleo F411REをつなげてみた例です。
$mbed detect [mbed] Detected NUCLEO_F411RE, port /dev/ttyACM0, mounted /media/usb0 [mbed] Supported toolchains for NUCLEO_F411RE +---------------+-----------+-----------+-----------+-----------+-----------+-----------+ | Target | mbed OS 2 | mbed OS 5 | ARM | GCC_ARM | IAR | ARMC6 | +---------------+-----------+-----------+-----------+-----------+-----------+-----------+ | NUCLEO_F411RE | Supported | Supported | Supported | Supported | Supported | Supported | +---------------+-----------+-----------+-----------+-----------+-----------+-----------+ Supported targets: 1 Supported toolchains: 4
もしNucleo 4xxを使っていて正しく認識されないようならば、ST-LINKをファームアップしてみて下さい。mbedのページあります。Windows機でST-LINKで接続し(場合によって最新のデバイスドライバが必要かも。場所は先のリンクにあります)、Windows上のファームアップソフトを立ち上げてファームアップできます。
また、この時点で、
[mbed] Auto-installing missing Python modules...
と表示されたら、足りないPythonモジュールがあるようなので、追加で入れておきます。
$sudo pip install -r mbed-os/requirements.txt
まだプロジェクトにプログラムの中身が無いので、Lチカのmain.cppを作っておきます。
#include <mbed.h> DigitalOut led1(D13); int main() { led1 = 1; while(1) { led1 = !led1; wait(0.1); } }
D13ピンにLEDのアノードを接続、GNDにカソードを接続しておきます。モジュールとツールチェインの設定を済ませて、ようやくビルドへ。
$mbed target NUCLEO_F411RE $mbed toochain -G GCC_ARM $mbed compile
設定とソースに誤りがなければ、
Building project mbed-test (NUCLEO_F411RE, GCC_ARM) Scan: . Scan: mbed Scan: env Compile [ 5.8%]: TimerEvent.cpp Compile [ 6.1%]: Timeout.cpp Compile [ 6.4%]: Timer.cpp ・ ・ ・ Compile [ 99.7%]: stm_spi_api.c Compile [100.0%]: test_env.cpp Link: mbed-test Elf2Bin: mbed-test +------------------+-------+-------+------+ | Module | .text | .data | .bss | +------------------+-------+-------+------+ | [fill] | 115 | 4 | 11 | | [lib]/c.a | 17219 | 2472 | 89 | | [lib]/gcc.a | 3120 | 0 | 0 | | [lib]/misc | 252 | 16 | 28 | | main.o | 80 | 4 | 28 | | mbed-os/drivers | 136 | 4 | 100 | | mbed-os/hal | 863 | 0 | 26 | | mbed-os/platform | 1246 | 4 | 270 | | mbed-os/rtos | 8539 | 180 | 5988 | | mbed-os/targets | 6102 | 4 | 820 | | Subtotals | 37672 | 2688 | 7360 | +------------------+-------+-------+------+ Total Static RAM memory (data + bss): 10048 bytes Total Flash memory (text + data): 40360 bytes Image: ./BUILD/NUCLEO_F411RE/GCC_ARM/mbed-test.bin
と表示されbinファイルが生成されます。このファイルをmbedにコピーすれば完了。
$cp ./BUILD/NUCLEO_F411RE/GCC_ARM/mbed-test.bin /media/usb0
無事にLチカが動くはずです。
NUCLEO F746ZGでは最新のtoolchainが必要!
別のmbedボードにつなぎ直して動作するか確かめていたところ、mbed OS 5に対応のSTMのNucleo F746ZGでは、うまくコンパイルできませんでした。
$mbed target NUCLEO_F746ZG $mbed compile ・ ・ ・ /usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/bin/ld: error: /usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/libc.a(lib_a-setjmp.o): Conflicting CPU architectures 13/1 /usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/bin/ld: failed to merge target specific data of file /usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/libc.a(lib_a-setjmp.o) collect2: error: ld returned 1 exit status [ERROR] /usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/bin/ld: error: /usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/libc.a(lib_a-setjmp.o): Conflicting CPU architectures 13/1 /usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/bin/ld: failed to merge target specific data of file /usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/libc.a(lib_a-setjmp.o) collect2: error: ld returned 1 exit status
リンカの設定がおかしいの?pythonもモジュールがおかしいのか?いろいろ悩んだり調べてみた挙句、最新のGCC Toolchainを使えば治るっぽいことがわかりました。早速、GNU ARM Embedded Toolchainのページへ行ってLinux版のライブラリをダウンロードしてきました。
これをbunzip2+tarで展開し、展開場所が/usr/localだとすると、そこにパスを通しておくのを忘れずに。
$mbed config -G GCC_ARM_PATH="/usr/local/gcc-arm-none-eabi-6-2017-q2-update/bin"
とし、compileをかけると、
$mbed compile ・ ・ ・ Compile [100.0%]: test_env.cpp Link: mbed-test Elf2Bin: mbed-test +------------------+-------+-------+-------+ | Module | .text | .data | .bss | +------------------+-------+-------+-------+ | [fill] | 104 | 4 | 19 | | [lib]/c.a | 17219 | 2472 | 89 | | [lib]/gcc.a | 3120 | 0 | 0 | | [lib]/misc | 252 | 16 | 28 | | main.o | 80 | 4 | 28 | | mbed-os/drivers | 136 | 4 | 100 | | mbed-os/features | 44 | 0 | 12556 | | mbed-os/hal | 863 | 0 | 26 | | mbed-os/platform | 1246 | 4 | 270 | | mbed-os/rtos | 8809 | 180 | 5988 | | mbed-os/targets | 9727 | 4 | 1084 | | Subtotals | 41600 | 2688 | 20188 | +------------------+-------+-------+-------+ Total Static RAM memory (data + bss): 22876 bytes Total Flash memory (text + data): 44288 bytes Image: ./BUILD/NUCLEO_F746ZG/GCC_ARM/mbed-test.bin
mbed CLIを使ってみて
mbed OS 5に対応していないとダメなのが残念ですが、使い慣れたLinux上のCエディタ(Emacs)でサクサクとコードが書けるのが快適です。mbed OS 5に対応しているNucleoのようなボードでソースのトライアンドエラーを済ませて、またオンラインコンパイラに戻って古いmbedボードを動かす、というのも悪くないと思っています。しかし、mbed-osを一々ダウンロードしてくるのには閉口しました・・・^^;まだまだ洗練度が足りない感じですね。
Windowsにもオフラインコンパイラがほしいですが、CLIではなくWindowsらしくEclipseで動かしてみたいと思います。