Skip to content

Commit 95a3110

Browse files
JordanYatesjhedberg
authored andcommitted
tests: drivers: gnss: gnss_emul: test driver
Test the behaviour of the emulated GNSS driver. Signed-off-by: Jordan Yates <[email protected]>
1 parent 70b0e17 commit 95a3110

File tree

5 files changed

+213
-0
lines changed

5 files changed

+213
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright (c) 2025 Embeint Pty Ltd
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
cmake_minimum_required(VERSION 3.20.0)
5+
6+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
7+
8+
project(gnss_emul)
9+
10+
target_sources(app PRIVATE
11+
src/main.c
12+
)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* Copyright 2025 Embeint Pty Ltd
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/ {
8+
aliases {
9+
gnss = &gnss;
10+
};
11+
12+
gnss: gnss {
13+
compatible = "zephyr,gnss-emul";
14+
status = "okay";
15+
zephyr,pm-device-runtime-auto;
16+
};
17+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright (c) 2025 Embeint Pty Ltd
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
CONFIG_ZTEST=y
5+
CONFIG_ZTEST_STACK_SIZE=4096
6+
7+
CONFIG_PM_DEVICE=y
8+
CONFIG_PM_DEVICE_RUNTIME=y
9+
10+
CONFIG_GNSS=y
11+
CONFIG_GNSS_EMUL=y
12+
CONFIG_GNSS_EMUL_MANUAL_UPDATE=y
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* Copyright 2025 Embeint Pty Ltd
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdint.h>
8+
9+
#include <zephyr/ztest.h>
10+
#include <zephyr/kernel.h>
11+
#include <zephyr/drivers/gnss.h>
12+
#include <zephyr/drivers/gnss/gnss_emul.h>
13+
#include <zephyr/pm/device.h>
14+
#include <zephyr/pm/device_runtime.h>
15+
16+
static void gnss_data_callback(const struct device *dev, const struct gnss_data *data);
17+
18+
GNSS_DATA_CALLBACK_DEFINE(DEVICE_DT_GET(DT_ALIAS(gnss)), gnss_data_callback);
19+
static K_SEM_DEFINE(gnss_data_published, 0, 1);
20+
static struct gnss_data gnss_published_data;
21+
22+
static void expected_pm_state(const struct device *dev, enum pm_device_state expected)
23+
{
24+
enum pm_device_state state;
25+
26+
zassert_equal(0, pm_device_state_get(dev, &state));
27+
zassert_equal(expected, state);
28+
}
29+
30+
static void gnss_data_callback(const struct device *dev, const struct gnss_data *data)
31+
{
32+
gnss_published_data = *data;
33+
k_sem_give(&gnss_data_published);
34+
}
35+
36+
static void print_time(const struct gnss_time *utc)
37+
{
38+
printk("TIME: %02d/%02d/%02d %02d:%02d:%02d.%03d\n", utc->century_year, utc->month,
39+
utc->month_day, utc->hour, utc->minute, utc->millisecond / 1000,
40+
utc->millisecond % 1000);
41+
}
42+
43+
ZTEST(gnss_emul, test_config_functions)
44+
{
45+
const struct device *dev = DEVICE_DT_GET(DT_ALIAS(gnss));
46+
enum gnss_navigation_mode mode;
47+
gnss_systems_t systems;
48+
uint32_t fix_rate;
49+
50+
/* Booted into suspend mode */
51+
expected_pm_state(dev, PM_DEVICE_STATE_SUSPENDED);
52+
53+
/* Configuration get API functions fail when suspended */
54+
zassert_equal(-ENODEV, gnss_get_enabled_systems(dev, &systems));
55+
zassert_equal(-ENODEV, gnss_get_navigation_mode(dev, &mode));
56+
zassert_equal(-ENODEV, gnss_get_fix_rate(dev, &fix_rate));
57+
58+
/* Configuration can be queried when enabled */
59+
zassert_equal(0, pm_device_runtime_get(dev));
60+
zassert_equal(0, gnss_set_enabled_systems(dev, GNSS_SYSTEM_GPS | GNSS_SYSTEM_GALILEO));
61+
zassert_equal(0, gnss_set_navigation_mode(dev, GNSS_NAVIGATION_MODE_HIGH_DYNAMICS));
62+
zassert_equal(0, gnss_set_fix_rate(dev, 1500));
63+
64+
zassert_equal(0, gnss_get_enabled_systems(dev, &systems));
65+
zassert_equal(0, gnss_get_navigation_mode(dev, &mode));
66+
zassert_equal(0, gnss_get_fix_rate(dev, &fix_rate));
67+
zassert_equal(GNSS_SYSTEM_GPS | GNSS_SYSTEM_GALILEO, systems);
68+
zassert_equal(GNSS_NAVIGATION_MODE_HIGH_DYNAMICS, mode);
69+
zassert_equal(1500, fix_rate);
70+
71+
zassert_equal(0, pm_device_runtime_put(dev));
72+
73+
/* Fails again when suspended */
74+
zassert_equal(-ENODEV, gnss_get_enabled_systems(dev, &systems));
75+
zassert_equal(-ENODEV, gnss_get_navigation_mode(dev, &mode));
76+
zassert_equal(-ENODEV, gnss_get_fix_rate(dev, &fix_rate));
77+
78+
/* But escape hatches work */
79+
systems = 0;
80+
mode = 0;
81+
fix_rate = 0;
82+
zassert_equal(0, gnss_emul_get_enabled_systems(dev, &systems));
83+
zassert_equal(0, gnss_emul_get_navigation_mode(dev, &mode));
84+
zassert_equal(0, gnss_emul_get_fix_rate(dev, &fix_rate));
85+
zassert_equal(GNSS_SYSTEM_GPS | GNSS_SYSTEM_GALILEO, systems);
86+
zassert_equal(GNSS_NAVIGATION_MODE_HIGH_DYNAMICS, mode);
87+
zassert_equal(1500, fix_rate);
88+
}
89+
90+
ZTEST(gnss_emul, test_callback_behaviour)
91+
{
92+
const struct device *dev = DEVICE_DT_GET(DT_ALIAS(gnss));
93+
const struct navigation_data nav = {
94+
.latitude = 150000000000,
95+
.longitude = -15199000000,
96+
.altitude = 123456,
97+
};
98+
const struct gnss_info info = {
99+
.satellites_cnt = 7,
100+
.hdop = 1999,
101+
.geoid_separation = 1000,
102+
.fix_status = GNSS_FIX_STATUS_GNSS_FIX,
103+
.fix_quality = GNSS_FIX_QUALITY_GNSS_SPS,
104+
};
105+
const struct gnss_time *utc;
106+
uint32_t timestamp;
107+
108+
/* Booted into suspend mode */
109+
expected_pm_state(dev, PM_DEVICE_STATE_SUSPENDED);
110+
111+
/* No data published while suspended */
112+
zassert_equal(-EAGAIN, k_sem_take(&gnss_data_published, K_SECONDS(5)));
113+
114+
/* Power up and configure for 1Hz */
115+
zassert_equal(0, pm_device_runtime_get(dev));
116+
zassert_equal(0, gnss_set_fix_rate(dev, 1000));
117+
timestamp = k_uptime_get_32();
118+
119+
/* Monitor data for a while */
120+
for (int i = 0; i < 10; i++) {
121+
zassert_equal(0, k_sem_take(&gnss_data_published, K_MSEC(1100)));
122+
zassert_equal(0, gnss_published_data.nav_data.latitude);
123+
zassert_equal(0, gnss_published_data.nav_data.longitude);
124+
zassert_equal(0, gnss_published_data.nav_data.altitude);
125+
zassert_equal(0, gnss_published_data.info.satellites_cnt);
126+
print_time(&gnss_published_data.utc);
127+
}
128+
129+
/* Set a location, approximately 14th July 2017, 02:40:xx am */
130+
gnss_emul_set_data(dev, &nav, &info, 1500000000000LL);
131+
for (int i = 0; i < 3; i++) {
132+
utc = &gnss_published_data.utc;
133+
/* Published data should match that configured */
134+
zassert_equal(0, k_sem_take(&gnss_data_published, K_MSEC(1100)));
135+
zassert_mem_equal(&gnss_published_data.nav_data, &nav, sizeof(nav));
136+
zassert_mem_equal(&gnss_published_data.info, &info, sizeof(info));
137+
zassert_equal(17, utc->century_year);
138+
zassert_equal(7, utc->month);
139+
zassert_equal(14, utc->month_day);
140+
zassert_equal(2, utc->hour);
141+
zassert_equal(40, utc->minute);
142+
print_time(&gnss_published_data.utc);
143+
}
144+
145+
/* Reset back to no location */
146+
gnss_emul_clear_data(dev);
147+
for (int i = 0; i < 5; i++) {
148+
zassert_equal(0, k_sem_take(&gnss_data_published, K_MSEC(1100)));
149+
zassert_equal(0, gnss_published_data.nav_data.latitude);
150+
zassert_equal(0, gnss_published_data.nav_data.longitude);
151+
zassert_equal(0, gnss_published_data.nav_data.altitude);
152+
zassert_equal(0, gnss_published_data.info.satellites_cnt);
153+
print_time(&gnss_published_data.utc);
154+
}
155+
156+
/* Once again no callbacks once suspended */
157+
zassert_equal(0, pm_device_runtime_put(dev));
158+
zassert_equal(-EAGAIN, k_sem_take(&gnss_data_published, K_SECONDS(5)));
159+
}
160+
161+
ZTEST_SUITE(gnss_emul, NULL, NULL, NULL, NULL, NULL);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright (c) 2025 Embeint Pty Ltd
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
tests:
5+
drivers.gnss.gnss_emul:
6+
platform_allow:
7+
- native_sim
8+
integration_platforms:
9+
- native_sim
10+
tags:
11+
- gnss

0 commit comments

Comments
 (0)