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。软件分层如下图所示。


调用生命周期必须保持为“上电 → 初始化 → 注册回调 → 打开并加载固件 → 可选配置 → 启动 → 停止 → 关闭 → 去初始化 → 下电”。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 秒。
- 执行
AT^GNSSINIT=1,1,0,0。 - 执行
AT^GNSSSAMPLE=1,函数gnss_cold_start()下发冷启动配置。 - 执行
AT^GNSSSTART并持续接收 NMEA。 - 在
RMC中观察到A后记录首次定位时间;结束时依次执行AT^GNSSSTOP、AT^GNSSDEINIT。
配置指令在 GNSS 芯片下电前保持有效。如需再次获得真正的冷启动结果,应完成去初始化和下电后再执行本场景。
热启动定位
热启动用于保持 GNSS 未下电且上次定位成功不超过 1 分钟的场景;有效时间、位置和星历可使设备快速重新捕获卫星,开阔环境下通常为秒级。
- 先成功完成一次定位,不执行
AT^GNSSDEINIT。 - 执行
AT^GNSSSTOP,在 1 分钟内执行AT^GNSSSAMPLE=2、AT^GNSSSTART。 - 观察
RMC的A并记录热启动 TTFF。
若已经下电、星历过期或时间精度不满足要求,则不能按热启动指标判定,应回到冷启动流程。
AGNSS 辅助定位
AGNSS 在定位前注入在线获得的时间和辅助星历,适用于设备可从网络取得辅助数据的场景。当前示例从 /user/gnss/xgnss/AGNSS.dat 读取数据,文件最大支持 1 024 000 字节,并在数据校验通过后注入芯片。
- 通过 XGNSS 开发指南 获取或生成有效的 AGNSS 原始文件,并保存为
/user/gnss/xgnss/AGNSS.dat。 - 执行
AT^GNSSINIT=1,1,0,0。 - 执行
AT^GNSSSAMPLE=3;gnss_agnss()会注入时间和辅助星历。 - 执行
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 秒的有效期处理。
- 按 XGNSS 开发指南 生成已扩展的 PGNSS 数据文件,并放入
/user/gnss/xgnss。 - 执行
AT^GNSSINIT=1,1,0,0、AT^GNSSSAMPLE=4、AT^GNSSSTART。 - 观察
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 信号。

测试环境应无外界信号干扰,设备与线缆连接正常。正常条件为 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 供电、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 输入口 | 是 |

将单音设备设为 1575.62 MHz(相对 L1 中心频点 1575.42 MHz 正偏 200 kHz),用参考板补偿线损,使 DUT 射频口输入为 -130 dBm。然后按以下流程操作:
-
发送
AT^GNSSINIT=1,1,0,0。
-
发送
AT^GNSSSAMPLE=5,配置gnss_factory_test()。
-
发送
AT^GNSSSTART。约 5 秒后,芯片返回产测结果。
-
发送
AT^GNSSSTOP、AT^GNSSDEINIT,结束本次测试。

| 测试项 | 示例代码默认门限 | 结果含义 |
|---|---|---|
| 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 增加组件入口,并在目标配置中增加同名开关后再构建:
在 /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、流控或板级上电问题;需要恢复时采用完整系统复位,或复用经验证的业务生命周期管理,而不是在失败状态下反复调用初始化接口。
验证步骤
- 在开阔天空或模拟器环境下调用
my_gnss_start()。 - 在 NMEA 回调中确认接收到完整语句,并用 RMC/GGA 字段判定定位状态。
- 结束时执行
my_gnss_stop();再次启动前确认先前调用已完成。 - 需要保存日志时,在业务任务中持久化回调复制的数据,避免与 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 输出都会增加功耗。 |