跳转至

GNSS 集成开发指南

本文档面向基于 HiDiTing V100 开发定位、辅助定位和产线测试功能的开发者。文档以 SDK 中已经参与 3322 默认构建的 GNSS 示例为代码依据,说明 GNSS 的软件分层、接口调用顺序、冷/热启动、AGNSS、PGNSS、硬件性能测试和产线快速判定流程,并给出将定位功能接入自有应用的方法。

GNSS 背景知识

GNSS(Global Navigation Satellite System)泛指卫星导航系统。HiDiTing 集成的 GNSS 子系统支持 GPS L1C/A、GLONASS L1OF、BDS B1I、Galileo E1C 和 QZSS L1C/A;应用可使用单星座或多星座定位,并可在定位前注入 AGNSS 或 PGNSS 辅助信息以缩短首次定位时间。

功能与规格

项目 规格或说明
定位能力 GPS、GLONASS、BDS、Galileo 单模和多模定位;支持 QZSS
辅助定位 AGNSS 在线辅助信息、PGNSS 离线辅助信息
其他能力 自动干扰检测、对外授时、位置/速度/时间/卫星状态和维测消息上报
冷启动捕获灵敏度 -149 dBm
热启动捕获灵敏度 -159 dBm
跟踪灵敏度 -162 dBm
冷启动 TTFF 平均不大于 34 s(-130 dBm)
热启动 TTFF 平均不大于 1 s(-130 dBm)
定位精度 水平位置 1.5 m、水平速度 0.15 m/s(-130 dBm,CEP 68%)
应用极限 速度 500 m/s,高度 18 000 m
GNSS 芯片功耗 捕获 6.40 mA@3.6 V、跟踪 4.95 mA@3.6 V、关机漏电流 14 μA@3.6 V

上述功耗仅统计 GNSS 芯片;TCXO、LNA 等板级器件不包含在内。信号环境、工作频率、NMEA/维测数据上报量都会影响实际整机功耗。

生命周期功耗参考

以下数值用于分析业务时序,不可直接作为整机功耗指标。启动阶段捕获与跟踪并行,弱信号或高频上报会进一步提高功耗。

阶段 GNSS 芯片典型状态与功耗参考
uapi_gnss_init() 已上电、等待加载固件,约 1.5 mA@3.3 V
uapi_gnss_open() 固件已加载、处于就绪状态,约 2.7 mA@3.3 V;应尽快配置或启动
uapi_gnss_start() 正在定位,外场步行场景约 7 mA@3.3 V,随信号环境变化
uapi_gnss_stop() 前约 35 秒约 0.5 mA@3.3 V,随后约 60 μA@3.3 V
uapi_gnss_close() / uapi_gnss_deinit() 芯片等待固件加载或已下电,约 18 μA@3.3 V 漏电

软件架构与数据流

主 MCU 通过 UART 管理 GNSS 芯片的上电、固件加载、配置、启动和停止;GNSS 芯片则将 NMEA 定位数据与二进制维测数据回传给 SDK。软件分层如下图所示。

GNSS 软件架构分层框图

卫星定位软件架构数据流图

调用生命周期必须保持为“上电 → 初始化 → 注册回调 → 打开并加载固件 → 可选配置 → 启动 → 停止 → 关闭 → 去初始化 → 下电”。uapi_gnss_close() 会释放回调注册,下一次初始化必须重新注册回调。

代码与配置位置

内容 SDK 路径 作用
GNSS 公共接口 /src/include/middleware/services/gnss/gnss_device.h 应用调用的 UAPI、回调和数据类型声明
GNSS API 参考 GNSS API 参考 接口约束、返回值和数据类型说明
GNSS 核心实现 /src/middleware/chips/3322/gnss/gnss.c 消息线程、固件打开、配置及启停实现
GNSS 场景示例 /src/application/samples/gnss/gnss_at_samples 冷/热启动、辅助定位、产测和日志示例
GNSS AT 命令 /src/middleware/utils/at/at_diting_gnss_cmd AT^GNSS... 命令转发至场景示例
板级驱动配置 /src/middleware/services/srv_tiot_host/tiot_driver/product_porting/3322_hiditing/gnss UART、流控、TCXO 和固件加载路径
GNSS 固件资源 /src/tools/pkg/bin/3322/gnss/firmwares/gnss_config.bin 打包进入镜像的 GNSS 配置固件

3322 diting-community 目标的 /src/build/config/target_config/3322/config.py 已启用 SUPPORT_GNSS_FEATURECONFIG_ENABLE_DITING_GNSS_SAMPLE,并在组件列表中包含 gnss_3322gnss_at_samplesgnss_diting_at。因此下面的 AT 场景可直接用于该目标;移植到自定义板级时,应同步核对 GNSS UART、流控、TCXO 频率和固件资源路径。

API 接口列表

接口 用途 调用阶段
uapi_gnss_power_on 输出 GNSS 32 kHz 时钟并上电 初始化开始
uapi_gnss_init 创建 GNSS 消息队列和处理线程 上电后
uapi_gnss_register_callback 注册 NMEA 或二进制数据回调 初始化后、打开前
uapi_gnss_open 打开 gn71 设备并加载固件 回调注册后
uapi_gnss_config 下发芯片配置或辅助数据 打开后、部分配置需在启动前
uapi_gnss_start 启动定位和数据上报 配置完成后
uapi_gnss_stop 停止定位 退出定位场景
uapi_gnss_close 关闭设备并清除回调 停止后
uapi_gnss_deinit 销毁消息线程和队列 关闭后
uapi_gnss_power_off 关闭 32 kHz 时钟 去初始化后
uapi_gnss_set_xgnss_type 选择 AGNSS 或 PGNSS 类型 启动前
uapi_gnss_register_xgnss_req_callback 注册辅助信息请求回调 启动前
uapi_notify_xgnss_updated 通知 GNSS 辅助信息已更新 注入辅助数据后
uapi_gnss_register_log_callback 注册 GNSS 日志输出回调 初始化后按需调用
uapi_gnss_set_pos_type 配置 PVT 或 RTK 定位类型 启动前
uapi_gnss_set_file_path 指定 GNSS 文件存储目录 启动前
uapi_gnss_register_power_callback 注册上、下电通知回调 有板级电源协同时,在上电前调用

gnss_message_t 的消息头按 1 字节对齐,载荷长度不包含 8 字节消息头。回调运行于 GNSS 数据处理链路,应先复制数据再交给业务线程,避免文件读写、网络访问或长时间计算阻塞回调。

TIOT 的 tiot_service_init/open/write/close/deinit 是 GNSS 驱动内部接口;应用应调用本表的 uapi_gnss_*,不应直接打开驱动设备或绕过 GNSS 核心的消息队列和回调管理。

快速跑通 GNSS 定位 Demo

功能说明

SDK 的 /src/application/samples/gnss/gnss_at_samples 是一个场景集合:gnss_process.c 将编号 1~5 分别映射到冷启动、热启动、AGNSS、PGNSS 和产测函数;AT 组件中的 at_gnss_sample() 直接调用该映射。因此 AT 命令执行的是 SDK 已参与构建的 GNSS 场景代码,而不是独立的文档示例。

准备工作

说明: 本文示例命令以一站式 CLI 为主。实际开发可从以下三种环境中选择,推荐使用一站式 CLI。

开发环境 适用场景 使用指南
一站式 CLI(推荐) 快速完成目标选择、构建、烧录和串口监视 一站式 CLI 开发环境使用指南
HiSpark Studio for VS Code 图形化编辑、编译、烧录和调试 HiSpark Studio for VS Code 开发环境使用指南
WSL 与 Docker 在 Windows 上使用一致的 Linux 容器构建环境 WSL 与 Docker 环境使用指南

一站式 CLI 开发环境使用指南 准备环境、构建和烧录;构建前确保 fbb doctor 成功。

确认 GNSS 天线已连接且处于开阔天空,或已通过射频线缆连接到 GNSS 信号模拟器。默认板级配置使用 UART 唤醒、26 MHz TCXO、1 000 000 bit/s UART 和硬件流控;相关配置位于 /src/middleware/services/srv_tiot_host/tiot_driver/product_porting/3322_hiditing/gnss/tiot_defconfig

使用方式

先执行公共初始化,再选择一种场景、启动、观察 NMEA,最后按顺序停止和去初始化。

AT^GNSSINIT=1,1,0,0      // 依次为:保存 NMEA、保存 REPLAY、日志级别、RTK REPLAY 开关
AT^GNSSSAMPLE=1          // 选择冷启动场景;本次运行只选择一个场景
AT^GNSSSTART
AT^GNSSSTOP
AT^GNSSDEINIT
AT 命令 当前 SDK 行为
AT^GNSSINIT=nmea,replay,level,rtkReplay 调用 gnss_proc_msg_init(),设置日志开关并执行上电、初始化、回调注册和固件加载
AT^GNSSSAMPLE=0 打印当前场景编号和名称
AT^GNSSSAMPLE=1..5 配置冷启动、热启动、AGNSS、PGNSS 或产测场景;仅配置,不启动定位
AT^GNSSSTART / AT^GNSSSTOP 调用场景的 gnss_start() / gnss_stop()
AT^GNSSDEINIT 关闭设备、销毁 GNSS 线程并下电
AT^GNSSNMEA=0/1 关闭/打开 NMEA 的串口打印
AT^GNSSLOGSIZE=num,size 设置日志文件数量和单文件大小限制
AT^GNSSHEX=... 调试时下发完整的芯片配置报文;报文格式由芯片协议定义

AT^GNSSCFG 在当前 gnss_at_samples 中对应的 gnss_proc_board_cfg() 明确返回“不支持”。选择定位类型或辅助类型时,应在应用中调用相应 UAPI 或使用已经实现的场景函数,不应将此 AT 命令作为已可用的板级配置入口。

当前 GNSS AT 命令表也未注册 AT^HSUARTREINIT。调试工具需要重新占用高速 UART 时,应先完成 AT^GNSSSTOPAT^GNSSDEINIT,再按照具体板级调试工具的连接要求处理,不能将该命令作为可用入口。

预期结果

启动后应看到 NMEA 语句。RMC 语句的位置有效字段为 A,或 GGA 语句定位质量字段为 1,表示定位成功;V0 表示尚未定位。开启文件保存时,日志默认写入 /user/gnss/log/gnss_data.log,其中可混合保存 NMEA 文本和 REPLAY 二进制数据。

文件结构与代码走读

文件 关键职责
/src/application/samples/gnss/gnss_at_samples/gnss_process.c AT 场景编号到功能函数的映射,初始化/启停转发
/src/application/samples/gnss/gnss_at_samples/gnss_common_proc.c 生命周期状态机、NMEA/二进制回调、时间和辅助数据注入
/src/application/samples/gnss/gnss_at_samples/gnss_normal.c 冷启动、热启动配置命令
/src/application/samples/gnss/gnss_at_samples/gnss_agnss.c AGNSS 文件校验、时间和星历注入
/src/application/samples/gnss/gnss_at_samples/gnss_pgnss.c PGNSS 离线辅助数据加载与注入
/src/application/samples/gnss/gnss_at_samples/gnss_factory_test.c 单音 CN0、频偏、频漂判定和结果解析

gnss_proc_msg_init() 先记录 NMEA/REPLAY 保存开关,再调用 gnss_init()。后者依次执行 uapi_gnss_power_on()uapi_gnss_init()、两次 uapi_gnss_register_callback()uapi_gnss_open();这就是应用代码应复用的顺序。

gnss_proc_msg_sample() 只负责选择 gnss_cold_start()gnss_hot_start()gnss_agnss()gnss_pgnss()gnss_factory_test()。这些函数均在 AT^GNSSSTART 前运行,以保证配置和辅助数据先于启动命令到达芯片。

gnss_proc_nmea_msg()gnss_proc_binary_msg() 先把驱动回调数据复制到本地缓冲区,再打印、存储或分发;该处理方式避免了在回调中执行耗时业务逻辑。gnss_deinit() 在运行中会先停止,再依次关闭、去初始化和下电,确保资源释放顺序正确。

GNSS 定位与辅助定位场景

冷启动定位

冷启动指 GNSS 上电后没有有效时间、位置和星历辅助信息,仅依赖当前接收的卫星信号完成首次定位。开阔天空下通常需约 30 秒。

  1. 执行 AT^GNSSINIT=1,1,0,0
  2. 执行 AT^GNSSSAMPLE=1,函数 gnss_cold_start() 下发冷启动配置。
  3. 执行 AT^GNSSSTART 并持续接收 NMEA。
  4. RMC 中观察到 A 后记录首次定位时间;结束时依次执行 AT^GNSSSTOPAT^GNSSDEINIT

配置指令在 GNSS 芯片下电前保持有效。如需再次获得真正的冷启动结果,应完成去初始化和下电后再执行本场景。

热启动定位

热启动用于保持 GNSS 未下电且上次定位成功不超过 1 分钟的场景;有效时间、位置和星历可使设备快速重新捕获卫星,开阔环境下通常为秒级。

  1. 先成功完成一次定位,不执行 AT^GNSSDEINIT
  2. 执行 AT^GNSSSTOP,在 1 分钟内执行 AT^GNSSSAMPLE=2AT^GNSSSTART
  3. 观察 RMCA 并记录热启动 TTFF。

若已经下电、星历过期或时间精度不满足要求,则不能按热启动指标判定,应回到冷启动流程。

AGNSS 辅助定位

AGNSS 在定位前注入在线获得的时间和辅助星历,适用于设备可从网络取得辅助数据的场景。当前示例从 /user/gnss/xgnss/AGNSS.dat 读取数据,文件最大支持 1 024 000 字节,并在数据校验通过后注入芯片。

  1. 通过 XGNSS 开发指南 获取或生成有效的 AGNSS 原始文件,并保存为 /user/gnss/xgnss/AGNSS.dat
  2. 执行 AT^GNSSINIT=1,1,0,0
  3. 执行 AT^GNSSSAMPLE=3gnss_agnss() 会注入时间和辅助星历。
  4. 执行 AT^GNSSSTART,观察 NMEA。

注入后,PNTH001 的有效星历数量字段通常大于 80;RMCA 表示定位成功。应用自行接入网络服务时,可在启动前调用 uapi_gnss_set_xgnss_typeuapi_gnss_register_xgnss_req_callbackuapi_notify_xgnss_updated,再复用示例中的报文编码和校验逻辑。

PGNSS 辅助定位

PGNSS 用于设备预置或离线下载的辅助信息。示例从 /user/gnss/xgnss 读取 AssistInfo.dat 和星历文件;GLONASS 星历按 900 秒、其他星座按 7 200 秒的有效期处理。

  1. XGNSS 开发指南 生成已扩展的 PGNSS 数据文件,并放入 /user/gnss/xgnss
  2. 执行 AT^GNSSINIT=1,1,0,0AT^GNSSSAMPLE=4AT^GNSSSTART
  3. 观察 PNTH001 的有效星历数量和 RMC 定位状态。

AGNSS、PGNSS 的文件解析、数据长度和校验不应由应用随意省略;应以 /src/application/samples/gnss/gnss_at_samples/gnss_agnss.c/src/application/samples/gnss/gnss_at_samples/gnss_pgnss.c 为实现参考。

GNSS 固件升级

GNSS 默认通过资源文件加载固件。3322 单 NOR Flash 资源路径为 /user/gnss/firmware/gnss_config.binditing-community 资源路径为 /boot/gnss/gnss_config.bin;打包源文件为 /src/tools/pkg/bin/3322/gnss/firmwares/gnss_config.bin。替换资源文件并重新生成镜像、重启后即可加载新固件。固件文件名、资源路径和打包规则必须保持一致。

硬件测试与产线测试

本章节将性能硬测和产线快速判定放在同一流程中:前者使用卫星信号模拟器测试 CN0 和三类灵敏度,后者使用单音信号快速筛查板级射频链路和 TCXO。两者测试目的不同,不应互相替代。

硬件性能测试环境

下图所示方案使用 SPIRENT GSS7000 卫星信号模拟器。控制 PC 配置模拟器的星座、场景和信号功率,并通过串口控制被测设备;模拟器通过 RF 线缆向 DUT 输入 GNSS 信号。

GNSS 硬件测试方案架构图

测试环境应无外界信号干扰,设备与线缆连接正常。正常条件为 15 °C~35 °C、湿度 20%~75%;极端温湿度按产品规范或厂商定义执行。DUT 可以是集成 HiDiTing 的手表、单板或样机。

CN0、冷捕获、热捕获与跟踪灵敏度

项目 目的 通过条件
CN0 评估卫星信号质量 -130 dBm 冷启动定位后运行 10 分钟,解析 NMEA 各模式 Top4 卫星的平均 CN0
冷捕获灵敏度 无辅助信息时首次捕获的最低信号功率 5 分钟内定位成功且首次定位精度小于 100 m
热捕获灵敏度 具备粗略时间/频率和星历时的再捕获能力 冷启动定位后保持 15 分钟收集星历,热启动 1 分钟内定位且精度小于 100 m
跟踪灵敏度 持续保持卫星跟踪的最低信号功率 冷启动定位并收集 15 分钟星历后,在目标功率下持续跟踪 100 秒且精度小于 100 m

测试均先在 -130 dBm 下确认可定位,然后每次降低 1 dBm,直到不满足条件并记录失败功率 A;再升高 0.5 dBm 并复测,若仍失败,结果取 A + 1 dBm,否则取复测功率 B。为缩短测试时间,冷捕获可按 -130 → -140 → -145 dBm 后每次降低 1 dBm;热捕获和跟踪可按 -130 → -150 → -155 dBm 后每次降低 1 dBm。典型设计参考值分别为 -149 dBm、-159 dBm、-162 dBm。

NMEA 的 GSV 语句可用于分析卫星方位、高度角和载噪比;开阔环境下 CN0 通常可达 40 dBHz 以上,若大部分卫星低于 30 dBHz,应优先排查天线、遮挡、线损或干扰。PNTH000 中的 VGA 档位为 2 时可能有强干扰,为 13 时可能表明信号过弱或射频增益不足。

产线快速判定 Demo

产测使用单音源验证板级射频口和 TCXO 指标。PC 通过串口向 DUT 发送 AT 命令,单音设备(如 R&S CMW500/270)通过 RF 线缆向 DUT 输入连续载波。连接射频扣线时应先让产品断电,避免损坏射频接口。

GNSS 产测方案覆盖管脚示意图

产测覆盖 GNSS 供电、TCXO 时钟、UART RX/TX、HOST 与 GNSS 唤醒以及 LNA 使能等关键链路。默认板级驱动将 GNSS 硬件信息配置为 UART_BUS_0S_AGPIO5/S_AGPIO3/S_AGPIO4,具体引脚定义以 /src/middleware/services/srv_tiot_host/tiot_driver/product_porting/3322_hiditing/gnss/gnss_board_port_config.h 为准。

下表中的管脚号对应 GNSS 芯片封装,不等同于主 MCU 的 GPIO 编号;“覆盖”表示产测方案可覆盖该管脚或其所属功能链路。

管脚号 名称 类型 功能说明 覆盖
1 VDD_PLL 电源 PLL LDO 输出,外接 1 μF 电容
2 VDD_XLDO 电源 TCXO LDO 输出,外接 1 μF 电容
3 XREF 时钟 TCXO 时钟输入
4 NC - 空置 -
5 VDD_IO_1P8 电源 IO LDO 输出,外接 1 μF 电容
6 VDD_IO_3P3_1P8 电源 VDDIO 电源输入,外接 1 μF 电容
7 VDD_BAT2 电源 VDD_XLDO 电源输入端
8 RTC_O 时钟 RTC 时钟输出
9 RTC_I 时钟 RTC 时钟输入
10 GPIO4 数字 IO 默认调试 UART,3.3 V/1.8 V,带施密特触发器 -
11 GPIO5 数字 IO 默认外置 LNA 使能,3.3 V/1.8 V,带施密特触发器
12 GPIO1 数字 IO 默认 UART RXD,3.3 V/1.8 V,带施密特触发器
13 GPIO0 数字 IO 默认 UART TXD,3.3 V/1.8 V,带施密特触发器
14 GPIO2 数字 IO、内部下拉 通用输入,3.3 V/1.8 V,带施密特触发器
15 GPIO3 数字 IO、内部下拉 通用双向,3.3 V/1.8 V,带施密特触发器
16 VDD_BAT1 电源 芯片内部 DCDC 输入
17 BUCK_LX 电源 BUCK 输出
18 VDD_1P05 电源 芯片内部主电源输入
19 VDD_CLDO 电源 Core LDO 输出
20 GPIO7 数字 IO、内部下拉 默认 GNSS 唤醒 HOST,上电启动复用
21 GPIO9 数字 IO、内部上拉 默认 HOST 唤醒 GNSS,上电启动复用
22 PWREN 模拟 IO 芯片上电使能,高电平有效
23 GPIO16 数字 IO、内部下拉 默认 UART CTS,上电启动复用
24 GPIO13 数字 IO 默认 PPS_OUT,通用双向 -
25 GPIO14 数字 IO 默认 UART RTS,通用双向
26 VDD_ANA 电源 模拟 LDO 输出
27 VDD_RF 电源 RF LDO 输出
28 RF_IN 射频 RF 输入口

GNSS 产测方案架构图

将单音设备设为 1575.62 MHz(相对 L1 中心频点 1575.42 MHz 正偏 200 kHz),用参考板补偿线损,使 DUT 射频口输入为 -130 dBm。然后按以下流程操作:

  1. 发送 AT^GNSSINIT=1,1,0,0

    GNSS 初始化串口示例

  2. 发送 AT^GNSSSAMPLE=5,配置 gnss_factory_test()

    GNSS 产测场景选择示例

  3. 发送 AT^GNSSSTART。约 5 秒后,芯片返回产测结果。

    GNSS 产测结果示例

  4. 发送 AT^GNSSSTOPAT^GNSSDEINIT,结束本次测试。

    GNSS 停止示例

    GNSS 去初始化示例

测试项 示例代码默认门限 结果含义
satellite CN0 40 dBHz,波动不超过 ±2 dB 检查射频接收链路的信号质量
frequency bias 不超过 3 000 ppb(1575.42 MHz 约 4 726 Hz) 检查 TCXO 频偏对搜星能力的影响
frequency drift 不超过 5 ppb/s(1575.42 MHz 约 8 Hz/s) 检查 TCXO 稳定性对解调的影响

代码中的 gnss_factory_test() 将 CN0 以 10 倍数值写入配置(40 dBHz 为 400),并解析 GNSS_FACTORY_TEST_RESULT 的状态位。可在 /src/application/samples/gnss/gnss_at_samples/gnss_factory_test.c 查看命令组包和结果解析。门限仅应在调试测试环境时调整;量产应使用已确认的门限,避免降低不良板拦截能力。

基于 GNSS Demo 开发自己的应用

自有应用应新建独立组件并调用 GNSS 公共接口,不修改 gnss_at_samples。可参考 /samples/native_samples/adc 的组件组织方式,并将 GNSS 功能入口放入应用的任务或业务状态机。

最小生命周期代码

下面的函数展示与现有 gnss_init() 相同的关键调用顺序。gnss_nmea_callback() 只投递或复制数据,业务解析应放在其他任务中;示例省略了具体的消息队列实现。

#include "errcode.h"
#include "gnss_device.h"

static void gnss_nmea_callback(uint8_t *data, uint32_t len)
{
    /* 仅复制或投递 data/len 到业务任务,禁止在此做阻塞操作。 */
}

errcode_t my_gnss_start(void)
{
    errcode_t ret;

    ret = uapi_gnss_power_on();
    if (ret != ERRCODE_SUCC) {
        return ret;
    }
    ret = uapi_gnss_init();
    if (ret != ERRCODE_SUCC) {
        (void)uapi_gnss_power_off();
        return ret;
    }
    ret = uapi_gnss_register_callback(GNSS_CALLBACK_NMEA, gnss_nmea_callback);
    if (ret != ERRCODE_SUCC) {
        (void)uapi_gnss_deinit();
        (void)uapi_gnss_power_off();
        return ret;
    }
    ret = uapi_gnss_open();
    if (ret != ERRCODE_SUCC) {
        (void)uapi_gnss_deinit();
        (void)uapi_gnss_power_off();
        return ret;
    }
    ret = uapi_gnss_start();
    if (ret != ERRCODE_SUCC) {
        (void)uapi_gnss_close();
        (void)uapi_gnss_deinit();
        (void)uapi_gnss_power_off();
    }
    return ret;
}

void my_gnss_stop(void)
{
    (void)uapi_gnss_stop();
    (void)uapi_gnss_close();
    (void)uapi_gnss_deinit();
    (void)uapi_gnss_power_off();
}

如需在启动前下发冷启动、热启动、定位模式或芯片专有配置,应构造对齐的 gnss_message_t 并调用 uapi_gnss_config。消息类型、载荷和校验由 GNSS 接口协议开发指南 定义;冷/热启动可直接参考 /src/application/samples/gnss/gnss_at_samples/gnss_normal.c 的完整组包,辅助数据请复用 AGNSS/PGNSS 示例的校验和注入流程。

CMakeLists.txt 修改要点

在 GitCode 的 native_samples 示例目录中建立独立 GNSS 应用目录,并创建如下 CMakeLists.txt。GNSS 公共头文件由 SDK 的中间件组件导出;不要复制 gnss_at_samples 的源文件,也不要同时注册同名 AT 命令。

set(COMPONENT_NAME "my_gnss_app")

set(SOURCES
    ${CMAKE_CURRENT_SOURCE_DIR}/my_gnss_app.c
)

set(PUBLIC_HEADER
    ${CMAKE_CURRENT_SOURCE_DIR}
)

set(PRIVATE_HEADER
    ${ROOT_DIR}/src/include/middleware/services/gnss
)

set(WHOLE_LINK true)
set(MAIN_COMPONENT false)
build_component()

/samples/native_samples/CMakeLists.txt 增加组件入口,并在目标配置中增加同名开关后再构建:

if("CONFIG_ENABLE_MY_GNSS_APP" IN_LIST DEFINES)
    add_subdirectory_if_exist(my_gnss_app)
endif()

/src/build/config/target_config/3322/config.py 的目标 defines 中加入 CONFIG_ENABLE_MY_GNSS_APP。现有 diting-community 已提供 GNSS 核心、场景和 AT 组件,新增开关仅用于把自有组件纳入该目标;完成修改后按 一站式 CLI 开发环境使用指南 重新配置并构建。

失败恢复边界

当前 GNSS 核心仅在 uapi_gnss_close 成功时清除已注册的回调。若 uapi_gnss_register_callback() 已成功而随后 uapi_gnss_open() 失败,公开接口没有单独的“注销回调”接口,不能假定直接再次注册会成功。应用应先记录失败原因并修复固件、UART、流控或板级上电问题;需要恢复时采用完整系统复位,或复用经验证的业务生命周期管理,而不是在失败状态下反复调用初始化接口。

验证步骤

  1. 在开阔天空或模拟器环境下调用 my_gnss_start()
  2. 在 NMEA 回调中确认接收到完整语句,并用 RMC/GGA 字段判定定位状态。
  3. 结束时执行 my_gnss_stop();再次启动前确认先前调用已完成。
  4. 需要保存日志时,在业务任务中持久化回调复制的数据,避免与 GNSS 回调线程竞争。

调试方法

日志与定位结果

  • 初始化参数的前两位分别控制 NMEA、REPLAY 保存。日志默认为 /user/gnss/log/gnss_data.log,NMEA 文本与 REPLAY 二进制可混合保存;不要向该文件插入无关数据。
  • 芯片日志用于保存 NMEA 和 REPLAY;用户自定义日志应写入独立文件或通过 uapi_gnss_register_log_callback 接入日志系统,不能混写到 GNSS 数据文件中。
  • RMC 第 3 字段为 AGGA 第 7 字段为 1 表示定位成功。
  • PNTH001 的定位错误码可帮助定位失败:1 为跟踪卫星不足,2 为有效星历不足,3 为定位精度不足被拦截;其定位质量评估因子有效范围为 3~200,值越小精度越好。
  • AGNSS/PGNSS 注入后,PNTH001 的有效星历数量应与注入预期相符,典型全星座值约为 100。

板级链路检查

  • 通过 GNSS UART TX 测试点确认芯片原始输出是否完整;若原始 UART 完整而应用 NMEA 缺失,再排查主控接收和回调处理。
  • 默认配置启用 UART 流控。板级未连接流控线或两端使能状态不一致会导致报文丢失,应同步检查硬件和 tiot_defconfig
  • 外场搜星慢时,先用 GSV 的卫星分布和 CN0 排查遮挡、天线和信号环境;天线不应紧贴地面或金属底面。
  • 固件加载时间由固件大小、UART 波特率和板级时序共同决定。当前默认波特率为 1 000 000 bit/s,不应在应用中固化加载时长;应以 uapi_gnss_open() 返回值和实际日志判断是否完成。

注意事项

  • uapi_gnss_config() 只能在 uapi_gnss_open() 成功后调用,且部分配置必须在 uapi_gnss_start() 前完成。
  • 调用 uapi_gnss_stop() 后不下电,可在星历有效期内实现热启动;若需要真正的冷启动,需完成关闭、去初始化和下电。
  • uapi_gnss_close() 后会清除已注册的消息回调;每次重新初始化均需重新注册。
  • 固件加载文件名、资源路径和镜像打包路径必须匹配。缺少 gnss_config.bin 时,打开设备或启动定位会失败。
  • 高定位频率、同时输出 NMEA 和 REPLAY、弱信号反复捕获都会提高功耗。停止后若需要最低待机功耗,应按生命周期完整关闭并下电。
  • 产线单音测试和卫星信号模拟器性能测试的信号类型不同:前者用于快速板级判定,后者用于 CN0 和灵敏度指标验证。

常见编译错误与问题定位

现象 原因与处理
找不到 gnss_device.h 确认目标启用了 GNSS 功能,并使用 SDK 组件的标准头文件导出路径;不要引用已废弃的非 /src 代码路径。
uapi_gnss_open() 失败 检查 GNSS 固件资源、UART/流控配置、TCXO 和天线板级设计;同时查看 GNSS 日志。
NMEA 缺行或不完整 检查 GNSS UART TX 原始数据、流控硬件连接和主控 UART RX 中断负载。
冷启动长时间未定位 在开阔环境核对 GSV 的星数与 CN0;确认天线、射频线损和当前星历状态。首次无辅助信息定位通常约 30 秒。
AGNSS/PGNSS 无加速效果 检查文件路径、文件校验、注入时机和 PNTH001 有效星历数量;辅助数据必须在启动前完成注入。
产测无结果 确认依次执行 GNSSINITGNSSSAMPLE=5GNSSSTART,并确认单音源已在启动前输出;结果通常在启动后约 5 秒出现。
产测搜星失败 确认场景为 GNSSSAMPLE=5、单音源已经正常输出且测试频率为 1575.62 MHz。
产测 CN0 失败 核对 RF 线缆、扣线和线损补偿,再与参考板对比以界定仪表或单板射频链路问题。
产测频偏失败 优先检查或更换 TCXO;可外灌 26 MHz 时钟,以区分 TCXO 器件和单板问题。
产测频漂失败 排查温度、风等测试环境因素后复测;仍失败时更换 TCXO。
功耗高于标称 标称值不含 TCXO、LNA 等板级器件;弱信号、启动捕获、高频定位和大量 NMEA/REPLAY 输出都会增加功耗。