From 78e7c2645bd6692c1305c61d4bd6f359a6ffd3e6 Mon Sep 17 00:00:00 2001 From: caisking Date: Thu, 30 Apr 2026 16:45:09 +0800 Subject: [PATCH] =?utf8?q?=E5=A2=9E=E5=8A=A0=E5=BC=80=E6=9C=BA=E6=97=B6?= =?utf8?q?=E9=97=B4=E6=A0=A1=E5=87=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../chips/brandy/exception/chip_system_time.c | 84 ++++++++++++++++++- code/sdk/zhihui/utils/custom_utils.c | 5 ++ 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/code/sdk/middleware/chips/brandy/exception/chip_system_time.c b/code/sdk/middleware/chips/brandy/exception/chip_system_time.c index ad7e09309..b7cd666d3 100644 --- a/code/sdk/middleware/chips/brandy/exception/chip_system_time.c +++ b/code/sdk/middleware/chips/brandy/exception/chip_system_time.c @@ -18,6 +18,58 @@ #define MAX_TIMEZONE_HOURS 24 #define TIME_MAX 64 #define TIME_FLOW_PREFIX "[TIME_FLOW][时间链路] " +#define MIN_VALID_RESTORE_SEC 946684800UL /* 2000-01-01 00:00:00 */ +#define DEFAULT_FALLBACK_UTC_SEC 1735660800UL /* 2025-01-01 00:00:00 */ +#define TIME_BIN_PATH "/user/userdata/time.bin" + +static uint32_t build_reasonable_fallback_local_sec(uint16_t timezone_quarters) +{ + uint32_t utc_now = get_current_timestamp(); + uint32_t zone_offset_sec = timezone_quarters * MINUTES_PER_QUARTER * SECONDS_PER_MINUTE; + + /* + * Prefer current RTC time when it already looks reasonable; otherwise + * fallback to a fixed baseline to avoid 1970/zero timestamp. + */ + if (utc_now >= MIN_VALID_RESTORE_SEC) { + return utc_now + zone_offset_sec; + } + return DEFAULT_FALLBACK_UTC_SEC + zone_offset_sec; +} + +static void save_time_bin(uint32_t utc_sec) +{ + FILE *fp = fopen(TIME_BIN_PATH, "wb"); + if (fp == NULL) { + printf(TIME_FLOW_PREFIX "save_time_bin: open failed, path=%s\r\n", TIME_BIN_PATH); + return; + } + size_t write_cnt = fwrite(&utc_sec, sizeof(utc_sec), 1, fp); + fclose(fp); + if (write_cnt != 1) { + printf(TIME_FLOW_PREFIX "save_time_bin: write failed\r\n"); + return; + } + printf(TIME_FLOW_PREFIX "save_time_bin: utc_sec=%u\r\n", utc_sec); +} + +static bool load_time_bin(uint32_t *utc_sec) +{ + if (utc_sec == NULL) { + return false; + } + + FILE *fp = fopen(TIME_BIN_PATH, "rb"); + if (fp == NULL) { + return false; + } + size_t read_cnt = fread(utc_sec, sizeof(*utc_sec), 1, fp); + fclose(fp); + if (read_cnt != 1 || *utc_sec < MIN_VALID_RESTORE_SEC) { + return false; + } + return true; +} void print_time(calendar_t *date) { @@ -63,6 +115,7 @@ void save_time(void) printf(TIME_FLOW_PREFIX "save_time: local_sec=%u, write_calendar_ms=%llu\r\n", (uint32_t)get_local_timestamp(), (unsigned long long)time_sec); uapi_calendar_set_timestamp(time_sec); + save_time_bin(get_current_timestamp()); } uint32_t get_current_timestamp(void) @@ -105,11 +158,34 @@ void restore_time(void) uapi_calendar_get_timestamp(&sec); printf("callendar timestamp = %lld \r\n", sec); sec = sec / MSEC_PER_SEC; + uint16_t timezone_quarters = uapi_get_timezone(); + if ((sec < MIN_VALID_RESTORE_SEC) || (sec > UINT32_MAX)) { + uint32_t file_utc_sec = 0; + if (load_time_bin(&file_utc_sec)) { + printf(TIME_FLOW_PREFIX "restore_time: invalid calendar timestamp=%llu, use time.bin utc=%u\r\n", + (unsigned long long)sec, file_utc_sec); + sync_time_utc(file_utc_sec, timezone_quarters); + } else { + uint32_t fallback_local_sec = build_reasonable_fallback_local_sec(timezone_quarters); + printf(TIME_FLOW_PREFIX "restore_time: invalid calendar timestamp=%llu, use fallback_local=%u\r\n", + (unsigned long long)sec, fallback_local_sec); + sync_time(fallback_local_sec, timezone_quarters); + } + } else { printf(TIME_FLOW_PREFIX "restore_time: read_calendar_sec=%llu, timezone_quarters=%u\r\n", - (unsigned long long)sec, uapi_get_timezone()); - sync_time(sec, uapi_get_timezone()); - printf(TIME_FLOW_PREFIX "restore_time: after_sync utc_now=%u, local_now=%u\r\n", - get_current_timestamp(), get_local_timestamp()); + (unsigned long long)sec, timezone_quarters); + sync_time((uint32_t)sec, timezone_quarters); + } + uint32_t utc_now = get_current_timestamp(); + uint32_t local_now = get_local_timestamp(); + printf(TIME_FLOW_PREFIX "restore_time: after_sync utc_now=%u, local_now=%u\r\n", utc_now, local_now); + + struct tm local_tm = {0}; + time_t utc_sec = (time_t)utc_now; + localtime_r(&utc_sec, &local_tm); + printf(TIME_FLOW_PREFIX "restore_time: actual_local_time=%04d-%02d-%02d %02d:%02d:%02d\r\n", + local_tm.tm_year + 1900, local_tm.tm_mon + 1, local_tm.tm_mday, + local_tm.tm_hour, local_tm.tm_min, local_tm.tm_sec); } uint32_t sync_time_utc(uint32_t timestamp, uint32_t timezone_quarters) { diff --git a/code/sdk/zhihui/utils/custom_utils.c b/code/sdk/zhihui/utils/custom_utils.c index 6a7728efd..292b25da3 100644 --- a/code/sdk/zhihui/utils/custom_utils.c +++ b/code/sdk/zhihui/utils/custom_utils.c @@ -277,6 +277,7 @@ uint32_t zh_set_sn(uint8_t *buf_sn, uint32_t len_sn) #include "pm_control.h" #include "non_os_reboot.h" +#include "calendar_porting.h" #define PM_SHIPMODE_DELAY_SLEEP_MS 100 void mcu_reset(void) @@ -293,6 +294,9 @@ static void poweroff_bt_dsp_display(void) } void mcu_poweroff(void) { + /* 关机前开启calendar校准,确保自动开机定时持续刷新。 */ + uapi_calendar_calibration_enable(); + /* clr ulp int and event */ writel(0x5702C1E4, 0x3F); writel(0x5702C1EC, 0x3F); @@ -358,6 +362,7 @@ void uapi_poweroff_device(void) void uapi_reboot_device(void) { PRINT("[PWR_FLOW] uapi_reboot_device: enter\r\n"); + uapi_calendar_calibration_enable(); //重启前要保存时间 uapi_calendar_store_date(); PRINT("[PWR_FLOW] uapi_reboot_device: calendar stored\r\n"); -- 2.17.1