Make GPS navigation epochs interrupt-coherent
Wait for every navigation-ready tracking channel in a GPS epoch, remove unlocked channels without a timeout, and keep late joins for the next epoch. Reset PLIC ownership during warm initialization and extend Linux synthetic, integrity, and fake-MMIO regression coverage.
This commit is contained in:
@@ -19,7 +19,6 @@
|
||||
// |___|_| |____/|_____|_| |___|_| \_|_____|____/
|
||||
|
||||
#define MIN_NEEDED_SATELLITE 4
|
||||
#define GPS_INITIAL_SUBFRAME_MASK ((1u << 1) | (1u << 2) | (1u << 3) | (1u << 4) | (1u << 5))
|
||||
#define GPS_TRCK_UNLOCK_TIMEOUT_TICKS 500000000u
|
||||
#define GPS_PRN_COUNT 32u
|
||||
#define GPS_PRN_INVALID 0xffu
|
||||
@@ -318,6 +317,7 @@
|
||||
double omgkdot; // from subframe 3
|
||||
double idot; // from subframe 3
|
||||
unsigned char update; // from subframe 3
|
||||
bool ephemeris_valid; // true only after a matching SF1/SF2/SF3 set is committed.
|
||||
unsigned char sf4_data_id; // from subframe 4 word 3.
|
||||
unsigned char sf4_sv_id; // page identifier encoded in subframe 4 word 3.
|
||||
unsigned char sf4_page; // decoded page number, or 0 if not mapped.
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#ifndef GPS_NAV_EPOCH_H
|
||||
#define GPS_NAV_EPOCH_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* The current receiver exposes nine tracking channels. Keep the epoch
|
||||
* selector bounded so its exhaustive, allocation-free search has a fixed
|
||||
* worst-case cost on the embedded target.
|
||||
*/
|
||||
#define GPS_NAV_EPOCH_MAX_CANDIDATES 9u
|
||||
|
||||
typedef struct {
|
||||
int week;
|
||||
double tow_sec;
|
||||
uint32_t raw_sample;
|
||||
} gps_nav_epoch_key_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t selected_mask;
|
||||
unsigned int selected_count;
|
||||
unsigned int reference_index;
|
||||
} gps_nav_epoch_selection_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t epoch_id;
|
||||
uint32_t expected_mask;
|
||||
uint32_t received_mask;
|
||||
bool active;
|
||||
} gps_nav_epoch_assembly_t;
|
||||
|
||||
typedef enum {
|
||||
GPS_NAV_EPOCH_EVENT_INVALID = 0,
|
||||
GPS_NAV_EPOCH_EVENT_ACCEPTED,
|
||||
GPS_NAV_EPOCH_EVENT_DUPLICATE,
|
||||
GPS_NAV_EPOCH_EVENT_STALE,
|
||||
GPS_NAV_EPOCH_EVENT_FUTURE,
|
||||
GPS_NAV_EPOCH_EVENT_COMPLETE
|
||||
} gps_nav_epoch_event_result_t;
|
||||
|
||||
bool gps_nav_epoch_select(
|
||||
const gps_nav_epoch_key_t candidates[GPS_NAV_EPOCH_MAX_CANDIDATES],
|
||||
unsigned int candidate_count,
|
||||
uint32_t sample_window,
|
||||
double tow_tolerance_sec,
|
||||
gps_nav_epoch_selection_t* selection);
|
||||
|
||||
bool gps_nav_epoch_id(
|
||||
int week,
|
||||
double tow_sec,
|
||||
unsigned int period_ms,
|
||||
uint64_t* epoch_id);
|
||||
|
||||
void gps_nav_epoch_assembly_reset(gps_nav_epoch_assembly_t* assembly);
|
||||
|
||||
gps_nav_epoch_event_result_t gps_nav_epoch_assembly_push(
|
||||
gps_nav_epoch_assembly_t* assembly,
|
||||
uint64_t epoch_id,
|
||||
unsigned int channel,
|
||||
uint32_t ready_mask);
|
||||
|
||||
bool gps_nav_epoch_assembly_remove_channel(
|
||||
gps_nav_epoch_assembly_t* assembly,
|
||||
unsigned int channel);
|
||||
|
||||
bool gps_nav_epoch_assembly_complete(
|
||||
const gps_nav_epoch_assembly_t* assembly);
|
||||
|
||||
#endif
|
||||
@@ -15,6 +15,7 @@ typedef struct gps_ephem_ll {
|
||||
volatile bool gps_how_anchor_valid;
|
||||
volatile uint32_t gps_nav_solve_sequence;
|
||||
volatile uint32_t gps_nav_solve_consumed_sequence;
|
||||
volatile gpstime_t gps_last_nav_solve_tow;
|
||||
volatile uint32_t gps_last_nav_solve_abs_sample;
|
||||
volatile double gps_last_nav_solve_corrected_abs_sample;
|
||||
volatile uint64_t gps_last_nav_solve_local_ticks;
|
||||
|
||||
Reference in New Issue
Block a user