2、基础知识:嵌入式系统、传感器类型、模拟/数字接口及数据格式
TinyML 的落地离不开对底层硬件的透彻理解。模型推理的输入并非抽象的“特征向量”,而是来自真实物理世界的电信号——加速度计感知的振动、麦克风捕获的气压波动、摄像头感光元件上的光子。这些信号经过传感器内部的模拟前端调理、ADC 量化,再通过 I2C、SPI 等总线以数字帧的形式送入 MCU。本章将系统梳理嵌入式系统的基本构成、主流传感器类型、常用通信接口的电气特性与数据格式,为后续设计硬件抽象层(HAL)和推理模块边界打下坚实基础。
2.1 嵌入式系统核心构成与 TinyML 硬件约束
嵌入式系统是以应用为中心、以计算机技术为基础,软硬件可裁剪,对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。在 TinyML 场景下,典型硬件平台包含 MCU(微控制器)、传感器、通信接口、电源管理、存储(Flash/SRAM)以及可选的外部存储(如 QSPI Flash)。与通用 CPU 不同,MCU 通常集成 Flash 和 SRAM 于单芯片内,运行频率在几十 MHz 到几百 MHz 之间,SRAM 容量从几十 KB 到几 MB 不等。
从硬件抽象层设计角度,需要关注以下核心约束:
- 算力受限:Cortex-M4 系列通常支持 DSP 指令和单精度浮点单元(FPU),但进行大规模矩阵运算仍需优化;Cortex-M33 增加 TrustZone 安全扩展,适合需要隔离的推理场景。
- 内存瓶颈:模型权重、中间激活值、输入输出缓冲区均需在 SRAM 中驻留。例如,一个 50KB 的模型在 256KB SRAM 的 MCU 上运行,需仔细规划内存池。
- 外设资源:I2C、SPI、UART、GPIO、ADC、DMA、定时器数量有限,HAL 需合理分配并支持复用。
- 功耗预算:电池供电设备通常要求平均电流在微安到毫安级,传感器采样、推理、无线传输的功耗需精细调度。
sensor_read_accel())、设备配置接口(如 sensor_set_range())和中断回调注册接口。这样上层推理引擎无需关心底层是 I2C 还是 SPI,也无需关心传感器是 Bosch 还是 ST 的产品。
2.2 主流传感器类型与输出特性
TinyML 应用中最常见的传感器包括惯性传感器(加速度计、陀螺仪)、环境传感器(温湿度、气压)、声学传感器(麦克风)和视觉传感器(摄像头)。每种传感器在物理原理、输出数据率、量程、噪声特性上差异显著,直接影响 HAL 的数据格式定义。
| 传感器类型 | 物理量 | 典型接口 | 输出数据格式 | 典型采样率 | TinyML 应用场景 |
|---|---|---|---|---|---|
| 加速度计 | 加速度 (g) | I2C/SPI | 16bit 有符号整数,量程 ±2g~±16g | 25~1000 Hz | 活动识别、跌倒检测、振动分析 |
| 陀螺仪 | 角速度 (°/s) | SPI/I2C | 16bit 有符号整数,量程 ±250~±2000°/s | 25~1000 Hz | 姿态估计、手势识别 |
| 麦克风 | 声压 (Pa) | PDM/I2S | 16/24bit PCM 或 PDM 位流 | 8~48 kHz | 关键词唤醒、声学事件检测 |
| 摄像头 | 光强/颜色 | DVP/MIPI | RAW Bayer / YUV / RGB565 | 1~30 fps | 图像分类、目标检测 |
| 温湿度 | 温度/相对湿度 | I2C | 16bit 无符号整数,需转换公式 | 0.5~10 Hz | 环境监测、预测性维护 |
以加速度计为例,其输出原始值为 ADC 量化后的数字码。假设量程为 ±2g,16 位分辨率,则 1g 对应的 LSB 值为 16384(即 2^15 / 2)。HAL 层需要将原始整数转换为物理单位(m/s² 或 g),并可选地进行低通滤波以去除高频噪声。对于麦克风,PDM 接口输出的是 1-bit 过采样位流,需经过抽取滤波(CIC 或 FIR)转换为 16-bit PCM 数据,这一过程通常在 MCU 内部完成。
2.3 模拟/数字接口:I2C、SPI、UART、GPIO、ADC
接口选型直接决定了 HAL 的驱动实现复杂度、数据传输速率和引脚占用。下表对比了 TinyML 中最常用的几种接口:
| 接口 | 信号线 | 速率 | 寻址/片选 | 典型应用 | HAL 注意事项 |
|---|---|---|---|---|---|
| I2C | SCL, SDA | 100/400/1000 kbps | 7/10-bit 地址 | 加速度计、温湿度、气压计 | 需处理时钟拉伸、多主机仲裁;速率较低,不适合高数据率传感器 |
| SPI | SCK, MOSI, MISO, CS | 1~40 Mbps | 独立 CS 片选 | 陀螺仪、摄像头、Flash | 全双工,速率高;需管理多个片选信号;支持 DMA 传输 |
| UART | TX, RX | 9600~4 Mbps | 无地址,点对点 | GPS、调试输出、部分传感器 | 异步通信,需配置波特率、数据位、停止位;无时钟线,需双方约定 |
| GPIO | 单线或多线 | 数字电平 | 无 | 中断触发、使能控制、LED 指示 | 可配置上拉/下拉、边沿触发;用于传感器数据就绪中断 |
| ADC | 模拟输入 | 采样率取决于 MCU | 通道选择 | 模拟麦克风、光敏电阻、电池电压 | 需配置参考电压、采样时间、分辨率;注意输入阻抗匹配 |
在 HAL 设计中,接口抽象层应提供统一的 bus_read() / bus_write() 函数,内部根据总线类型分发到具体驱动。例如,对于 I2C 传感器,HAL 需要封装寄存器地址、字节序(大端/小端)和重复起始条件等细节。对于 SPI 传感器,则需处理 8/16/32-bit 传输宽度、时钟极性和相位(CPOL/CPHA)配置。
2.4 数据格式与转换链路
从传感器原始数据到 TinyML 模型输入,通常经历以下转换阶段:
- 原始寄存器值:传感器内部 ADC 输出的二进制补码,如 16-bit 有符号整数。
- 物理单位转换:根据量程和分辨率计算实际物理值。例如,加速度计输出 16384 对应 1g,则物理值 = 原始值 / 16384 * 9.81 m/s²。
- 预处理:包括去直流偏置、滤波(低通/高通/带通)、滑动窗口分帧、归一化(Z-score 或 Min-Max)。
- 特征提取:时域特征(均值、方差、峰值)、频域特征(FFT 频谱)、或直接使用原始波形作为模型输入(端到端学习)。
- 张量格式化:将特征组织为模型所需的形状,如 (时间步, 特征维度) 或 (通道, 高度, 宽度)。
在 HAL 层,建议统一使用 float 或 int16_t 作为传感器数据的标准输出类型。浮点便于上层算法处理,但占用内存较大;定点数(如 Q15 格式)在无 FPU 的 MCU 上运算更快。对于麦克风音频数据,通常使用 16-bit PCM 格式,采样率 16kHz 或 8kHz 以降低计算量。
// 示例:加速度计数据读取与转换(伪代码)
typedef struct {
int16_t x_raw;
int16_t y_raw;
int16_t z_raw;
} accel_raw_t;
typedef struct {
float x_g;
float y_g;
float z_g;
} accel_phys_t;
#define ACCEL_RANGE_2G (2.0f)
#define ACCEL_RES_16BIT (32768.0f)
accel_phys_t accel_convert(accel_raw_t raw) {
accel_phys_t phys;
phys.x_g = (float)raw.x_raw / ACCEL_RES_16BIT * ACCEL_RANGE_2G;
phys.y_g = (float)raw.y_raw / ACCEL_RES_16BIT * ACCEL_RANGE_2G;
phys.z_g = (float)raw.z_raw / ACCEL_RES_16BIT * ACCEL_RANGE_2G;
return phys;
}
2.5 实战场景:多传感器数据同步与时间戳管理
在真实 TinyML 系统中,往往需要融合多个传感器数据。例如,一个可穿戴设备同时使用加速度计和陀螺仪进行姿态估计,两者采样率可能不同(加速度计 100Hz,陀螺仪 200Hz)。HAL 需要解决数据同步问题,否则时间错位会导致推理结果错误。
案例背景:某智能运动手环需实现游泳姿势识别,使用 BMI270 六轴惯性传感器(加速度计+陀螺仪),通过 SPI 接口连接至 nRF52840 MCU。初始方案中,HAL 分别读取两个传感器数据,但发现推理准确率仅 72%,且偶发数据跳变。
问题分析:通过逻辑分析仪抓取 SPI 时序,发现加速度计和陀螺仪数据并非同时采样——BMI270 内部虽然共享同一时钟,但读取时存在约 2ms 的时间差。在快速划臂动作中,2ms 的延迟导致角速度与加速度数据错位,模型输入特征失真。
解决方案:
- 启用 BMI270 的 FIFO 缓冲模式,将加速度计和陀螺仪数据按固定时间戳打包存储,一次性读取 32 组数据。
- 在 HAL 层增加 时间戳管理,使用 MCU 的 32-bit 定时器记录每次 FIFO 读取的精确时间。
- 对陀螺仪数据进行 线性插值,将 200Hz 数据重采样至 100Hz,与加速度计对齐。
结果:优化后推理准确率提升至 91%,数据跳变消失。代价是 FIFO 模式占用更多 SRAM(约 1.2KB),且 SPI 单次传输长度增加,但整体功耗未显著上升。
2.6 常见误区与设计复盘
在嵌入式系统与传感器接口设计中,以下误区值得特别注意:
- 忽视传感器上电稳定时间:许多传感器上电后需要 10~100ms 才能输出稳定数据。HAL 初始化时需加入延时,否则首次读取可能返回全零或随机值。
- 字节序处理错误:部分传感器(如某些陀螺仪)输出大端字节序,而 MCU 默认小端。HAL 需统一进行字节交换,否则数据符号错误。
- ADC 参考电压选择不当:若使用内部参考电压(如 1.2V),而传感器输出范围是 0~3.3V,则需外部电阻分压或运放调理,否则 ADC 溢出。
- 中断服务函数(ISR)中执行耗时操作:在 GPIO 中断回调中直接调用 I2C 读取会导致中断阻塞时间过长,影响系统实时性。正确做法是在 ISR 中仅置标志位,由主循环或 RTOS 任务处理数据读取。
- 未考虑传感器噪声:即使静止放置,加速度计输出也有约 ±0.01g 的噪声。HAL 层可加入滑动平均或 IIR 低通滤波,但需注意滤波引入的相位延迟。