90 lines
3.9 KiB
Python
90 lines
3.9 KiB
Python
"""Run the actual GNSS parser and power-state paths with logging off and on."""
|
|
from pathlib import Path
|
|
import re
|
|
import subprocess
|
|
import tempfile
|
|
|
|
root = Path(__file__).resolve().parents[1]
|
|
app = root / 'ql-application/threadx/interface/custom_app'
|
|
source = (app / 'gnss.c').read_text()
|
|
source = re.sub(r'^#include "(?!app_gnss_log.h")[^"]+"\n', '', source, flags=re.M)
|
|
harness = r'''
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
#include <setjmp.h>
|
|
#include <stdarg.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
typedef unsigned int u32;
|
|
typedef unsigned char u8;
|
|
typedef void *ql_task_t;
|
|
typedef enum { GNSS_MODE_FAST, GNSS_MODE_SLOW } gnss_mode_t;
|
|
typedef struct { double latitude, longitude; int is_valid; char raw_nmea[512]; } gps_location_info_t;
|
|
enum { AGPS_GNSS_ENABLE, APFLASH_GNSS_ENABLE, PACKET_MODE };
|
|
static unsigned int now;
|
|
static int scenario, opened, closed, printed;
|
|
static jmp_buf stop;
|
|
static unsigned int hal_os_up_time_ms(void) { return now; }
|
|
static int test_printf(const char *format, ...) { (void)format; printed++; return 0; }
|
|
#define printf test_printf
|
|
static int ql_gnss_close(void) { closed++; return 0; }
|
|
static int ql_gnss_open(void (*cb)(char *, int)) { (void)cb; opened++; return 0; }
|
|
static void app_set_app_operation(int value) { assert(value == 1); }
|
|
static void ql_gnss_cfgsys_set(int value) { (void)value; }
|
|
static void ql_gnss_cfgmsg_set(int value) { (void)value; }
|
|
static void ql_gnss_agps_cfg(int value, int extra) { (void)value; (void)extra; }
|
|
static void ql_gnss_apflash_cfg(int value) { (void)value; }
|
|
static void ql_set_gnss_nmea_mode(int value) { (void)value; }
|
|
static void ql_rtos_task_sleep_s(int seconds);
|
|
static void ql_rtos_task_create(ql_task_t *task, int stack, int priority, char *name, void (*entry)(void *), void *arg) {
|
|
(void)task; (void)stack; (void)priority; (void)name; (void)entry; (void)arg;
|
|
}
|
|
'''
|
|
harness += source
|
|
harness += r'''
|
|
#undef printf
|
|
static void ql_rtos_task_sleep_s(int seconds) {
|
|
if (closed) longjmp(stop, 1);
|
|
now += (unsigned int)seconds * 1000;
|
|
if (scenario == 1) g_gnss_sat_count = 2;
|
|
if (scenario == 2) { g_gnss_sat_count = 4; g_gps_location.is_valid = 1; }
|
|
assert(now < 1000000);
|
|
}
|
|
int main(void) {
|
|
(void)test_printf;
|
|
char data[] = "$GPGGA,120000,2311.71298,N,11328.63118,E,1,08,0.9,10,M,0,M,0,0*00\r\n"
|
|
"$GPGSV,1,1,08,01,10,10,30*00\r\n";
|
|
quec_gnss_callback(data, (int)strlen(data));
|
|
assert(g_gps_location.is_valid && g_gnss_sat_count == 8);
|
|
assert(fabs(g_gps_location.latitude - 23.1952163333) < 0.000001);
|
|
assert(fabs(g_gps_location.longitude - 113.4771863333) < 0.000001);
|
|
assert(strncmp(g_gps_location.raw_nmea, "$GPGGA,", 7) == 0);
|
|
print_gps_location_info();
|
|
set_gnss_mode(GNSS_MODE_FAST);
|
|
assert(get_gnss_mode() == GNSS_MODE_FAST && get_gnss_interval() == 180);
|
|
for (scenario = 0; scenario < 4; scenario++) {
|
|
now = 1; opened = closed = 0; gnss_is_open = 0;
|
|
g_gnss_mode = scenario == 3 ? GNSS_MODE_FAST : GNSS_MODE_SLOW;
|
|
if (!setjmp(stop)) quec_gnss_test(NULL);
|
|
assert(opened == 1 && closed == 1 && get_gnss_open_status() == 0);
|
|
}
|
|
#if APP_GNSS_LOG_ENABLED
|
|
assert(printed > 0);
|
|
#else
|
|
assert(printed == 0);
|
|
#endif
|
|
puts("PASS: GNSS parsing and all four hardware-close paths preserved; expected log visibility");
|
|
}
|
|
'''
|
|
with tempfile.TemporaryDirectory(prefix='banban-gnss-log-') as directory:
|
|
cfile = Path(directory) / 'gnss-test.c'
|
|
cfile.write_text(harness)
|
|
for enabled in (0, 1):
|
|
exe = Path(directory) / f'gnss-test-{enabled}'
|
|
subprocess.run(['cc', '-std=c99', '-Wall', '-Wextra', '-Werror',
|
|
'-Wno-unused-parameter', '-Wno-unused-variable', '-Wno-sign-compare',
|
|
'-fsanitize=address,undefined', f'-DAPP_GNSS_LOG_ENABLED={enabled}',
|
|
'-I' + str(app / 'inc'), str(cfile), '-o', str(exe)], check=True)
|
|
subprocess.run([str(exe)], check=True)
|