みかんのゆるふわ技術ブログ

Raspberry PiやIoT関係のことを書き残していきます

マイコンで動くIoT向けオープンソース組み込みOS 6種類を比較!

f:id:kimura_khs:20210404174819p:plain:w400

Raspberry Piはパソコンやサーバーと同じLinuxが動きます。 一方で、IoTの末端になるデバイスの中には、Linux Kernelすら動作しない安いマイコンで動くものもたくさんあります。

そういった機器ではどんなOSが使われているのでしょうか?

ここでは安いマイコンでも動かせる組み込みOSと呼ばれるものを紹介します。

商用のものは私は詳しくないので、特にIoTに向いた次のオープンソース組み込みOS6種類を紹介します!

私はインストール厨なので、程度はともかくとして、この6種類はどれも使ったことがあります😎

Zephyr OS

私の中での組み込みOS注目度ランキングNo.1🥇を誇るOSがこちら(個人の感想です)、その名も、ゼフィロス!!じゃなかった、Zephyr OS(ゼファーオーエス)です!!

zephyrproject.org

2015年からの比較的新しいプロジェクトですが、多くのマイコンメーカーが開発に参加しており、急速に成長中の強力でモダンな組み込みOSです。

ちなみにゼフィロス(Zephyros)とは、ギリシャ神話で風をつかさどる神様だそうで、このOSの名前もこの神様に由来します。

特徴

Linux Foundationがホストしているからか、どことなくLinux Kernelの開発環境っぽい感じがします。 Device Treeでのボード定義、KconfigでのコンフィグレーションなどLinux Kernel開発由来の手法が導入されています。

カーネルとしてはプリエンプティブなマルチスレッドにも対応しています。優先度ベースのスケジューリングもできます。 セマフォやミューテックス、メッセージキューなどのスレッド間通信手段も、もちろんいろいろ用意されています。

コンフィグレーションが柔軟にでき、どんなプロトコルスタックを搭載するか、シングルスレッドにするかマルチスレッド対応にするか、など基本的なところから細かいことまで多くの項目をメニュー形式で設定でき、すぐにアプリケーション開発が始められるようになっています。

Nordic、NXP、Intelを中心として幅広いマイコンメーカーも開発に参加しています。オープンソースハードウェアメーカーのAdafruitも開発に参加しているみたいです。その他、Google、Facebookなどもスポンサーになっているなど、有力な企業が開発に参加しており安心感があります☺️

Apacheライセンスで商用にも使いやすいオープンソースOSです。

対応マイコン、通信プロトコル

対応CPUはCortex-M、Cortex-Aシリーズ、x86、RISC-Vをはじめとする32bit/64bitCPUに対応しています。8bit/16bit CPUには対応していないようです。

これらのCPUを搭載した、LPC、nRF52、STM32、SAMDなど多くのマイコンに対応しています。 STM32 Nucleoシリーズ、BBC micro:bit、Seeeduino XIAOなどお手軽に買える開発ボードにも対応しています。 また、Linux上でアプリとしてZephyr OSを動かすこともできます。

センサーなどの周辺デバイスもたくさんサポートされており、以前の記事で紹介した温湿度気圧センサーBME280や、明るさセンサーMAX44009もドライバーがあります。

TCP/IP、IPv6、Bluetooth Low Energy、BLE Mesh、OpenThread、HTTP、MQTT、CoAPをはじめ、様々なプロトコルスタックが含まれているので、IoTの開発にも向いています。特にプロトコルスタックの充実ぶりは素晴らしいです✨

開発環境

開発環境はwestという独自コマンドラインツールや、Kconfigでのコンフィグレーション、Device Treeでのボード定義など、Linux Kernel開発環境由来の独特なものが多くなっています。

ファームウェアのビルドはアプリケーションのフォルダに移動して、

$ west build -b seeeduino_xiao

などとターゲットボードを指定して行います。実機への書き込みもwestからできます。さらに、

$ west build -t menuconfig

とすると、

f:id:kimura_khs:20210411224130p:plain:w480

このようなメニュー形式の画面が出てきて、Kconfigでいろんな機能の有効/無効を設定できます。 Linux Kernelのコンフィグレーションでおなじみの機能ですね。

特に商用開発では、ほぼ同じだけど少しずつ違うバリエーションのハードウェア向けに多種類ののファームウェアをビルドすることがあります。 そういう時にDevice TreeやKconfigの仕組みはとても強力で、ソースが#ifdefの嵐にならず見通しよく開発できます。

独自の開発ツールもあり、C言語の知識だけあっても最初はなかなかとっつきにくいかもしれません。 ただし、企業の強力なサポートがあるためか、公式ドキュメントの充実ぶりは素晴らしいものがあり、学習しやすいです。

サンプルアプリ

Hello, world!を出力してLEDを点滅させるサンプルアプリは次のようになります(Zephyr OS付属のものを一部改変)。

#include <zephyr.h>
#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>
#include <sys/printk.h>

#define SLEEP_TIME_MS   1000

#define LED0_NODE DT_ALIAS(led0)

#if DT_NODE_HAS_STATUS(LED0_NODE, okay)
#define LED0   DT_GPIO_LABEL(LED0_NODE, gpios)
#define PIN    DT_GPIO_PIN(LED0_NODE, gpios)
#define FLAGS  DT_GPIO_FLAGS(LED0_NODE, gpios)
#else
#error "Unsupported board: led0 devicetree alias is not defined"
#endif

void main(void)
{
    const struct device *dev;
    bool led_is_on = true;
    int ret;

    dev = device_get_binding(LED0);

    gpio_pin_configure(dev, PIN, GPIO_OUTPUT_ACTIVE | FLAGS);
    printk("Hello, world!");

    while (1) {
        gpio_pin_set(dev, PIN, (int)led_is_on);
        led_is_on = !led_is_on;
        k_msleep(SLEEP_TIME_MS);
    }
}

printk()というのがなんとなくLinux Kernelっぽいですね☺️

printk()の文字列をどこに出力するか(どのUARTポートに出すか、USBで出すかなど)やled0のGPIOポートはDevice Treeファイルで設定できます。例えば、次のようになります。

/ {
    leds {
        compatible = "gpio-leds";
        green_led_2: led_2 {
            gpios = <&gpiob 3 GPIO_ACTIVE_HIGH>;
            label = "User LED2";
        };
    };

    aliases {
        led0 = &green_led_2;
    };
};

この例では、GPIOB PB3のピンにLEDを繋いだ場合の例です。これで、led0というエイリアス名でC言語のソースからアクセスできます。 (ビルドシステムがそのようにヘッダファイルを自動生成します)

ボードのソースファイルをいじらずにアプリのほうで柔軟にコンフィグレーションできるのがZephyr OSの特徴だと思います。

ただ、DT_ALIAS(led0)などのDevice Tree関連のAPIは慣れるのに最初は苦労します😢(少なくとも私は苦労しています)

どんな人に向いている?

商用のIoT製品をオープンソースOSで開発する人にはピッタリだと思います。

でも、趣味で使うには独自の開発環境に慣れるまでが少し大変かもしれません。 とはいえ、サポートされている開発ボードの数は多いですし、今もどんどん進化しているので、少しずつ使ってみるのもいいかもしれませんよ。 BLEセンサーを開発するなど、Zephyr OSならではの機能を使いたい場合は特におススメです。

スポンサーリンク

RIOT OS

RIOT OSはヨーロッパの大学や研究機関を中心に幅広いコミュニティに支えられている組み込みOSです。

www.riot-os.org

一言でいえば、Zephyr OSみたいに機能豊富ながら、馴染みのある開発環境で取っつきやすいOSです。

特徴

Zephyr OSは独特の開発環境でハードルが高い!😡という方も、RIOT OSなら入りやすいかもしれません。

こちらの方が「よくある」C言語、C++の開発環境に近く、Makefileを編集してGNU makeでビルドします。 Device Treeのような仕組みもありません。 そのため、C言語、C++の開発になれた人にとって入りやすいと言えるでしょう。 コミュニティーベースとはいえ、ドキュメントも充実していて学習しやすいです。

プリエンプティブなマルチスレッドに対応しており、高機能なアプリも作りやすいです。

ライセンスはLGPLv2となっています。

対応マイコン、通信プロトコル

STM32、SAMD、CC2538、nRF52などよく使われる32bitマイコンに対応しています。 Zephyr OSが対応していないAVRやMSP430などの8bit/16bit CPUにも対応しています。 Linux上のアプリとしてRIOT OSを動かすこともできます。

対応開発ボードとしても、STM32 Nucleoシリーズ、BBC micro:bit、Arduino Zeroなどに加え、8bitのArduino Unoなどにも対応しています。

Zephyr OSと違って、Cortex-Aシリーズや64bit CPUなどハイエンドCPUには対応していないみたいです。

プロトコルスタックは特にIEEE802.15.4+6LoWPANベースのIPv6通信に力が入れられているようです。 メッシュ通信を実現するRPLや、組み込み向けのHTTP的なプロトコルであるCoAPなどが揃っており、IoT機器の開発に使えます。

センサーなど周辺デバイスのドライバーも豊富で、先に挙げた温湿度気圧センサーBME280や、 CO2センサーMH-Z19Aのドライバーもありました。 かなり充実しているといえます。

開発環境

ビルドはGNU Makeで行います。アプリのフォルダに移動して、

$ make BOARD=samr21-xpro

など対象ボードを指定してビルドするとファームウェアができます。

Kconfigにも対応しており、メニュー形式でいろいろな設定もできます。

サンプルアプリ

LEDをチカチカさせるサンプルアプリは次のようになります。

#include <stdio.h>
#include <xtimer.h>

#define LED_INTERVAL 1 /* sec */

int main(void)
{
    printf("Hello World!\n");

    while(1) {
        LED0_ON;
        xtimer_sleep(LED_INTERVAL);
        LED0_OFF;
        xtimer_sleep(LED_INTERVAL);
    }
    return 0;
}

printf()の出力先や、LED0_ONのピン設定などは全てボードのソースファイルで定義されています。 Zephyr OSのようにDevice Treeで設定を変えられたりはしないので、ボードのソースファイルを編集する必要があります。

柔軟性は低いですが、直観的でわかりやすいとも言えますね。

ビルドするには、Makefileが必要です。サンプルMakefileは次のようになっています。

# name of your application
APPLICATION = blinky

# If no BOARD is found in the environment, use this default:
BOARD ?= native

USEMODULE += xtimer

# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../../RIOT

# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
DEVELHELP ?= 1

# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1

include $(RIOTBASE)/Makefile.include

あとはmake BOARD=samr21-xproのように、対象ボードを指定してビルドすればファームウェアができます。

どんな人に向いている?

Zephyr OSは入りにくいけど、本格的な組み込みOSに入門してみたいという場合におススメです。 お手軽度ではArduinoの方が上ですが、RIOT OSならマルチスレッドで組み込みOSならではの本格的なアプリが作れます。 ソースコードを見て、OSの仕組みを勉強するにもよさそうです。

スポンサーリンク

mbed OS

mbed OSはマイコンCPUを開発するイギリスの会社ARMが出しているOSです。なので、ARM Cortex-MシリーズのCPUを搭載したデバイスで使えるOSです。

os.mbed.com

特徴

Web IDEが用意されており、ブラウザ上で全ての開発ができてしまいます。インストール不要で使えるのはとてもお手軽です! mbed OSのサイトにアクセスしてアカウントを作成して、ボードやライブラリを選んでプロジェクト作成し、コードを書いてビルドすると、ファームウェアがダウンロードできます。

もちろん、SDKをダウンロードしてローカルで開発環境を構築することもできます。

プリエンプティブなマルチスレッドが使えるFull Profileと、シングルスレッドのBare Metal Profileの2種類が用意されています。 Bare metal profileを使えばRAM、Flashの容量がとても小さくて済み、安いマイコンでも動作させられます。

対応マイコン、通信プロトコル

STM32 NucleoシリーズやFreedom開発ボードなど、日本でも手に入りやすいマイコン開発ボードにもmbed対応のものがあります。

IoT向けの機能がたくさん搭載されており、TCP/IP、6LoWPAN、BLEをはじめ、豊富なプロトコルスタックが利用できます。 私はmbed OSではスタンドアロンのものしか開発してみたことがないので詳しくはないのですが、Zephyr OSと同等以上に充実してそうです。

開発環境

Web IDEを使えば開発環境を構築する必要がありません。ビルドもボタン一つでできてしまいます。

ローカルの開発環境は、Mbed Studioという専用のIDEと、Mbed CLIというコマンドラインの開発環境の2種類が選べます。

私は今のところWeb IDE + Bare Metal Profileしか使ったことがないのでローカル開発環境の方は詳しく知らないので語れません…。

サンプルアプリ

Bare Metal ProfileでLED点滅のサンプルプログラムを用意してみました。

#include "mbed.h"

#define WAIT_TIME_MS 1000 
DigitalOut led1(LED1);

int main()
{
    printf("Hello, world!");

    while (true)
    {
        led1 = !led1;
        thread_sleep_for(WAIT_TIME_MS);
    }
}

これもZephyr OSのものよりスッキリしていますね。LED1はBSPが提供しています。

RIOT OS同様、元からサポートされているLED以外、例えばブレッドボードに自分で挿したLEDを使うには、ボードのソースファイルを編集するか、GPIOのAPIを使ってアクセスする必要があります。

Web IDEの場合、ブラウザでログインして、ターゲットボードを選択してプロジェクトを作成し、上のソースファイルを作成し、ビルドボタンを押すだけでファームウェアがダウンロードできます。ローカルに開発環境を用意する必要がないので、簡単なプログラムを最速で作るのに便利です。

どんな人に向いている?

STM32 Nucleoなど対応ボードを使って、簡単なアプリをお手軽に作りたいときに、mbed OSのWeb IDEはベストな選択肢だと思います。 とにかく思い立ってからファームウェアになるまでのスピードが早いです。ブラウザだけで開発できるのはすごい!

対応プロトコルスタックが充実しているので、本格的な商用IoT製品開発にも向いているのかもしれません。

スポンサーリンク

Contiki-ng

その昔、一世を風靡したオープンソース組み込みOSにContiki OSというものがありました。 IoTという言葉もなかった(と思われる)2003年ごろから開発されている、歴史あるオープンソース組み込みOSです。 8bitマイコンでも動き、ほぼOSレスな構成なのに疑似マルチタスクができるという特徴があります。

以前は私の中の組み込みOS注目度ランキングでContiki OSが第1位でした。(個人の感想です)

とはいえIoT全盛時代。Contiki OSは8bitマイコンのサポートと最近の高機能なプロトコルスタック対応を両立するのが大変なのか、ついに2018年に開発が停止しました。そしてContiki OSの発展形として、IoT向けに特化したOSとしてContiki-ngが誕生しました。

github.com

Contiki-ngはContiki OSのコアを受け継ぎつつ、8bitマイコンなどレガシーなデバイスのサポートをバッサリと切り、現代のIoTに対応すべく様々な機能拡張をしやすい形に再編したものになります。

特徴

現状、IPv6(6LoWPAN)、CoAPを中心に、プロトコルスタックがサポートされています。 シングルスレッド+疑似マルチタスク(コルーチン)のコアは健在で、RAMやFlashの少ないマイコンでも動かしやすいOSになっています。

ただし、Zephyr OSなどに比べるとサポートされているマイコンや開発ボードが少ないので、趣味の用途では使いにくいです😢

シングルスレッドでOSのコアが比較的単純なので、ソースコードを読んでOSの仕組みを理解するにはちょうど良いと思います😊

珍しい機能としては、ネットワークシミュレーターのCoojaというものが付属しています。 無線機をたくさん置くと、電波を出すタイミングが重なり電波がぶつかって受信できないなど、いろんな通信エラーのパターンがあります。 途中に中継器を置き、直接通信できない無線機にデータを届けるメッシュネットワークを使う場合もあります。 そのような無線通信をシミュレーションし、プロトコルスタック開発に役立てるシミュレーターになっています。

例えば、RPLというIPv6ベースのプロトコルによるメッシュネットワークのシミュレーションができるようになっています。

対応マイコン、通信プロトコル

Texas Instrumentsも開発に参加しているため、特にTexas Instrumentsのマイコンや開発ボードがよくサポートされています。 それ以外にもnRF52などいくつかのマイコンがサポートされています。

プロトコルスタックとしてはIEEE802.15.4e TiSCHに6LoWPAN、RPL、CoAPという構成が基本となります。

RIOTやZephyr OSに比べれば対応デバイス数やプロトコルスタック数は少ないです。 Texas Instrumentsの無線LSIを使ってIoT製品を開発する場合が主なユースケースとなると思います。

開発環境

こちらもGNU Makeを使った昔ながらの構成です。

Contiki-ngは、以前紹介したSensorTagという開発ボードがサポートされています。 SensorTag用に独自ファームウェアをビルドするには、アプリのプロジェクトフォルダで次のようにします。

$ make TARGET=simplelink BOARD=sensortag/cc2650

私はSensorTagの書き込み機を持っていないので、実際に書き込んだことはないですが…😅

サンプルアプリ

LEDをチカチカさせるサンプルアプリを用意してみました。

#include "contiki.h"
#include "dev/leds.h"
#include <stdio.h> /* For printf() */
/*---------------------------------------------------------------------------*/
PROCESS(hello_world_process, "Hello world process");
AUTOSTART_PROCESSES(&hello_world_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(hello_world_process, ev, data)
{
  static struct etimer timer;

  PROCESS_BEGIN();

  printf("Hello, world\n");

  /* Setup a periodic timer that expires after 1 second. */
  etimer_set(&timer, CLOCK_SECOND);

  while(1) {

    /* Wait for the periodic timer to expire and then restart the timer. */
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));
    etimer_reset(&timer);
    leds_single_on(LEDS_LED1);

    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));
    etimer_reset(&timer);
    leds_single_off(LEDS_LED1);
  }

  PROCESS_END();
}
/*---------------------------------------------------------------------------*/

PROCESS_THREAD()など、疑似プロセス関係の大文字のマクロっぽいものがたくさん出てきて特徴的です。

実はこれら大文字のものはC言語のマクロで、展開するとこのようになります(PROCESS_THREAD()の中身だけ抜粋)。

static char process_thread_hello_world_process(
  struct pt *process_pt, process_event_t ev, process_data_t data)
{
  static struct etimer timer;
  {
  char PT_YIELD_FLAG = 1;
  if (PT_YIELD_FLAG) {;}

  switch((process_pt)->lc) {
  case 0:;
    printf("Hello, world\n");
    /* Setup a periodic timer that expires after 1 second. */
    etimer_set(&timer, 128);
    while(1) {
      /* Wait for the periodic timer to expire and then restart the timer. */
      do {
        PT_YIELD_FLAG = 0;
        (process_pt)->lc = 22;
  case 22:;
        if((PT_YIELD_FLAG == 0) || !(etimer_expired(&timer))) { return 1; }
      } while(0);
      etimer_reset(&timer);
      leds_single_on(0x00);
      do {
        PT_YIELD_FLAG = 0;
        (process_pt)->lc = 26;
  case 26:;
        if((PT_YIELD_FLAG == 0) || !(etimer_expired(&timer))) { return 1; }
      } while(0);
      etimer_reset(&timer);
      leds_single_off(0x00);
    }
  };

  PT_YIELD_FLAG = 0;
  (process_pt)->lc = 0;;
  return 3;
  };
}
/

switch()のcase文がwhile()の中にあるなど、とても不思議なソースコードになっていますね🤔

Contiki OS/Contiki-ngではボードごとのソースファイル中にmain()関数があり、その中のwhile(1)で全プロセスを順番に呼び出しています。

このswitch((process_pt)->lc)lcに注目してください👀

元のソースのPROCESS_WAIT_EVENT_UNTIL()の部分で、lc__LINE__マクロで生成した行番号を代入し、returnします。 次にmain()からこの関数が呼ばれると、switch~case文でlcに代入された行番号の場所、すなわち先ほどreturnした場所に戻ってきます。

オーバーヘッドがほとんどなく、先ほどタスクが中断した場所に復帰していることがわかります。すごい仕組みですね!!😳

ANSI Cの仕様を最大限に使って、まるでマルチタスクOSのような動作を実現してしまうのが旧Contiki OSからのすごいところで、 Contiki OSの作者でスーパーハッカーのアダム・ダンケルさんのセンスが光っています。

どんな人に向いている?

残念ながら対応マイコンボードが少ないので、現時点ではほぼTexas InstrumentsのLSIを使って商用IoT製品を開発する場合しか使う機会がないかもしれません。趣味で使うには厳しそうです。

スポンサーリンク

Arduino

ArduinoはOSというよりOSも含んだ開発環境です。そもそも開発環境なので他とレイヤーが違いますが、有名ですので紹介しておきます。

www.arduino.cc

特徴

Arduinoは教育用に作られた開発環境です。

ソフトウェア開発ではファームウェアをビルドする前にまず開発環境を構築する必要があります。 まあこれまで挙げたどの組み込みOSもマニュアルが整備されていて、私のようなインストール厨にとっては手順通りすれば難しくないです。

しかし、そもそも「コマンドプロンプト」って何?🤔という人や、黒いウィンドウに文字(しかも英語)が並んでいるのを見るだけでやる気をなくす人のほうが普通です。

というわけで、パソコン初心者の中学生や高校生でも使える開発環境としてイタリア🇮🇹でArduinoが開発されました。Arduinoの開発ボードは、中高生のお小遣いでも買えるよう、安いものだと1000円を切るくらい安価になっています😊

教育用の枠を超えて大人気になったため、サードパーティーのライブラリが充実し、今ではIoT向けの開発にも十分使えるくらい発展しています。

機能

OSとしてはシングルスレッドの単純なものです。複雑なことをするには向いていませんが、ちょっとしたものが手軽に作れます。 Arduinoの機能はタイマーやUART、I2Cなどマイコンの機能へのアクセスなどに限られ多くはないです。

しかしサードパーティーのライブラリがとても豊富なので、様々なセンサーのドライバ、プロトコルスタック、など多種多様なものが入手できます。非公式なので品質は物によりますが…。

また、ボード対応パッケージ(BSP)もサードパーティーが自由に作れるため、公式のArduinoボード以外にSTM32など様々なものが使えます。

サードパーティー製のBSPやライブラリのインストールもArduinoの画面からGUIで簡単にできるのが便利です。

開発環境

インストーラからインストールするだけで、IDE、コンパイラや書き込みツールなど一式が入りますので、環境構築に悩む必要はありません😊

ArduinoはこのようなIDEで開発します。

f:id:kimura_khs:20210404164153p:plain

IDEの機能も少なく絞られており、初心者でも迷いにくくなっています。 外部エディタ連携もできるので、Visual Studio Codeなど使い慣れたエディタでコードを書き、ビルド・書き込みだけに使うこともできます。

Arduinoは独自のArduino言語というC/C++をベースにしたもので開発します。とはいえ概ね普通のC/C++と思って大丈夫です。 C/C++との違いは、

  • タイマー、UART、SPIなどの機能が含まれている
  • アプリの#includeの管理はIDEが行い、開発者が意識する必要がない
  • エントリーポイントがmain()ではなく、setup()loop()という2つの関数になっている

といったところでしょうか。

実際にはコンパイラはC++が使われます。main()はBSPの中に隠蔽されてユーザが意識しない形になっています。 そもそもBSPは隠しファイルとしてインストールされ、見る必要もないようになっています。

ちょっとBSPの中身をのぞいてみましょう。 例えば、Arduino M0という、Arduinoの中では比較的高性能な公式ボードのBSPのmain()は次のようになっています。

int main( void )
{
  init();

  __libc_init_array();

  initVariant();

  delay(1);
#if defined(USBCON)
  USBDevice.init();
  USBDevice.attach();
#endif

  setup();

  for (;;)
  {
    loop();
    if (serialEventRun) serialEventRun();
  }

  return 0;
}

このように、main()からsetup()が呼ばれ、loop()がひたすら呼ばれ続ける、という構成になっています。 このsetup()とloop()の中身をArduino IDEで開発するというわけです。

サンプルアプリ

LEDをチカチカさせるサンプルアプリはこのようになります。

// the setup function runs once when you press reset or power the board
void setup() {
  Serial.begin(115200);
  Serial.println("Hello World!");
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(1000);
}

LED_BUILTINはBSPで定義されているものを使っていますが、番号を指定することで任意のGPIOを使うこともできます。

最低限この2つの関数を書けばファームウェアができますが、 複数のソースファイルに分割したり、自分でC++のクラスを定義して使うことももちろんできます。

どんな人に向いている?

手軽に開発環境を構築してマイコン開発をしたい人にピッタリです。

非公式ながらサードパーティー製ライブラリが充実しているので、やりたいことが手軽に実現できる可能性があります。 教育用でメジャーなので、情報の充実度が抜群で、日本語の情報もたくさんあるのもメリットです。

スポンサーリンク

FreeRTOS

IoT向けのオープンソース組み込みOSといえば、FreeRTOSがいちばん有名かもしれません。

Amazonが2017年に買収💸して、今はAmazonが権利を持っており、MITライセンスで公開しています。

www.freertos.org

もともと2003年くらいから開発が続いている歴史の長いOSでもあり、対応マイコンの豊富さがすごいです。

STM32、LPCなどのARM Cortex-Mマイコン、RISC-V、PIC32、ルネサスRXシリーズなどにも対応しており、Zephyr OSなどと比べてもより多いです。

OSのコアはマルチスレッド、排他制御、タイマーなどの機能に限られており、 プロトコルスタックなどその他の機能はライブラリで提供されています。

IPv4/v6、TLS、HTTP、MQTT、ファイルシステムなど豊富なライブラリが使えます。

そしてAmazonが買収しただけあり、AWS関連のライブラリも充実しており、IoT製品が作りやすくなっています。

他のOS

ここから先は私が使ったことないOSですが、他にもいろんなOSがあります。

  • NuttX - Apache Software Foundationがホストしている組み込みOS。8bitから32bitまでの幅広いマイコンに対応しており、AVR、STM32、LPCシリーズや、ルネサスのマイコンまで数多く対応している。POSIXライクなAPIを提供するなど使いやすそう。開発も活発。
  • Mongoose OS - ESP32を中心に、STM32のハイエンド品などでも動くIoT向け組み込みOS。クラウド対応が充実しておりAWS IoT、Google Cloud IoT Core、Azure IoTに対応。Apache License 2.0。
  • CircuitPython - Adafruit社が開発している、マイコン上でPythonでプログラミングができる開発環境。SAMD21やSTM32F4マイコン上で動き、Pythonでアプリが書けてとても便利。MITライセンス。
  • Tiny OS - Contiki OSやFreeRTOSと同じくらい歴史のある組み込みOS。更新はやや収束気味かも?

このように、とてもたくさんのOSが選べるマイコンプログラミングの世界ですが、みなさまはどんなOSをお使いでしょうか😉

マイコンの性能が上がったこともあり、以前に比べてずいぶん使いやすく洗練された開発環境が増えてきました。 これからの進化にも期待ですね!🥰