Files
gps/soc/software/gps_system/tests/test_gps_ephemeris_cache.c
T
onur 30179df8e6 feat(gps): add timer-based assisted reacquisition
Remove the fixed pseudorange start offset, preserve per-PRN navigation assistance across RF loss and power cycles, and seed coherent navigation measurement phase on reacquisition. Add full LNAV almanac visibility scheduling, power-safe QSPI journaling, RF-domain reset isolation, and PPS Gray CDC hardening with Linux, sanitizer, RTL, and end-to-end coverage.
2026-08-04 02:58:11 +03:00

141 lines
4.1 KiB
C

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "gps/gps_ephemeris_cache.h"
static gps_ephemeris_t make_ephemeris(
unsigned int prn,
unsigned char iode)
{
gps_ephemeris_t ephemeris;
memset(&ephemeris, 0, sizeof(ephemeris));
ephemeris.SVID = (unsigned char)prn;
ephemeris.iode = iode;
ephemeris.ephemeris_valid = true;
ephemeris.toe.week = 2430;
ephemeris.toe.sec = 123456.0;
return ephemeris;
}
static void test_store_restore_and_expiry(void)
{
gps_ephemeris_cache_t cache;
gps_ephemeris_cache_init(&cache, 100u);
gps_ephemeris_t input = make_ephemeris(4u, 17u);
gps_ephemeris_t output;
memset(&output, 0, sizeof(output));
assert(gps_ephemeris_cache_store(
&cache, 4u, &input, 1000u));
input.iode = 99u;
assert(gps_ephemeris_cache_restore(
&cache, 4u, 1100u, &output));
assert(output.iode == 17u);
assert(output.SVID == 4u);
assert(!gps_ephemeris_cache_restore(
&cache, 4u, 1101u, &output));
/* Expiration invalidates the slot, not only this read. */
assert(!gps_ephemeris_cache_restore(
&cache, 4u, 1001u, &output));
}
static void test_validation_independence_and_invalidate(void)
{
gps_ephemeris_cache_t cache;
gps_ephemeris_cache_init(&cache, 500u);
gps_ephemeris_t prn4 = make_ephemeris(4u, 21u);
gps_ephemeris_t prn19 = make_ephemeris(19u, 44u);
gps_ephemeris_t output;
prn4.ephemeris_valid = false;
assert(!gps_ephemeris_cache_store(
&cache, 4u, &prn4, 0u));
prn4.ephemeris_valid = true;
assert(!gps_ephemeris_cache_store(
&cache, 5u, &prn4, 0u));
assert(!gps_ephemeris_cache_store(
&cache, GPS_PRN_COUNT, &prn4, 0u));
assert(gps_ephemeris_cache_store(
&cache, 4u, &prn4, 20u));
assert(gps_ephemeris_cache_store(
&cache, 19u, &prn19, 30u));
assert(gps_ephemeris_cache_restore(
&cache, 19u, 40u, &output));
assert(output.iode == 44u);
gps_ephemeris_cache_invalidate(&cache, 4u);
assert(!gps_ephemeris_cache_restore(
&cache, 4u, 40u, &output));
assert(gps_ephemeris_cache_restore(
&cache, 19u, 40u, &output));
}
static void test_repeated_issue_does_not_hide_staleness(void)
{
gps_ephemeris_cache_t cache;
gps_ephemeris_cache_init(&cache, 100u);
gps_ephemeris_t issue17 = make_ephemeris(6u, 17u);
gps_ephemeris_t output;
assert(gps_ephemeris_cache_store(
&cache, 6u, &issue17, 1000u));
assert(gps_ephemeris_cache_store(
&cache, 6u, &issue17, 1090u));
assert(!gps_ephemeris_cache_restore(
&cache, 6u, 1101u, &output));
/* A changed IOD is a fresh broadcast issue and receives a new TTL. */
issue17.iode = 18u;
issue17.iodc = 18u;
assert(gps_ephemeris_cache_store(
&cache, 6u, &issue17, 1200u));
assert(gps_ephemeris_cache_restore(
&cache, 6u, 1300u, &output));
assert(output.iode == 18u);
}
static void test_time_anchor_is_independent_and_short_lived(void)
{
gps_ephemeris_cache_t cache;
gps_ephemeris_cache_init(&cache, 1000u);
gps_ephemeris_t ephemeris = make_ephemeris(11u, 9u);
gps_cached_time_anchor_t anchor = {
.tow = {.week = 2430, .sec = 345678.0},
.raw_sample = 0xffff0000u,
.corrected_sample = 4294901759.75,
.week_valid = true,
.valid = true
};
gps_cached_time_anchor_t restored;
/* An anchor cannot outlive or exist without its ephemeris slot. */
assert(!gps_ephemeris_cache_store_time_anchor(
&cache, 11u, &anchor, 50u));
assert(gps_ephemeris_cache_store(
&cache, 11u, &ephemeris, 50u));
assert(gps_ephemeris_cache_store_time_anchor(
&cache, 11u, &anchor, 60u));
assert(gps_ephemeris_cache_restore_time_anchor(
&cache, 11u, 170u, 110u, &restored));
assert(restored.tow.week == 2430);
assert(restored.raw_sample == 0xffff0000u);
assert(!gps_ephemeris_cache_restore_time_anchor(
&cache, 11u, 171u, 110u, &restored));
/* The two-hour-class ephemeris remains usable after the short counter
* anchor expires; firmware then waits for one fresh HOW, not SF1/2/3. */
assert(gps_ephemeris_cache_restore(
&cache, 11u, 171u, &ephemeris));
}
int main(void)
{
test_store_restore_and_expiry();
test_validation_independence_and_invalidate();
test_repeated_issue_does_not_hide_staleness();
test_time_anchor_is_independent_and_short_lived();
puts("gps ephemeris cache tests passed");
return 0;
}