如何在多家厂商芯片上运行相同的 C 语言代码

在过去的两年里,我一直在用 Zephyr RTOS 来磨练我的技能。对我来说最有趣的部分之一是能够维护一个代码库,并为来自多个供应商的芯片编译它。我最近做了一个物联网传感器群演示,其中有不同的节点运行 Nordic、NXP 或 Espressif 芯片。当来自 DigiKey 的 Josh 和 Kelsie 看到它时,他们邀请我们在传感器会议的 DigiKey 展位上展示它。

Golioth 可以轻松地将基于微控制器的物联网设备连接到云端,使数据在云端可用,并促进远程设备管理。这个项目的研究部分集中在如何以一种与硬件无关的方式处理 Zephyr 实时操作系统应用程序代码。我将详细介绍我们是如何做到这一点的,但如果你想现在就看到代码,请查看我们发布的开源物联网天气fleet仓库

相同硬件的三个不同版本

image

因为这只是一个演示,所以传感器数据非常简单: 以远程配置,间隔报告温度读数。当然,一旦启动并运行,将传感器数据变成任何其他类型的数据都是很简单的。

由于近年来芯片短缺的困扰,我想展示的不仅仅是在一个芯片家族内部转移的能力,而是在完全不同的供应商之间转移的能力。我降落在 Nordic nRF9160 (这里是一个 SPARKFUN THING PLUS - NRF9160),NXP i.MX RT1062 (这里是一个 RT1060-EVKB评估板,和一个 Espressif ESP32 (这里是一个 Adafruit Huzzah32 )。

如何在所有这些不同的硬件上运行相同的代码呢? Zephyr 使用 Kconfig 和 Devicetree 以一种不会使模型变复杂的方式提取硬件。这包括引脚复用和一个智能的传感器模型,所以我们所需要做的就是为每个变体制作两个文件。以下是 NXP 板上的传感器和引脚分配:

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

&lpi2c1 {
	status = "okay";

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

您可以看到,我选择了 i2c1 总线与 Bosch BME280 传感器。如果语法现在不完全清楚,不要担心,只需查看顶部为传感器分配别名的地方。这使得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代码

在芯片短缺的时代,不用重写固件就能转换完全不同的传感器,这是一种难以置信的解放。英飞凌DPS310温度传感器(此处显示的是AdafruitDPS310断口)代替Bosch BME280(如图所示是MikroE Weather Click )。

唯一改变的是Devicetree覆盖文件,它告诉构建我们使用的是哪个传感器(以及i2c总线使用哪些引脚):

/ {
    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 将负责提取,为 DPS310 而不是 BME28 0启用和构建适当的驱动程序库。

看看数据滚滚而来吧

image

一旦构建数据看起来是一样的。唯一真正的区别是,英飞凌传感器的精度是六位数,而博世传感器只有两位数。否则,fleet 数据将被记录在 Golioth 服务器上,并准备在您希望的任何云平台上查询、可视化和使用。

该演示还包括改变整个 fleet 设置的能力,比如读取数据的频率。当然,如果你需要调整固件的工作方式,所有这些设备都可以接收无线 (OTA) 固件更新。试试吧,Golioth 的 Dev Tier 对你的前50台设备是免费的。

image

当数据进入服务器时,我们可以立即将其可视化。上图中,我们使用 Grafana 来绘制从三个不同电路板接收到的温度读数。

参见传感器演示

image

传感器会议现在正在Santa Clara 举行。整个 Golioth 团队都很高兴我们的硬件,演示是 DigiKey 展台的一部分。抬头看看物联网天气 fleet 发送实时读数!

资源