同じCコードを、複数のベンダーのチップ上で動作させる方法

mike_golioth Verified Supplier Rep

この2年間にわたり、Zephyr RTOSによって私はスキルを磨いて来ました。私にとって最も興味深いものの1つは、1つのコードベース(一連のソースコード)をメンテナンスし、それを複数のベンダーのチップ用にコンパイルできる能力です。最近、Nordic、NXP、Espressifのチップを搭載したさまざまなノードを持つIoTセンサのいくつかのデモを作りました。それを見たDigiKeyのJoshとKelsieが、Sensors Converge ConferenceのDigiKeyブースで出展するよう招待してくれました。

Golioth を使用すると、マイクロコントローラ ベースの IoT デバイスをクラウドに簡単に接続でき、クラウド側でデータを利用できるようになり、リモートデバイス管理が容易になります。このプロジェクトの研究は、ハードウェアに左右されない方法でZephyr Real-Time Operating Systemのアプリコードに、どのようにアプローチするかを中心テーマとしました。その方法については後ほど詳しく説明しますが、直ぐに知りたいのであれば、オープンソースのIoT Weather Fleetリポジトリをご覧ください。

3つの全く異なるハードウェアバージョン

これはデモに過ぎないので、センサのデータは非常に単純です。それは、リモートで設置可能な間隔で読み込んだ温度測定値を報告します。もちろん、一旦それを稼働させれば、他のタイプのデータに変換するのは容易なことです。

ここ数年、チップの供給不足に悩まされ、チップファミリの中のみならず、まったく異なるベンダーのチップにも移植することができる能力を実証したいと思っていました。私は、Nordic nRF9160(すなわちSparkfun Thing Plus nRF9160)、NXP i.MX RT1062(すなわちRT1060-EVKB board)、そしてEspressif ESP32 (すなわち、Featherボードと同じフォームファクタを持っているAdafruit Huzzah32)に行き着きました。

同じコードをこのような異なるハードウェア上で動作させるにはどのようにすれば良いのでしょうか。ZephyrはKconfigとDevicetreeを使って、ビルドを肥大化させない方法でハードウェアを抽象化しています。これにはピンの多重化と、優れたセンサモデルが含まれているので、必要なことは各ボード用に2つのファイルを作ることだけでした。NXPボードのセンサとピン配置は以下のとおりです。

/ {
    aliases {
        weather = &bme280;
    };
};

&lpi2c1 {
	status = "okay";

	bme280: bme280@76 {
		status = "okay";
		compatible = "bosch,bme280";
		reg = <0x76>;
	};
};

Bosche BME280センサでi2c1バスを選んでいるのがわかります。この時点で構文が理解できなくとも、心配することはありません。ここではセンサに名前を割り付けています。これにより、Cのコードでweatherというセンサを参照することが可能になります。それはどのタイプのセンサであるかを知ることではなく、知る必要もありません。Zephyrはそのすべてを処理し、センサの読み取りに一般的な「チャンネル」を利用できるようにします。

// Create a pointer to our sensor
const struct device *weather_dev = DEVICE_DT_GET(DT_ALIAS(weather));

// Perform a sensor reading and access the temperature data
sensor_sample_fetch(weather_dev);
sensor_channel_get(weather_dev, SENSOR_CHAN_AMBIENT_TEMP, &tem);

異なるマイクロコントローラを使用し、しかも異なるセンサを使用すること、これがポイントです。

異なるセンサに同じCコード

チップが入手しにくい時代、ファームウェアを書き換えることなく、全く異なるセンサに入れ替えることができるのは何と素晴らしいことではないでしょうか。Infineon DPS310温度センサ(ここで示されているのはAdafruit DPS310ブレークアウト)は、Bosch BME280(ここで示されているのはMikroE Weather Click)の代わりになります。

唯一の変更点は、どのセンサが使用されているのか(そしてどのピンがi2cバスに使用されているのか)をビルドに伝えるDevicetree overlayファイルだけです。

/ {
    aliases {
        weather = &dps310;
    };
};

&i2c1 {
	status = "okay";
	clock-frequency = <I2C_BITRATE_STANDARD>;
	pinctrl-0 = <&i2c1_default>;

	dps310: dps310@77 {
		status = "okay";
		compatible = "infineon,dps310";
		reg = <0x77>;
	};
};

&pinctrl {
	i2c1_default: i2c1_default {
		group1 {
			psels = <NRF_PSEL(TWIM_SDA, 0, 26)>,
				<NRF_PSEL(TWIM_SCL, 0, 27)>;
		};
	};
};

同じ名前(weather)が作られていますが、違うセンサにもその名前が割り当てられていることに注目してください。ここで再び、Zephyrは抽象化を行い、BME280の代わりにDPS310の適切なドライバライブラリを有効にし、ビルドします。

時々刻々送られて来るデータを見る

一旦データがビルドされ、フラッシュされると、同じように見えます。唯一違う点は、磁気センサが6桁の精度に対し、Boscheのセンサは2桁しかないことです。それ以外では、送られてくる全データはGoliothのサーバに記録され、照会、視覚化、および必要なクラウドプラットフォームで使用する準備ができています。

このデモでは、測定値を読み込む頻度の設定など、全体にわたる設定を変更できる能力を持っています。もちろん、ファームウェアがどのように動作するのかの微調整が必要ならば、これらの全てのデバイスは、Over-the-Air(OTA)ファームウェアのアップデートを受けることができます。Golioth’s Dev Tierは50デバイスまで無料ですので、是非お試しください。

データがサーバに入ってくると、直ぐに視覚化することができます。上図では、3つの異なるボードからの温度の測定値を、Grafanaを使ってグラフ化しています。

Sensors Converge Conferenceのデモを見る

サンタクララにおいて、現在Sensors Converge conferenceが行われています。筆者のチーム全員は、ハードウェアのデモがDigiKeyブースの一画で行われていることに興奮しています。私たちのブースを訪れて頂き、温度測定値がライブで送られてくるIot気象センサのデモをご覧ください。

資料




オリジナル・ソース(English)