如何在不同製造商的晶片上運行相同的 C 程式碼

在過去的兩年裡,我一直在用 Zephyr RTOS 來磨練我的技能。 對我來說最有趣的部分之一是能夠維持一個程式碼庫,並能夠被編譯於不同製造商的晶片。 我最近做了一個物聯網 IoT感測器群演示,其中有不同的節點運行 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代碼

image

在晶片短缺的時代,不用重寫韌體就能轉換完全不同的感測器,這是一種難以置信的解放。 Infineon 的DPS310 溫度感測器(此處顯示的是 Adafruit 的 DPS310 分接板)取代 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 而不是 BME280啟用和建立適當的驅動程式庫。

看到數據滾滾而來吧

image

一旦建立,數據看起來是一樣的。 唯一真正的區別是,Infineon 感測器的精確度是六位數,而 Bosch 感測器只有兩位數。 否則,fleet 資料將記錄在 Golioth 伺服器上,並準備在您想要的任何雲端平台上查詢、視覺化和使用。

該演示還包括改變整個 fleet 設定的能力,例如讀取資料的頻率。 當然,如果你需要調整韌體的工作方式,所有這些裝置都可以接收無線(OTA)韌體更新。 試試吧,Golioth 的 Dev Tier 對你的前50台設備是免費的。

image

當資料進入伺服器時,我們可以立即將其視覺化。上圖中,我們使用 Grafana 來繪製從三個不同電路板接收到的溫度讀數。

參考感測器演示

image

感測器會議在 Santa Clara 舉行。 整個 Golioth 團隊都很高興我們的硬件,演示是 DigiKey 展位的一部分。 抬頭看看物聯網IoT天氣 fleet 發送即時讀數!

資源