読者です 読者をやめる 読者になる 読者になる

mbed CLIでのコンパイルを楽にするシェルスクリプト

プログラミング mbed

はじめに

この記事はmbed Advent Calendar 2016の6日目の記事です。

mbed CLIがリリースされ、ローカル環境でのコンパイルが楽になりました。 しかし、コンパイルするときにボードを設定したり、コンパイルされたファイルが結構深い階層にあったりと、何度も手作業で繰り返すのは結構面倒です。 そこで一発でボードを自動的に判定し、mbedへのコピーまでやってくれるスクリプトを作ったので紹介します。

mbed CLI自体のインストールについては、既に日本語の記事がまとまっていますので、以下をご覧ください。

mbed CLI (コマンドライン・インタフェース)を Mac OS X で使ってみる | mbed

作ったスクリプト

#!/bin/bash

set -eu

PROGRAM_NAME=$(basename `pwd`)
MBED_DETECT=$(mbed detect | grep Detected | sed 's/,//g' | head -n 1)

if [ -z "${MBED_DETECT}" ];then
    echo "[info] No mbed boards are found."
    exit 1;
fi

TARGET=$(echo ${MBED_DETECT} | cut -d' ' -f3)
MBED_VOLUME=$(echo ${MBED_DETECT} | cut -d' ' -f7)

echo "[info] Target:"${TARGET}", Volume:"${MBED_VOLUME}

TOOL_CHAIN="GCC_ARM"

mbed compile --toolchain ${TOOL_CHAIN} --target ${TARGET}

BUILD_PATH=$(echo "BUILD/"${TARGET}"/"${TOOL_CHAIN}"/"${PROGRAM_NAME}".bin")
cp ${BUILD_PATH} ${MBED_VOLUME}/
echo "[info] Success to copy from "${BUILD_PATH}" to "${MBED_VOLUME}

適当な名前(compile.shなど)で保存し、$ bash compile.shとするか実行権限をつけて直接スクリプトを叩けば実行されます。

手元のLPC1768で試して動くことを確認しましたが、それ以外のボードでは未検証です。動かない場合は教えてください。

なおMacでしか動かないと思います(Linuxは動くかもですが)。

やっていること

mbed detectでターゲットとコピー先のボリュームを取得し、mbed compileで生成されたbinファイルをコピーしています。

mbed newmbed importするとディレクトリ名がbinファイルのファイル名となるので、それも利用しています。

複数のmbedがPCに接続されている場合はmbed detectで先頭になる1台に対してコピーが行われます。

mbed OS 5でのイベント処理(mbed events libraryの使い方)

電子工作 プログラミング mbed

はじめに

この記事はmbed Advent Calendar 2016の4日目の記事です。

mbed OS 5でイベント駆動なプログラムを書くためのライブラリ mbed-events-library の使い方を紹介します。 なお、ドキュメントに書いてあるコードは古いのか正常に動かないところがあったので、GithubのREADMEを参照して検証しました。

mbed-events-libraryが追加されたことで、従来の RtosTimer はdeprecated*1となったようです。

動かしてみる

青mbed(LPC1768)を使って実験しました。 p18 にPullUpでタクトスイッチをつけています。

1. 即実行されるイベント

EventQueueインスタンスを作成し、callメソッドを呼び出すことで即実行されるイベントを追加することができます。

dispatch メソッドを実行するとイベントループが廻り続けるため、最後に while(true) といった記述は必要ありません。

サンプルコードと実際の動作

#include "mbed.h"

DigitalOut led1(LED1);
InterruptIn sw1(p18);

// イベントキューを作成する
EventQueue queue;

// LEDのON/OFFを切り替える関数
void toggle_led() {
    led1 = !led1;
}

// タクトスイッチが押されたときに実行される関数
void pushed() {
    // 即実行されるイベント
    queue.call(&toggle_led);
}

int main() {
    // スイッチピンをPullUpにする
    sw1.mode(PullUp);

    // タクトスイッチが押されたときの割り込み処理
    sw1.fall(&pushed);

    // イベントループが廻り続ける
    queue.dispatch();
}

動作させたのが以下の動画です。スイッチを押すとLEDがON/OFFします。

f:id:mia_0032:20161203210614g:plain

2. 指定時間後に実行されるイベント

EventQueueインスタンスに対して call_in メソッドを呼び出すことで 指定ミリ秒後に実行されるイベントを作成することができます。

サンプルコードと実際の動作

先ほどのコードに queue.call_in(2000, &toggle_led); を追加し、ボタンを押してから2000ミリ秒(2秒)後に消える処理を追加しました。

#include "mbed.h"

DigitalOut led1(LED1);
InterruptIn sw1(p18);

// イベントキューを作成する
EventQueue queue;

// LEDのON/OFFを切り替える関数
void toggle_led() {
    led1 = !led1;
}

// タクトスイッチが押されたときに実行される関数
void pushed() {
    // 即実行されるイベント
    queue.call(&toggle_led);
    // 2000ms後に実行されるイベント
    queue.call_in(2000, &toggle_led);
}

int main() {
    // スイッチピンをPullUpにする
    sw1.mode(PullUp);

    // タクトスイッチが押されたときの割り込み処理
    sw1.fall(&pushed);

    // イベントループが廻り続ける
    queue.dispatch();
}

動作させたのが以下のようになります。スイッチを押すとLEDがONし、2秒後にOFFになります。

f:id:mia_0032:20161203210632g:plain

なお、ON/OFFするイベントをひたすらキューに積んでいる形になるため、連打するとON/OFFの順番は崩れます・・・

3. 指定時間ごとに定期実行されるイベント

EventQueueインスタンスに対して call_every メソッドを呼び出すことで 指定ミリ秒ごとに実行されるイベントを作成することができます。

サンプルコードと実際の動作

先ほどのコードからスイッチの処理を取り除き、call_every で1秒ごとに実行されるイベントを追加したものになります。

#include "mbed.h"

DigitalOut led1(LED1);

// イベントキューを作成する
EventQueue queue;

// LEDのON/OFFを切り替える関数
void toggle_led() {
    led1 = !led1;
}

int main() {
    // 1000msごとに定期実行するイベント
    queue.call_every(1000, &toggle_led);

    // イベントループが廻り続ける
    queue.dispatch();
}

動作させると以下のように、1秒ごとにLEDのON/OFFを繰り返します。

f:id:mia_0032:20161203210643g:plain

おわりに

今回のコードは以下のリポジトリに公開しています。 mbed import してお使いください。

github.com

以前、mbed OSのTechnical Preview版のときはMINARと呼ばれるイベントスケジューラーがあり、それを検証したことがありました。

そのときは結構な行数のコードが必要だったのですが、mbed-events-library は非常に簡潔なで直感的なコードで同様のことが実現できるようになったようです。

どんどん進化していますね。

GoogleCloudPub/Subのfluentdプラグイン fluent-plugin-gcloud-pubsub-customを作った

プログラミング fluentd Ruby

マネージド・メッセージ・キューのGoogle Cloud Pub/Subを利用するためのfluentdプラグインとしてfluent-plugin-gcloud-pubsub-customを作りました。

リポジトリは以下です。 github.com

もともと GitHub - mdoi/fluent-plugin-gcloud-pubsub というプラグインがあったものの、最近更新されていなさそうでしたのでforkして新しいプラグインとして公開しました。

元になったfluent-plugin-gcloud-pubsubから大きな変更点として以下があります。

  • google-cloud-rubyのバージョンアップに追随
  • Pub/Subの各種クォータの制限に対応
    • file bufferも使えるように lightening buffer への依存を排除しています。
  • formatter, parserプラグインに対応してjson形式以外も指定できるようにした
  • エラーハンドリングを改善
  • inputプラグインにHTTP RPCでメッセージのpullをstop, startできる機能を追加
    • デプロイ時や流量のコントロールなどに使えると思います。

使い方はREADMEを参照してください。

Pub/SubにはAttributeを付与できる機能があるので、Attributeにtagを入れて、pullするときはそれを使ってtagを付与できる機能を、そのうち実装したいと思っています。 forestプラグイン等でtopicをたくさん増やす必要がなくなって便利かなと。

しばらく自分でも使ってみて特に問題は発生していないですが、もし使ってみてバグや欲しい機能とかありましたら、何かでご連絡ください。

【10/30追記】

マルチスレッドでメッセージをpullできる機能をinput pluginに追加しました。