第一章:Zephyr与传感器生态

大家好,我是你们的讲师。今天咱们聊聊Zephyr和传感器这件事。

做嵌入式开发这么多年,我接触过不少RTOS。FreeRTOS、RT-Thread、uC/OS都玩过。但说实话,Zephyr在传感器支持这块,确实让我眼前一亮。为什么?因为它把传感器驱动做成了一个标准化的子系统。你想想看,以前换个传感器,驱动代码得重写大半。现在呢?改个设备树节点,调几个参数就完事了。

1.1 Zephyr RTOS简介

Zephyr是什么?简单说,它是一个面向物联网的实时操作系统。由Linux基金会维护,开源、免费。我最早接触Zephyr是在2018年,当时一个项目需要同时支持温度、湿度、气压、加速度计四个传感器。用FreeRTOS的话,我得自己写驱动框架。用Zephyr,它已经帮你搭好了架子。

Zephyr有几个特点让我印象深刻:

  • 模块化设计:内核、驱动、协议栈都是独立的模块。想用哪个加哪个,不像某些RTOS,一上来就是个大胖子。
  • 设备树支持:这个是从Linux继承过来的。硬件配置和驱动代码分离,改硬件不用改代码。
  • 丰富的驱动库:官方支持的传感器驱动就有上百种。我常用的BME280、MPU6050、LIS3DH都在里面。
  • 安全机制:支持TLS、DTLS,做物联网产品不用额外加安全芯片。
我的小建议:如果你是第一次用Zephyr,别急着看源码。先跑几个官方例程,感受一下它的开发流程。我当初就是直接啃源码,结果绕了不少弯路。

1.2 传感器子系统架构

Zephyr的传感器子系统,说白了就是一套标准接口。不管你是温度传感器还是加速度计,都走同一套API。这样做的好处很明显——上层应用不用关心底层是I2C还是SPI。

架构分三层:

  • 应用层:调用 sensor_sample_fetch() 获取数据,用 sensor_channel_get() 读取具体值。
  • 驱动层:实现 sensor_driver_api 结构体里的函数。包括 init、sample_fetch、channel_get 等。
  • 硬件层:通过设备树描述硬件连接。比如传感器挂在哪个I2C总线上,地址是多少。

举个例子,读取BME280的温度:

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>

void main(void)
{
    const struct device *dev = DEVICE_DT_GET_ANY(bosch_bme280);
    struct sensor_value temp;

    if (!device_is_ready(dev)) {
        printk("传感器未就绪\n");
        return;
    }

    while (1) {
        sensor_sample_fetch(dev);
        sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp);
        printk("温度: %d.%d°C\n", temp.val1, temp.val2);
        k_sleep(K_MSEC(1000));
    }
}

你看,代码就这么几行。不用管I2C时序,不用管寄存器地址。驱动层都帮你封装好了。我在项目中遇到过一个问题:同一个传感器,在不同板子上I2C地址不一样。用设备树的话,改一下 dts 文件就行,代码完全不用动。

注意:sensor_sample_fetch() 是阻塞的。如果你的传感器采样时间很长(比如某些气体传感器要几秒),记得用异步方式或者单独开个线程。我曾经在一个产品里用主循环直接调用,结果整个系统卡了3秒,被客户投诉了。

1.3 支持的传感器类型

Zephyr支持的传感器类型,我数了数,大概有这些大类:

类型 常见型号 接口
温度/湿度 BME280, DHT22, SHT3x I2C, SPI
气压 BMP180, LPS22HB I2C
加速度计 MPU6050, LIS3DH, ADXL345 I2C, SPI
陀螺仪 MPU6050, ICM-20948 I2C, SPI
磁力计 HMC5883L, LIS3MDL I2C
光线 BH1750, TSL2561 I2C
距离 VL53L0X, HC-SR04 I2C, GPIO
气体 CCS811, SGP30 I2C

嗯,这里要注意。虽然官方支持很多,但有些传感器驱动质量参差不齐。比如DHT22的驱动,我试过两个版本,一个采样间隔必须大于1秒,另一个可以连续读。所以用之前,最好看看驱动源码,确认一下限制条件。

1.4 开发板选型建议

选开发板这事,我踩过不少坑。给你几个建议:

  • nRF52840 DK:Nordic的板子,Zephyr支持最好的平台之一。蓝牙、USB、传感器接口都有。我第一个Zephyr项目就是用这个板子做的。
  • STM32 Nucleo系列:比如NUCLEO-F411RE。便宜、资料多。但要注意,有些Nucleo板子没有板载传感器,得自己外接。
  • ESP32系列:WiFi和蓝牙都有,适合做物联网网关。但Zephyr对ESP32的支持还在完善中,有些外设驱动可能不完整。
  • MIMXRT1060-EVK:NXP的板子,性能强,适合做复杂传感器融合。但价格贵,初学者慎入。

我的推荐:如果你是初学者,直接买nRF52840 DK。别问为什么,我当初就是图便宜买了块STM32F103的板子,结果折腾了两周才把Zephyr跑起来。nRF52840 DK开箱即用,官方例程一烧就亮。

选板子还要考虑传感器接口。大部分传感器用I2C,所以板子上最好有I2C接口。另外,注意电平匹配。很多传感器是3.3V的,如果你用5V的板子,得加电平转换。我曾经因为没注意这个,烧了两个传感器。

好了,第一章就到这里。下一章我们聊聊怎么搭建开发环境,以及如何让你的第一个传感器跑起来。