Files
banban/ql-application/threadx/interface/custom_app/app_sys_time_probe.c
T

122 lines
4.7 KiB
C

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include "ql_func.h"
#include "ql_rtos.h"
#include "ql_rtc.h"
#include "ql_atcmd.h"
#include "app_sys_time_probe.h"
/* Exact signatures from the existing kernel pmic_rtc.h/duster.h.
* Lookup only: never add exports, use fixed addresses, or use our diagnostic API.
* SYS_OFFSET is 0 in pmic_rtc.h. Missing exports are an expected result. */
typedef unsigned int (*sys_count_fn)(int);
typedef int (*zone_minutes_fn)(void);
static void probe_sys_exports(void)
{
sys_count_fn get_count;
zone_minutes_fn get_zone;
unsigned int raw[2], ticks[2];
int zone[2], i;
long long utc[2], advance, elapsed, drift;
get_count = (sys_count_fn)(intptr_t)m_get_api_ptr("PMIC_RTC_GetTime_Count");
get_zone = (zone_minutes_fn)(intptr_t)m_get_api_ptr("GetTimeZone");
printf("[APP-SYS-PROBE] exports sys_count=%d network_zone=%d\r\n",
get_count != NULL, get_zone != NULL);
if (!get_count || !get_zone) {
printf("[APP-SYS-PROBE] direct_sys=unavailable no_kernel_change=1\r\n");
return;
}
for (i = 0; i < 2; ++i) {
raw[i] = get_count(0);
zone[i] = get_zone();
ticks[i] = ql_rtos_get_systicks();
utc[i] = (long long)raw[i] - (long long)zone[i] * 60;
printf("[APP-SYS-PROBE] direct index=%d raw=%lu zone_minutes=%d "
"utc=%lld ticks=%lu\r\n", i + 1, (unsigned long)raw[i],
zone[i], utc[i], (unsigned long)ticks[i]);
if (i == 0) ql_rtos_task_sleep_ms(3000);
}
elapsed = (ticks[1] - ticks[0]) / 200U;
advance = utc[1] - utc[0];
drift = advance - elapsed;
if (utc[0] >= 1704067200LL && utc[1] <= 2147483647LL &&
zone[0] >= -720 && zone[0] <= 840 && zone[0] == zone[1] &&
elapsed >= 2 && elapsed <= 10 && advance > 0 && drift >= -1 && drift <= 1) {
printf("[APP-SYS-PROBE] direct_sys=candidate advancing=1 "
"advance_s=%lld elapsed_s=%lld external_utc_check_required=1\r\n",
advance, elapsed);
} else {
printf("[APP-SYS-PROBE] direct_sys=rejected advance_s=%lld "
"elapsed_s=%lld drift_s=%lld\r\n", advance, elapsed, drift);
}
}
static void probe_app_rtc(int round)
{
ql_rtc_time_t calendar;
int rc;
printf("[APP-SYS-PROBE] app round=%d utc=%ld ticks=%lu\r\n",
round, (long)time(NULL), (unsigned long)ql_rtos_get_systicks());
if (!m_get_api_ptr("ql_rtc_get_time_ex")) {
printf("[APP-SYS-PROBE] rtc_ex=unavailable\r\n");
return;
}
memset(&calendar, 0, sizeof(calendar));
rc = ql_rtc_get_time_ex(&calendar);
printf("[APP-SYS-PROBE] rtc_ex round=%d rc=%d calendar="
"%04d-%02d-%02dT%02d:%02d:%02d source_not_assumed=1\r\n",
round, rc, calendar.tm_year, calendar.tm_mon, calendar.tm_mday,
calendar.tm_hour, calendar.tm_min, calendar.tm_sec);
}
static void probe_at(int round, char *command, const char *label)
{
char response[256];
unsigned int began = ql_rtos_get_systicks(), ended;
int rc, terminated;
size_t i;
memset(response, 0, sizeof(response));
rc = ql_atcmd_send_sync(command, response, sizeof(response), NULL, 2);
ended = ql_rtos_get_systicks();
terminated = memchr(response, '\0', sizeof(response)) != NULL;
response[sizeof(response) - 1] = '\0';
for (i = 0; response[i]; ++i)
if ((unsigned char)response[i] < 32 || response[i] == '"') response[i] = ' ';
printf("[APP-SYS-PROBE] at round=%d query=%s rc=%d duration_ms=%lu "
"ticks=%lu terminated=%d raw=\"%s\"\r\n", round, label, rc,
(unsigned long)(ended - began) * 5UL, (unsigned long)ended,
terminated, response);
}
void app_sys_time_probe_run(void)
{
int round;
printf("[APP-SYS-PROBE] begin version=1 read_only=1 kernel_diag_used=0\r\n");
if (!m_get_api_ptr) {
printf("[APP-SYS-PROBE] FAIL stage=api_lookup_unavailable\r\n");
goto done;
}
probe_sys_exports();
if (!m_get_api_ptr("ql_atcmd_send_sync")) {
printf("[APP-SYS-PROBE] at=unavailable\r\n");
goto done;
}
for (round = 1; round <= 2; ++round) {
probe_app_rtc(round);
/* QLTS support/semantics on this model must be established on-device.
* Mode 0 may be a snapshot; mode 1/2 on supported models advances.
* CCLK is comparison only; it may expose the same broken APP RTC. */
probe_at(round, "AT+QLTS=0\r\n", "QLTS_0");
probe_at(round, "AT+QLTS=1\r\n", "QLTS_1");
probe_at(round, "AT+QLTS=2\r\n", "QLTS_2");
probe_at(round, "AT+CCLK?\r\n", "CCLK");
if (round == 1) ql_rtos_task_sleep_ms(3000);
}
done:
printf("[APP-SYS-PROBE] finished rtc_not_written=1\r\n");
}