- 物联网
- 嵌入式
- 操作系统
- 实时系统
【免费下载链接】RIOT
RIOT - The friendly OS for IoT
Cayenne Low Power Payload(LPP)是面向 LPWAN(如 LoRaWAN)网络的轻量级二进制数据序列化格式,它用紧凑的字节布局将传感器读数打包成可直接放入 LoRaWAN 帧的上行负载。本文以 RIOT 官方测试应用 tests/pkg/cayenne-lpp/README.md 为主线,结合 tests/pkg/cayenne-lpp/main.c 与 pkg/cayenne-lpp 包定义,完整讲解如何在 RIOT 上运行 Cayenne LPP 编解码测试、理解其字节级编码原理,并掌握将该测试扩展为真实 LoRaWAN 节点数据发送流程的方法。
Cayenne LPP 与 RIOT 中的 cayenne-lpp 包
Cayenne LPP 的核心思想是:用"通道号(1 字节)+ 数据类型码(1 字节)+ 载荷(定长 N 字节)"的三段式结构,把每个传感器读数编码成紧凑二进制。RIOT 通过外部包(pkg)机制集成了社区实现cayenne-lpp,相关说明位于 pkg/cayenne-lpp/doc.txt,其中明确指出该包"为 Cayenne LPP 格式提供 RIOT 支持",适用于"通过 LoRaWAN 等 LPWAN 网络发送数据"的场景。
包本身由 pkg/cayenne-lpp/Makefile 定义:
PKG_NAME=cayenne-lpp PKG_URL=https://github.com/aabadie/cayenne-lpp PKG_VERSION=0.1.1 PKG_LICENSE=LGPL-2.1-only include $(RIOTBASE)/pkg/pkg.mk all: $(QQ)"$(MAKE)" -C $(PKG_SOURCE_DIR) -f $(RIOTBASE)/Makefile.base- 固定版本
0.1.1,许可证为LGPL-2.1-only; - 构建时通过
pkg/pkg.mk拉取源码,并借用 RIOT 的Makefile.base编译; - 头文件搜索路径由 pkg/cayenne-lpp/Makefile.include 提供:
INCLUDES += -I$(PKGDIRBASE)/cayenne-lpp,因此应用代码中只需#include "cayenne_lpp.h"即可使用全部 API。
测试应用概览:运行方式与预期输出
官方 README 给出的使用方法非常简洁——在native板(RIOT 的宿主机仿真平台)上直接编译并启动终端:
make all term该命令在 tests/pkg/cayenne-lpp/Makefile 的配合下工作。该 Makefile 内容如下:
include ../Makefile.pkg_common USEPKG += cayenne-lpp include $(RIOTBASE)/Makefile.include关键点是USEPKG += cayenne-lpp:它声明本测试应用依赖该外部包,RIOT 构建系统会据此完成包的拉取、打补丁与编译(Makefile.pkg_common位于 tests/pkg/Makefile.pkg_common)。
程序启动后应输出以下两行内容(对应 README 的 Expected result 一节):
Cayenne LPP test application 03670110056700FF第一行是应用启动横幅,第二行则是第一个测试用例编码出的完整 LPP 负载。该十六进制串并非随机数据,而是两个温度传感器读数的逐字节编码结果,下一节将逐字节拆解其含义。
逐用例源码解析:从传感器值到 LPP 字节流
测试程序 tests/pkg/cayenne-lpp/main.c 共执行 3 个用例,每个用例都遵循同一模式:调用cayenne_lpp_add_*系列 API 向缓冲区写入数据,随后用memcmp与预置期望字节流比对,一致则打印SUCCESS,否则打印FAILED并返回非零退出码。测试前后通过cayenne_lpp_reset(&lpp)清空缓冲区。
Test 1:双温度传感器
cayenne_lpp_add_temperature(&lpp, 3, 27.2); cayenne_lpp_add_temperature(&lpp, 5, 25.5);期望字节流定义为:
#define TEST_BUFFER1 { 0x03, 0x67, 0x01, 0x10, 0x05, 0x67, 0x00, 0xff }逐字节解读:
| 字节 | 值 | 含义 | | ---- | -- | ---- | | 1 |0x03| 通道号 3(第一路温度) | | 2 |0x67| 类型码:温度传感器 | | 3-4 |0x01 0x10| 有符号 16 位温度值,0x0110 = 272,除以 10 得27.2°C| | 5 |0x05| 通道号 5(第二路温度) | | 6 |0x67| 类型码:温度 | | 7-8 |0x00 0xff|0x00FF = 255,除以 10 得25.5°C|
这正好拼出 README 中的预期输出03670110056700FF。可见温度编码规则为:摄氏度 ×10 取整后存入有符号 16 位,这也是 Cayenne LPP 温度类型(type0x67)的固定载荷长度(2 字节)的由来。
Test 2:温度 + 加速度计
cayenne_lpp_reset(&lpp); cayenne_lpp_add_temperature(&lpp, 1, -4.1); cayenne_lpp_add_accelerometer(&lpp, 6, 1.234, -1.234, 0);期望字节流(native 平台):
#define TEST_BUFFER2 { 0x01, 0x67, 0xFF, 0xD8, \ 0x06, 0x71, 0x04, 0xD1, 0xFB, 0x2F, 0x00, 0x00 }解码过程:
01 67 FF D8:通道 1 温度。0xFFD8是有符号 16 位值-40,即 -4.0°C(浮点 -4.1 经定点化后落入 -40/-41,0xFD8 与 -41=0xFFD7 相差 1,属于定点量化误差,这正是源码中对 native32 与其它平台使用两套期望缓冲区的深层原因);06 71 04 D1 FB 2F 00 00:通道 6 加速度计,类型码0x71。三个轴向各占 2 字节:0x04D1 = 1233(约 1.234g)、0xFB2F = -1233(约 -1.234g)、0x0000 = 0,即g 值 ×1000 存入有符号 16 位。
Test 3:GPS 定位
cayenne_lpp_reset(&lpp); cayenne_lpp_add_gps(&lpp, 1, 42.3519, -87.9094, 10);期望字节流:
#define TEST_BUFFER3 { 0x01, 0x88, 0x06, 0x76, \ 0x5E, 0xF2, 0x96, 0x0A, 0x00, 0x03, 0xE8 }解码过程:
01 88:通道 1,类型码0x88(GPS);- 纬度 3 字节:
0x06765E = 423518,除以 1e4 得42.3518°(源码入参 42.3519,量化误差 0.0001); - 经度 3 字节:
0xF2960A为有符号 24 位值-879094,除以 1e4 得-87.9094°,与入参完全一致; - 海拔 3 字节:
0x0003E8 = 1000,单位为厘米,除以 100 得10 米。
同时,源码中通过CAYENNE_LPP_TEMPERATURE_SIZE、CAYENNE_LPP_ACCELEROMETER_SIZE、CAYENNE_LPP_GPS_SIZE三个常量分别校验各类型固定载荷长度(温度 2、加速度 6、GPS 9 字节),这些常量由cayenne_lpp.h提供,可在后续自研编码时直接复用,避免手写魔法数字。
自动化回归测试:让编码结果可机器校验
该测试应用不仅面向人工演示,还内置了自动化验证脚本 tests/pkg/cayenne-lpp/tests/01-run.py:
NB_TESTS = 3 def testfunc(child): for test in range(NB_TESTS): child.expect_exact('Test {}:'.format(test + 1)) child.expect('Result: [0-9A-Z]+ SUCCESS')脚本借助 RIOT 的 testrunner 框架:逐个等待Test 1:、Test 2:、Test 3:横幅出现,并用正则Result: [0-9A-Z]+ SUCCESS断言每个用例都打印了大写十六进制结果且以SUCCESS结尾。这意味着在 CI(持续集成)或make test流程中,只要任一用例编码错误导致输出变成FAILED,测试即告失败。对 LoRaWAN 节点固件而言,这种"编码前先过单元测试"的做法能有效防止设备上线后上报损坏数据。
从测试到实战:把 LPP 负载接入 LoRaWAN 上行链路
结合 pkg/cayenne-lpp/doc.txt 与测试源码,可将该测试的应用模式迁移到真实 LoRaWAN 节点:
- 引入依赖:在应用 Makefile 中加入
USEPKG += cayenne-lpp(参考 tests/pkg/cayenne-lpp/Makefile),并在源码中#include "cayenne_lpp.h"; - 声明缓冲上下文:仿照
static cayenne_lpp_t lpp;维护编解码状态,发送前调用cayenne_lpp_reset()复位; - 按通道叠加数据:不同传感器使用不同通道号(如温度
0x67、加速度0x71、GPS0x88),在 1 字节通道号范围内合理规划通道分配,注意每类数据的载荷定长,缓冲区总容量受cayenne_lpp_t内部数组约束,需在应用层估算一次上报的最大字节数; - 发送负载:将
lpp.buffer与lpp.cursor(有效长度)交给 LoRaWAN 协议栈(如 RIOT 的 Semtech LoRaMAC 包)填充进上行帧,即可被兼容 Cayenne LPP 的云平台(如 myDevices)自动解析为图表数据。
需要注意的是,测试程序在 native 平台运行时,Test 2 使用0xFF 0xD8而非其它平台的0xFF 0xD7,两者相差 1 个 LSB,源于定点化在宿主机浮点环境与交叉编译环境间的舍入差异。若在真实硬件上移植本测试,务必像源码那样按平台区分期望字节流,或以"编码后回解误差在容差内"替代精确字节比对。
总结
通过make all term一条命令,RIOT 的 cayenne-lpp 测试应用在 native 上完成了温度、加速度计、GPS 三类传感器的 LPP 编码自检。从 tests/pkg/cayenne-lpp/main.c 的字节级断言到 tests/pkg/cayenne-lpp/tests/01-run.py 的自动化回归,再到 pkg/cayenne-lpp 的包封装,读者可以以此为模板,将"通道号 + 类型码 + 定长载荷"的 LPP 编码实践直接落地到自己的 LoRaWAN 物联网节点固件中。
- 物联网
- 嵌入式
- 操作系统
- 实时系统
【免费下载链接】RIOT
RIOT - The friendly OS for IoT
相关推荐
PyTorch Geometric 数据变换(Transforms)完全指南:Data 与 HeteroData 的预处理与增强实战
PyTorch Geometric 数据变换(Transforms)完全指南:Data 与 HeteroData 的预处理与增强实战 导读 torch_geom
物联网嵌入式操作系统实时系统RIOT OS 核心 API 运行时长基准测试:runtime_coreapis 应用深度解析
RIOT OS 核心 API 运行时长基准测试:runtime_coreapis 应用深度解析 导读 本文围绕 RIOT OS 测试套件中的 tests/ben
物联网嵌入式操作系统实时系统RIOT 中 NimBLE 与 ESP WiFi 共存测试应用深度解析(tests/pkg/nimble_esp_wifi_coexist)
RIOT 中 NimBLE 与 ESP WiFi 共存测试应用深度解析(tests/pkg/nimble_esp_wifi_coexist) 导读 本文围绕 R
物联网嵌入式操作系统实时系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考