7.9 位置服务组件
2026/7/19大约 3 分钟常用组件组件定位位置服务IoT
7.9 位置服务组件
📚 本节导读
学习时长:约 15 分钟
难度级别:⭐⭐☆☆☆
前置知识:第 7.2 节网络协议栈
🎯 学习目标
- 理解 OneOS 位置服务组件的定位
- 了解定位能力适配层的架构
- 掌握位置服务的基本配置
一、概述
OneOS 位置服务组件(components/position/)提供定位能力的统一适配层。核心适配接口位于 port/onepos_adapter.h,Kconfig 配置位于 Kconfig。支持多种定位方式(GPS、基站定位、WiFi 定位等)的接入,通过适配层屏蔽不同定位模块的差异,向上层提供统一的位置数据接口。
目录结构
components/position/
├── port/ # 定位适配层
│ ├── onepos_adapter.h # 适配接口头文件
│ └── weave.yaml
├── sample/ # 使用示例
├── Kconfig # 配置选项
└── weave.yaml二、核心接口
2.1 适配接口
位置服务组件通过 onepos_adapter.h 定义统一的适配接口:
/* 位置数据结构 */
typedef struct
{
double latitude; /* 纬度 */
double longitude; /* 经度 */
double altitude; /* 海拔高度(米) */
float speed; /* 速度(km/h) */
float direction; /* 方向(度) */
os_uint32_t timestamp; /* 时间戳 */
os_uint8_t satellites; /* 卫星数量 */
os_uint8_t fix_type; /* 定位类型(0=无, 1=2D, 2=3D) */
} onepos_data_t;
/* 定位模块适配接口 */
typedef struct
{
int (*init)(void); /* 初始化 */
int (*deinit)(void); /* 反初始化 */
int (*get_position)(onepos_data_t *data); /* 获取位置 */
int (*set_mode)(int mode); /* 设置工作模式 */
int (*get_status)(void); /* 获取状态 */
} onepos_ops_t;三、Kconfig 配置
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
OS_USING_POSITION | bool | n | 启用位置服务组件 |
POSITION_USING_GPS | bool | n | 启用 GPS 定位 |
POSITION_USING_SAMPLE | bool | n | 启用示例代码 |
配置菜单
(Top) → Components → Position
[*] Enable position service
[ ] Enable GPS positioning
[ ] Enable position sample四、GPS 模组适配示例
4.1 AT 指令交互流程
典型的 GPS 模组(如 Quectel L76K、ATGM336H)通过串口 AT 指令进行通信:
MCU (OneOS) GPS 模组
│ │
│ AT+CGNSPWR=1 │ 开启 GPS 电源
│──────────────────────────────>│
│ OK │
│<──────────────────────────────│
│ │
│ AT+CGNSINF │ 查询导航信息
│──────────────────────────────>│
│ +CGNSINF: 1,1,20260719093000,│
│ 39.904200,116.407400,50.5, │ 返回经纬度/海拔/速度
│ 0.00,225.0,8,12 │
│<──────────────────────────────│4.2 适配器实现示例
#include <onepos_adapter.h>
#include <serial.h>
/* GPS 模组适配器 */
static int gps_init(void)
{
/* 打开 GPS 模组连接的串口 */
os_device_t *serial = os_device_open("uart2");
if (serial == NULL) return -1;
/* 发送 AT 指令开启 GPS */
os_device_write(serial, "AT+CGNSPWR=1\r\n", 14);
return 0;
}
static int gps_get_position(onepos_data_t *data)
{
char buf[256];
os_device_t *serial = os_device_open("uart2");
/* 发送查询指令 */
os_device_write(serial, "AT+CGNSINF\r\n", 12);
/* 读取响应 */
int len = os_device_read(serial, buf, sizeof(buf), 5000);
if (len <= 0) return -1;
/* 解析 NMEA 或 GNSS 数据 */
/* +CGNSINF: <mode>,<fix>,<utc>,<lat>,<lng>,<alt>,<speed>,<course>,<sat>,<hdop> */
sscanf(buf, "+CGNSINF: %*d,%hhd,%*s,%lf,%lf,%lf,%f,%f,%hhd",
&data->fix_type, &data->latitude, &data->longitude,
&data->altitude, &data->speed, &data->direction,
&data->satellites);
return 0;
}
/* 注册适配器 */
static onepos_ops_t gps_ops = {
.init = gps_init,
.deinit = NULL,
.get_position = gps_get_position,
.set_mode = NULL,
.get_status = NULL,
};4.3 位置数据上报到云平台
#include <onepos_adapter.h>
#include <mqtt_client.h>
/* 周期上报位置到 MQTT 云平台 */
void position_report_task(void *arg)
{
onepos_data_t pos;
char json_buf[256];
while (1)
{
/* 获取位置数据 */
if (get_position(&pos) == 0 && pos.fix_type > 0)
{
/* 构造 JSON 格式上报 */
snprintf(json_buf, sizeof(json_buf),
"{\"lat\":%.6f,\"lng\":%.6f,\"alt\":%.1f,"
"\"speed\":%.1f,\"sat\":%d,\"ts\":%lu}",
pos.latitude, pos.longitude, pos.altitude,
pos.speed, pos.satellites, pos.timestamp);
/* 通过 MQTT 发布到云平台 */
mqtt_publish("device/position", json_buf);
}
os_task_msleep(5000); /* 每 5 秒上报一次 */
}
}📝 本节小结
- 位置服务组件提供统一的定位能力适配层
onepos_data_t结构体包含经纬度、海拔、速度、方向等- 通过适配接口屏蔽不同定位模块的差异
- 适用于需要位置信息的 IoT 设备(物流追踪、资产定位等)