跳转至

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_FEATURE、CONFIG_ENABLE_DITING_GNSS_SAMPLE,并在组件列表中包含 gnss_3322、gnss_at_samples 和 gnss_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^GNSSSTOP、AT^GNSSDEINIT,再按照具体板级调试工具的连接要求处理,不能将该命令作为可用入口。

预期结果

启动后应看到 NMEA 语句。RMC 语句的位置有效字段为 A,或 GGA 语句定位质量字段为 1,表示定位成功;V 和 0 表示尚未定位。开启文件保存时,日志默认写入 /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^GNSSSTOP、AT^GNSSDEINIT。

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

热启动定位

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

  1. 先成功完成一次定位,不执行 AT^GNSSDEINIT。
  2. 执行 AT^GNSSSTOP,在 1 分钟内执行 AT^GNSSSAMPLE=2、AT^GNSSSTART。
  3. 观察 RMC 的 A 并记录热启动 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=3;gnss_agnss() 会注入时间和辅助星历。
  4. 执行 AT^GNSSSTART,观察 NMEA。

注入后,PNTH001 的有效星历数量字段通常大于 80;RMC 为 A 表示定位成功。应用自行接入网络服务时,可在启动前调用 uapi_gnss_set_xgnss_type、uapi_gnss_register_xgnss_req_callback 和 uapi_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,0、AT^GNSSSAMPLE=4、AT^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.bin,diting-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_0 和 S_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^GNSSSTOP、AT^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 字段为 A 或 GGA 第 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 有效星历数量;辅助数据必须在启动前完成注入。
产测无结果 确认依次执行 GNSSINIT、GNSSSAMPLE=5、GNSSSTART,并确认单音源已在启动前输出;结果通常在启动后约 5 秒出现。
产测搜星失败 确认场景为 GNSSSAMPLE=5、单音源已经正常输出且测试频率为 1575.62 MHz。
产测 CN0 失败 核对 RF 线缆、扣线和线损补偿,再与参考板对比以界定仪表或单板射频链路问题。
产测频偏失败 优先检查或更换 TCXO;可外灌 26 MHz 时钟,以区分 TCXO 器件和单板问题。
产测频漂失败 排查温度、风等测试环境因素后复测;仍失败时更换 TCXO。
功耗高于标称 标称值不含 TCXO、LNA 等板级器件;弱信号、启动捕获、高频定位和大量 NMEA/REPLAY 输出都会增加功耗。